Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
3545 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
6948 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2017. 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
        cmp     ax, 0x8086
436
        jne     .notfound
437
        shr     eax, 16
438
 
439
        DEBUGF  1,"Device_id=0x%x\n", ax
440
        mov     ecx, DEVICE_IDs
441
        mov     edi, device_id_list
442
        repne   scasw
443
        jne     .notfound
444
        jmp     .found
445
 
446
  .notfound:
3845 hidnplayr 447
        DEBUGF  2,"Unsupported device!\n"
3545 hidnplayr 448
        or      eax, -1
449
        ret
450
 
451
  .found:
452
 
453
 
454
 
455
;----------
456
;
457
;  Reset
458
;
459
;----------
460
 
461
align 4
462
reset:
463
 
4581 hidnplayr 464
        movzx   eax, [ebx + device.irq_line]
3545 hidnplayr 465
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
4581 hidnplayr 466
        invoke  AttachIntHandler, eax, int_handler, ebx
3545 hidnplayr 467
        test    eax, eax
468
        jnz     @f
3845 hidnplayr 469
        DEBUGF  2,"Could not attach int handler!\n"
4581 hidnplayr 470
        or      eax, -1
471
        ret
3545 hidnplayr 472
  @@:
473
 
3845 hidnplayr 474
        DEBUGF  1,"Resetting\n"
3545 hidnplayr 475
 
6717 hidnplayr 476
;----------------
477
; Selective reset
3545 hidnplayr 478
 
4581 hidnplayr 479
        set_io  [ebx + device.io_addr], 0
6717 hidnplayr 480
        set_io  [ebx + device.io_addr], REG_EEPROM
481
        mov     eax, PORT_SELECTIVE_RESET
482
        out     dx, eax
483
 
6948 hidnplayr 484
        mov     esi, 10
6717 hidnplayr 485
        invoke  Sleep
486
 
487
;-----------
488
; Soft reset
489
 
5562 hidnplayr 490
        set_io  [ebx + device.io_addr], REG_PORT
6717 hidnplayr 491
        mov     eax, PORT_SOFT_RESET
3545 hidnplayr 492
        out     dx, eax
493
 
494
        mov     esi, 10
6717 hidnplayr 495
        invoke  Sleep
3545 hidnplayr 496
 
6717 hidnplayr 497
;-------------
498
; Read PHY IDs
499
 
500
        mov     cx, 1
501
        mov     dx, MII_PHYSID1
502
        call    mdio_read
503
        DEBUGF  1, "PHY ID1: 0x%x\n", ax
504
 
505
        mov     cx, 1
506
        mov     dx, MII_PHYSID2
507
        call    mdio_read
508
        DEBUGF  1, "PHY ID2: 0x%x\n", ax
509
 
510
;---------------------
511
; Read MAC from eeprom
512
 
513
        call    ee_get_width
514
        call    mac_read_eeprom
515
 
3545 hidnplayr 516
;---------------------------------
517
; Tell device where to store stats
518
 
4581 hidnplayr 519
        lea     eax, [ebx + device.lstats.tx_good_frames]      ; lstats
520
        invoke  GetPhysAddr
521
        set_io  [ebx + device.io_addr], 0
5562 hidnplayr 522
        set_io  [ebx + device.io_addr], REG_SCB_PTR
3545 hidnplayr 523
        out     dx, eax
524
 
5562 hidnplayr 525
        set_io  [ebx + device.io_addr], REG_SCB_CMD
5525 hidnplayr 526
        mov     ax, CU_STATSADDR or INT_MASK
3545 hidnplayr 527
        out     dx, ax
528
        call    cmd_wait
529
 
5525 hidnplayr 530
;------------------------
531
; setup RX base addr to 0
3545 hidnplayr 532
 
5562 hidnplayr 533
        set_io  [ebx + device.io_addr], REG_SCB_PTR
3545 hidnplayr 534
        xor     eax, eax
535
        out     dx, eax
536
 
5562 hidnplayr 537
        set_io  [ebx + device.io_addr], REG_SCB_CMD
5525 hidnplayr 538
        mov     ax, RX_ADDR_LOAD or INT_MASK
3545 hidnplayr 539
        out     dx, ax
540
        call    cmd_wait
541
 
542
;-----------------------------
543
; Create RX and TX descriptors
544
 
5525 hidnplayr 545
        call    init_rx_ring
5522 hidnplayr 546
        test    eax, eax
547
        jz      .error
3545 hidnplayr 548
 
5525 hidnplayr 549
        call    init_tx_ring
3545 hidnplayr 550
 
5525 hidnplayr 551
 
552
;---------
553
; Start RX
554
 
555
        DEBUGF  1, "Starting RX"
556
 
4581 hidnplayr 557
        set_io  [ebx + device.io_addr], 0
5562 hidnplayr 558
        set_io  [ebx + device.io_addr], REG_SCB_PTR
4581 hidnplayr 559
        mov     eax, [ebx + device.rx_desc]
560
        invoke  GetPhysAddr
5522 hidnplayr 561
        add     eax, NET_BUFF.data
3545 hidnplayr 562
        out     dx, eax
563
 
5562 hidnplayr 564
        set_io  [ebx + device.io_addr], REG_SCB_CMD
5525 hidnplayr 565
        mov     ax, RX_START or INT_MASK
3545 hidnplayr 566
        out     dx, ax
567
        call    cmd_wait
568
 
5525 hidnplayr 569
;----------
3545 hidnplayr 570
; Set-up TX
571
 
5562 hidnplayr 572
        set_io  [ebx + device.io_addr], REG_SCB_PTR
3545 hidnplayr 573
        xor     eax, eax
574
        out     dx, eax
575
 
5562 hidnplayr 576
        set_io  [ebx + device.io_addr], REG_SCB_CMD
5525 hidnplayr 577
        mov     ax, CU_CMD_BASE or INT_MASK
3545 hidnplayr 578
        out     dx, ax
579
        call    cmd_wait
580
 
5525 hidnplayr 581
;-------------------------
582
; Individual address setup
3545 hidnplayr 583
 
5562 hidnplayr 584
        mov     [ebx + device.confcmd.command], TXFD_CMD_IA + TXFD_CMD_SUSPEND
5525 hidnplayr 585
        mov     [ebx + device.confcmd.status], 0
586
        lea     eax, [ebx + device.tx_ring]
587
        invoke  GetPhysAddr
588
        mov     [ebx + device.confcmd.link], eax
589
        lea     edi, [ebx + device.confcmd.data]
590
        lea     esi, [ebx + device.mac]
591
        movsd
592
        movsw
593
 
5562 hidnplayr 594
        set_io  [ebx + device.io_addr], REG_SCB_PTR
5525 hidnplayr 595
        lea     eax, [ebx + device.confcmd.status]
596
        invoke  GetPhysAddr
597
        out     dx, eax
598
 
5562 hidnplayr 599
        set_io  [ebx + device.io_addr], REG_SCB_CMD
5525 hidnplayr 600
        mov     ax, CU_START or INT_MASK
601
        out     dx, ax
602
        call    cmd_wait
603
 
604
;-------------
605
; Configure CU
606
 
5562 hidnplayr 607
        mov     [ebx + device.confcmd.command], TXFD_CMD_CFG + TXFD_CMD_SUSPEND
4581 hidnplayr 608
        mov     [ebx + device.confcmd.status], 0
5525 hidnplayr 609
        lea     eax, [ebx + device.confcmd.status]
4581 hidnplayr 610
        invoke  GetPhysAddr
611
        mov     [ebx + device.confcmd.link], eax
3545 hidnplayr 612
 
613
        mov     esi, confcmd_data
4581 hidnplayr 614
        lea     edi, [ebx + device.confcmd.data]
3545 hidnplayr 615
        mov     ecx, 22
616
        rep     movsb
617
 
5562 hidnplayr 618
        set_io  [ebx + device.io_addr], REG_SCB_PTR
4581 hidnplayr 619
        lea     eax, [ebx + device.confcmd.status]
620
        invoke  GetPhysAddr
3545 hidnplayr 621
        out     dx, eax
622
 
5562 hidnplayr 623
        set_io  [ebx + device.io_addr], REG_SCB_CMD
5525 hidnplayr 624
        mov     ax, CU_START                            ; expect Interrupts from now on
3545 hidnplayr 625
        out     dx, ax
626
        call    cmd_wait
627
 
3845 hidnplayr 628
        DEBUGF  1,"Reset complete\n"
4581 hidnplayr 629
        mov     [ebx + device.mtu], 1514
3545 hidnplayr 630
 
631
; Set link state to unknown
4581 hidnplayr 632
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
3545 hidnplayr 633
 
634
        xor     eax, eax        ; indicate that we have successfully reset the card
635
        ret
636
 
5522 hidnplayr 637
  .error:
638
        or      eax, -1
639
        ret
3545 hidnplayr 640
 
5522 hidnplayr 641
 
3545 hidnplayr 642
align 4
5525 hidnplayr 643
init_rx_ring:
3545 hidnplayr 644
 
645
        DEBUGF  1,"Creating ring\n"
646
 
647
;---------------------
648
; build rxfd structure
649
 
5522 hidnplayr 650
        invoke  NetAlloc, 2000
651
        test    eax, eax
652
        jz      .out_of_mem
4581 hidnplayr 653
        mov     [ebx + device.rx_desc], eax
3545 hidnplayr 654
        mov     esi, eax
4581 hidnplayr 655
        invoke  GetPhysAddr
5522 hidnplayr 656
        add     eax, NET_BUFF.data
5562 hidnplayr 657
        mov     [esi + sizeof.NET_BUFF + rxfd.status], 0
658
        mov     [esi + sizeof.NET_BUFF + rxfd.command], RXFD_CMD_EL or RXFD_CMD_SUSPEND
5522 hidnplayr 659
        mov     [esi + sizeof.NET_BUFF + rxfd.link], eax
660
        mov     [esi + sizeof.NET_BUFF + rxfd.count], 0
661
        mov     [esi + sizeof.NET_BUFF + rxfd.size], 1528
3545 hidnplayr 662
 
5525 hidnplayr 663
        ret
3545 hidnplayr 664
 
5525 hidnplayr 665
  .out_of_mem:
666
        ret
667
 
668
 
669
 
670
 
671
align 4
672
init_tx_ring:
673
 
674
        DEBUGF  1,"Creating TX ring\n"
675
 
676
        lea     esi, [ebx + device.tx_ring]
677
        mov     eax, esi
4581 hidnplayr 678
        invoke  GetPhysAddr
5525 hidnplayr 679
        mov     ecx, TX_RING_SIZE
680
  .next_desc:
681
        mov     [esi + txfd.status], 0
682
        mov     [esi + txfd.command], 0
683
        lea     edx, [eax + txfd.buf_addr]
684
        mov     [esi + txfd.desc_addr], edx
685
        add     eax, sizeof.txfd
686
        mov     [esi + txfd.link], eax
687
        mov     [esi + txfd.count], 0x01208000          ; One buffer, 0x20 bytes of transmit threshold, end of frame
688
        add     esi, sizeof.txfd
689
        dec     ecx
690
        jnz     .next_desc
691
 
692
        lea     eax, [ebx + device.tx_ring]
4581 hidnplayr 693
        invoke  GetPhysAddr
5525 hidnplayr 694
        mov     dword[ebx + device.tx_ring + sizeof.txfd*(TX_RING_SIZE-1) + txfd.link], eax
3545 hidnplayr 695
 
5525 hidnplayr 696
        mov     [ebx + device.cur_tx], 0
697
        mov     [ebx + device.last_tx], 0
5522 hidnplayr 698
 
3545 hidnplayr 699
        ret
700
 
701
 
702
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
703
;;                                         ;;
704
;; Transmit                                ;;
705
;;                                         ;;
4581 hidnplayr 706
;; In: pointer to device structure in ebx  ;;
3545 hidnplayr 707
;;                                         ;;
708
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
709
 
5522 hidnplayr 710
proc transmit stdcall bufferptr
3545 hidnplayr 711
 
4581 hidnplayr 712
        pushf
713
        cli
714
 
5522 hidnplayr 715
        mov     esi, [bufferptr]
716
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
717
        lea     eax, [esi + NET_BUFF.data]
3545 hidnplayr 718
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
719
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
720
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
721
        [eax+13]:2,[eax+12]:2
722
 
5522 hidnplayr 723
        cmp     [esi + NET_BUFF.length], 1514
4581 hidnplayr 724
        ja      .fail
5522 hidnplayr 725
        cmp     [esi + NET_BUFF.length], 60
4581 hidnplayr 726
        jb      .fail
3545 hidnplayr 727
 
5525 hidnplayr 728
        ; Get current TX descriptor
729
        mov     edi, [ebx + device.cur_tx]
730
        mov     eax, sizeof.txfd
731
        mul     edi
732
        lea     edi, [ebx + device.tx_ring + eax]
733
 
734
        ; Check if current descriptor is free or still in use
735
        cmp     [edi + txfd.status], 0
736
        jne     .fail
737
 
738
        ; Fill in status and command values
739
        mov     [edi + txfd.status], 0
5562 hidnplayr 740
        mov     [edi + txfd.command], TXFD_CMD_SUSPEND + TXFD_CMD_TX + TXFD_CMD_TX_FLEX
5525 hidnplayr 741
        mov     [edi + txfd.count], 0x01208000
742
 
743
        ; Fill in buffer address and size
744
        mov     [edi + txfd.virt_addr], esi
745
        mov     eax, esi
746
        add     eax, [esi + NET_BUFF.offset]
747
        push    edi
4581 hidnplayr 748
        invoke  GetPhysAddr
5525 hidnplayr 749
        pop     edi
750
        mov     [edi + txfd.buf_addr], eax
751
        mov     ecx, [esi + NET_BUFF.length]
752
        mov     [edi + txfd.buf_size], ecx
3545 hidnplayr 753
 
754
        ; Inform device of the new/updated transmit descriptor
5525 hidnplayr 755
        mov     eax, edi
4581 hidnplayr 756
        invoke  GetPhysAddr
757
        set_io  [ebx + device.io_addr], 0
5562 hidnplayr 758
        set_io  [ebx + device.io_addr], REG_SCB_PTR
3545 hidnplayr 759
        out     dx, eax
760
 
761
        ; Start the transmit
5562 hidnplayr 762
        set_io  [ebx + device.io_addr], REG_SCB_CMD
3545 hidnplayr 763
        mov     ax, CU_START
764
        out     dx, ax
765
 
5525 hidnplayr 766
        ; Update stats
4581 hidnplayr 767
        inc     [ebx + device.packets_tx]
768
        add     dword[ebx + device.bytes_tx], ecx
769
        adc     dword[ebx + device.bytes_tx + 4], 0
3545 hidnplayr 770
 
5525 hidnplayr 771
        ; Wait for command to complete
772
        call    cmd_wait
773
 
774
        inc     [ebx + device.cur_tx]
775
        and     [ebx + device.cur_tx], TX_RING_SIZE - 1
776
 
3545 hidnplayr 777
        DEBUGF  1,"Transmit OK\n"
4581 hidnplayr 778
        popf
3545 hidnplayr 779
        xor     eax, eax
4581 hidnplayr 780
        ret
3545 hidnplayr 781
 
4581 hidnplayr 782
  .fail:
5525 hidnplayr 783
        DEBUGF  2,"Transmit failed!\n"
5522 hidnplayr 784
        invoke  NetFree, [bufferptr]
4581 hidnplayr 785
        popf
3545 hidnplayr 786
        or      eax, -1
4581 hidnplayr 787
        ret
3545 hidnplayr 788
 
4581 hidnplayr 789
endp
790
 
791
 
3545 hidnplayr 792
;;;;;;;;;;;;;;;;;;;;;;;
793
;;                   ;;
794
;; Interrupt handler ;;
795
;;                   ;;
796
;;;;;;;;;;;;;;;;;;;;;;;
797
 
798
align 4
799
int_handler:
800
 
801
        push    ebx esi edi
802
 
3845 hidnplayr 803
        DEBUGF  1,"INT\n"
3545 hidnplayr 804
 
805
; find pointer of device wich made IRQ occur
806
 
807
        mov     ecx, [devices]
808
        test    ecx, ecx
809
        jz      .nothing
810
        mov     esi, device_list
811
  .nextdevice:
812
        mov     ebx, [esi]
813
 
5562 hidnplayr 814
;        set_io  [ebx + device.io_addr], 0      ; REG_SCB_STATUS = 0
815
        set_io  [ebx + device.io_addr], REG_SCB_STATUS
3545 hidnplayr 816
        in      ax, dx
5562 hidnplayr 817
        out     dx, ax                          ; send it back to ACK
3545 hidnplayr 818
        test    ax, ax
819
        jnz     .got_it
820
  .continue:
821
        add     esi, 4
822
        dec     ecx
823
        jnz     .nextdevice
824
  .nothing:
825
        pop     edi esi ebx
826
        xor     eax, eax
827
 
6717 hidnplayr 828
        ret                                         ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
3545 hidnplayr 829
 
830
  .got_it:
831
 
832
        DEBUGF  1,"Device: %x Status: %x\n", ebx, ax
833
 
5562 hidnplayr 834
        test    ax, SCB_STATUS_FR               ; did we receive a frame?
3545 hidnplayr 835
        jz      .no_rx
836
 
837
        push    ax
838
 
839
        DEBUGF  1,"Receiving\n"
840
 
841
        push    ebx
842
  .rx_loop:
843
        pop     ebx
844
 
4581 hidnplayr 845
        mov     esi, [ebx + device.rx_desc]
5562 hidnplayr 846
        test    [esi + sizeof.NET_BUFF + rxfd.status], RXFD_STATUS_C            ; Completed?
847
        jz      .no_rx_
848
        test    [esi + sizeof.NET_BUFF + rxfd.status], RXFD_STATUS_OK           ; OK?
849
        jz      .not_ok
3545 hidnplayr 850
 
5522 hidnplayr 851
        DEBUGF  1,"rxfd status=0x%x\n", [esi + sizeof.NET_BUFF + rxfd.status]:4
3545 hidnplayr 852
 
5522 hidnplayr 853
        movzx   ecx, [esi + sizeof.NET_BUFF + rxfd.count]
3545 hidnplayr 854
        and     ecx, 0x3fff
855
 
856
        push    ebx
857
        push    .rx_loop
858
        push    esi
5522 hidnplayr 859
        mov     [esi + NET_BUFF.length], ecx
860
        mov     [esi + NET_BUFF.device], ebx
861
        mov     [esi + NET_BUFF.offset], NET_BUFF.data + rxfd.packet
3545 hidnplayr 862
 
863
; Update stats
4581 hidnplayr 864
        add     dword [ebx + device.bytes_rx], ecx
865
        adc     dword [ebx + device.bytes_rx + 4], 0
866
        inc     dword [ebx + device.packets_rx]
3545 hidnplayr 867
 
868
; allocate new descriptor
869
 
5522 hidnplayr 870
        invoke  NetAlloc, 2000
5561 hidnplayr 871
        test    eax, eax
872
        jz      .out_of_mem
4581 hidnplayr 873
        mov     [ebx + device.rx_desc], eax
3545 hidnplayr 874
        mov     esi, eax
4581 hidnplayr 875
        invoke  GetPhysAddr
5522 hidnplayr 876
        add     eax, NET_BUFF.data
5562 hidnplayr 877
        mov     [esi + sizeof.NET_BUFF + rxfd.status], 0
878
        mov     [esi + sizeof.NET_BUFF + rxfd.command], RXFD_CMD_EL or RXFD_CMD_SUSPEND
5522 hidnplayr 879
        mov     [esi + sizeof.NET_BUFF + rxfd.link], eax
880
        mov     [esi + sizeof.NET_BUFF + rxfd.count], 0
881
        mov     [esi + sizeof.NET_BUFF + rxfd.size], 1528
3545 hidnplayr 882
 
883
; restart RX
884
 
4581 hidnplayr 885
        set_io  [ebx + device.io_addr], 0
5562 hidnplayr 886
        set_io  [ebx + device.io_addr], REG_SCB_PTR
5560 hidnplayr 887
;        mov     eax, [ebx + device.rx_desc]
4581 hidnplayr 888
;        invoke  GetPhysAddr
5560 hidnplayr 889
;        add     eax, NET_BUFF.data
3545 hidnplayr 890
        out     dx, eax
891
 
5562 hidnplayr 892
        set_io  [ebx + device.io_addr], REG_SCB_CMD
3545 hidnplayr 893
        mov     ax, RX_START
894
        out     dx, ax
895
        call    cmd_wait
5561 hidnplayr 896
  .out_of_mem:
3545 hidnplayr 897
 
5562 hidnplayr 898
; Hand the frame over to the kernel
5522 hidnplayr 899
        jmp     [EthInput]
3545 hidnplayr 900
 
5562 hidnplayr 901
  .not_ok:
902
; Reset the FD
903
        mov     [esi + sizeof.NET_BUFF + rxfd.status], 0
904
        mov     [esi + sizeof.NET_BUFF + rxfd.command], RXFD_CMD_EL or RXFD_CMD_SUSPEND
905
        mov     [esi + sizeof.NET_BUFF + rxfd.count], 0
906
 
907
; Restart RX
908
        set_io  [ebx + device.io_addr], 0
909
        set_io  [ebx + device.io_addr], REG_SCB_PTR
910
        mov     eax, esi
911
        invoke  GetPhysAddr
912
        add     eax, NET_BUFF.data
913
        out     dx, eax
914
 
915
        set_io  [ebx + device.io_addr], REG_SCB_CMD
916
        mov     ax, RX_START
917
        out     dx, ax
918
        call    cmd_wait
919
 
920
        push    ebx
921
        jmp     .rx_loop
922
 
923
  .no_rx_:
3545 hidnplayr 924
        DEBUGF  1, "no more data\n"
925
        pop     ax
926
 
927
  .no_rx:
928
 
5562 hidnplayr 929
        test    ax, SCB_STATUS_CNA
5525 hidnplayr 930
        jz      .no_tx
931
        DEBUGF  1, "Command completed\n"
3545 hidnplayr 932
 
5525 hidnplayr 933
        push    eax
934
  .loop_tx:
935
        mov     edi, [ebx + device.last_tx]
936
        mov     eax, sizeof.txfd
937
        mul     eax
938
        lea     edi, [ebx + device.tx_ring + eax]
939
 
940
        cmp     [edi + txfd.status], 0
941
        je      .tx_done
942
 
943
        cmp     [edi + txfd.virt_addr], 0
944
        je      .tx_done
945
 
946
        DEBUGF  1,"Freeing buffer 0x%x\n", [edi + txfd.virt_addr]
947
 
948
        push    [edi + txfd.virt_addr]
949
        mov     [edi + txfd.virt_addr], 0
950
        invoke  NetFree
951
 
952
        inc     [ebx + device.last_tx]
953
        and     [ebx + device.last_tx], TX_RING_SIZE - 1
954
 
955
        jmp     .loop_tx
956
  .tx_done:
957
        pop     eax
958
  .no_tx:
959
 
5562 hidnplayr 960
        test    ax, RU_STATUS_NO_RESOURCES
3545 hidnplayr 961
        jne     .fail
962
 
5560 hidnplayr 963
        DEBUGF  2, "Out of resources!\n"
3545 hidnplayr 964
 
965
  .fail:
966
        pop     edi esi ebx
967
        xor     eax, eax
968
        inc     eax
969
 
970
        ret
971
 
972
 
973
 
974
 
975
align 4
976
cmd_wait:
977
 
978
        in      al, dx
979
        test    al, al
980
        jnz     cmd_wait
981
 
982
        ret
983
 
984
 
985
 
986
 
987
 
988
 
989
align 4
990
ee_read:        ; esi = address to read
991
 
3845 hidnplayr 992
        DEBUGF  1,"Eeprom read from 0x%x\n", esi
3545 hidnplayr 993
 
4581 hidnplayr 994
        set_io  [ebx + device.io_addr], 0
5562 hidnplayr 995
        set_io  [ebx + device.io_addr], REG_EEPROM
3545 hidnplayr 996
 
997
;-----------------------------------------------------
998
; Prepend start bit + read opcode to the address field
999
; and shift it to the very left bits of esi
1000
 
1001
        mov     cl, 29
4581 hidnplayr 1002
        sub     cl, [ebx + device.ee_bus_width]
3545 hidnplayr 1003
        shl     esi, cl
1004
        or      esi, EE_READ shl 29
1005
 
4581 hidnplayr 1006
        movzx   ecx, [ebx + device.ee_bus_width]
3545 hidnplayr 1007
        add     ecx, 3
1008
 
6717 hidnplayr 1009
        mov     ax, 0x4800 + EE_CS
1010
        out     dx, ax
5247 hidnplayr 1011
        call    udelay
3545 hidnplayr 1012
 
1013
;-----------------------
1014
; Write this to the chip
1015
 
1016
  .loop:
6717 hidnplayr 1017
        mov     al, EE_CS
3545 hidnplayr 1018
        shl     esi, 1
1019
        jnc     @f
1020
        or      al, EE_DI
1021
       @@:
1022
        out     dx, al
5247 hidnplayr 1023
        call    udelay
3545 hidnplayr 1024
 
6717 hidnplayr 1025
        or      al, EE_SK
3545 hidnplayr 1026
        out     dx, al
5247 hidnplayr 1027
        call    udelay
3545 hidnplayr 1028
 
1029
        loop    .loop
1030
 
1031
;------------------------------
1032
; Now read the data from eeprom
1033
 
1034
        xor     esi, esi
1035
        mov     ecx, 16
1036
 
1037
  .loop2:
1038
        shl     esi, 1
6717 hidnplayr 1039
        mov     al, EE_CS
3545 hidnplayr 1040
        out     dx, al
5247 hidnplayr 1041
        call    udelay
3545 hidnplayr 1042
 
6717 hidnplayr 1043
        or      al, EE_SK
1044
        out     dx, al
1045
        call    udelay
1046
 
3545 hidnplayr 1047
        in      al, dx
1048
        test    al, EE_DO
1049
        jz      @f
1050
        inc     esi
1051
       @@:
1052
 
1053
        loop    .loop2
1054
 
1055
;-----------------------
1056
; de-activate the eeprom
1057
 
6717 hidnplayr 1058
        xor     al, al
1059
        out     dx, al
3545 hidnplayr 1060
 
3845 hidnplayr 1061
        DEBUGF  1,"0x%x\n", esi:4
3545 hidnplayr 1062
        ret
1063
 
1064
 
1065
 
1066
align 4
1067
ee_write:       ; esi = address to write to, di = data
1068
 
1069
        DEBUGF  1,"Eeprom write 0x%x to 0x%x\n", di, esi
1070
 
4581 hidnplayr 1071
        set_io  [ebx + device.io_addr], 0
5562 hidnplayr 1072
        set_io  [ebx + device.io_addr], REG_EEPROM
3545 hidnplayr 1073
 
1074
;-----------------------------------------------------
1075
; Prepend start bit + write opcode to the address field
1076
; and shift it to the very left bits of esi
1077
 
1078
        mov     cl, 29
4581 hidnplayr 1079
        sub     cl, [ebx + device.ee_bus_width]
3545 hidnplayr 1080
        shl     esi, cl
1081
        or      esi, EE_WRITE shl 29
1082
 
4581 hidnplayr 1083
        movzx   ecx, [ebx + device.ee_bus_width]
3545 hidnplayr 1084
        add     ecx, 3
1085
 
6717 hidnplayr 1086
        mov     ax, 0x4800 + EE_CS       ; enable chip
1087
        out     dx, ax
3545 hidnplayr 1088
 
1089
;-----------------------
1090
; Write this to the chip
1091
 
1092
  .loop:
6717 hidnplayr 1093
        mov     al, EE_CS
3545 hidnplayr 1094
        shl     esi, 1
1095
        jnc     @f
1096
        or      al, EE_DI
1097
       @@:
1098
        out     dx, al
5247 hidnplayr 1099
        call    udelay
3545 hidnplayr 1100
 
6717 hidnplayr 1101
        or      al, EE_SK
3545 hidnplayr 1102
        out     dx, al
5247 hidnplayr 1103
        call    udelay
3545 hidnplayr 1104
 
1105
        loop    .loop
1106
 
1107
;-----------------------------
1108
; Now write the data to eeprom
1109
 
1110
        mov     ecx, 16
1111
 
1112
  .loop2:
6717 hidnplayr 1113
        mov     al, EE_CS
3545 hidnplayr 1114
        shl     di, 1
1115
        jnc     @f
1116
        or      al, EE_DI
1117
       @@:
1118
        out     dx, al
5247 hidnplayr 1119
        call    udelay
3545 hidnplayr 1120
 
6717 hidnplayr 1121
        or      al, EE_SK
3545 hidnplayr 1122
        out     dx, al
5247 hidnplayr 1123
        call    udelay
3545 hidnplayr 1124
 
1125
        loop    .loop2
1126
 
1127
;-----------------------
1128
; de-activate the eeprom
1129
 
1130
        xor     al, al
1131
        out     dx, al
1132
 
1133
 
1134
        ret
1135
 
1136
 
1137
 
1138
align 4
1139
ee_get_width:
1140
 
4581 hidnplayr 1141
        set_io  [ebx + device.io_addr], 0
5562 hidnplayr 1142
        set_io  [ebx + device.io_addr], REG_EEPROM
3545 hidnplayr 1143
 
6717 hidnplayr 1144
        mov     ax, 0x4800 + EE_CS      ; activate eeprom
1145
        out     dx, ax
5247 hidnplayr 1146
        call    udelay
3545 hidnplayr 1147
 
1148
        mov     si, EE_READ shl 13
1149
        xor     ecx, ecx
1150
  .loop:
6717 hidnplayr 1151
        mov     al, EE_CS
3545 hidnplayr 1152
        shl     si, 1
1153
        jnc     @f
1154
        or      al, EE_DI
1155
       @@:
6717 hidnplayr 1156
        out     dx, ax
5247 hidnplayr 1157
        call    udelay
3545 hidnplayr 1158
 
6717 hidnplayr 1159
        or      al, EE_SK
1160
        out     dx, ax
5247 hidnplayr 1161
        call    udelay
3545 hidnplayr 1162
 
1163
        inc     ecx
1164
 
1165
        cmp     ecx, 15
1166
        jae     .give_up
1167
 
1168
        in      al, dx
1169
        test    al, EE_DO
1170
        jnz     .loop
1171
 
1172
        xor     al, al
6717 hidnplayr 1173
        out     dx, al                  ; de-activate eeprom
3545 hidnplayr 1174
 
6717 hidnplayr 1175
        sub     cl, 3                   ; dont count the opcode bits
4581 hidnplayr 1176
        mov     [ebx + device.ee_bus_width], cl
3845 hidnplayr 1177
        DEBUGF  1, "Eeprom width=%u bit\n", ecx
3545 hidnplayr 1178
 
3845 hidnplayr 1179
        ret
3545 hidnplayr 1180
 
3845 hidnplayr 1181
  .give_up:
1182
        DEBUGF  2, "Eeprom not found!\n"
1183
        xor     al, al
6717 hidnplayr 1184
        out     dx, al                  ; de-activate eeprom
3545 hidnplayr 1185
 
1186
        ret
1187
 
1188
 
5247 hidnplayr 1189
; Wait a minimum of 2µs
1190
udelay:
1191
        pusha
1192
        mov     esi, 1
1193
        invoke  Sleep
1194
        popa
3545 hidnplayr 1195
 
5247 hidnplayr 1196
        ret
1197
 
1198
 
1199
 
3545 hidnplayr 1200
; cx = phy addr
1201
; dx = phy reg addr
1202
 
1203
; ax = data
1204
 
1205
align 4
1206
mdio_read:
1207
 
1208
        DEBUGF  1,"MDIO read\n"
1209
 
1210
        shl     ecx, 21                 ; PHY addr
6717 hidnplayr 1211
        mov     eax, ecx
3545 hidnplayr 1212
        shl     edx, 16                 ; PHY reg addr
1213
        or      eax, edx
1214
        or      eax, 10b shl 26         ; read opcode
1215
 
4581 hidnplayr 1216
        set_io  [ebx + device.io_addr], 0
5562 hidnplayr 1217
        set_io  [ebx + device.io_addr], REG_MDI_CTRL
3545 hidnplayr 1218
        out     dx, eax
1219
 
1220
  .wait:
5247 hidnplayr 1221
        call    udelay
3545 hidnplayr 1222
        in      eax, dx
1223
        test    eax, 1 shl 28           ; ready bit
1224
        jz      .wait
1225
 
1226
        ret
1227
 
6717 hidnplayr 1228
 
1229
 
3545 hidnplayr 1230
; ax = data
1231
; cx = phy addr
1232
; dx = phy reg addr
1233
 
1234
; ax = data
1235
 
1236
align 4
1237
mdio_write:
1238
 
1239
        DEBUGF  1,"MDIO write\n"
1240
 
1241
        and     eax, 0xffff
1242
 
1243
        shl     ecx, 21                 ; PHY addr
1244
        shl     edx, 16                 ; PHY reg addr
1245
 
1246
        or      eax, ecx
1247
        or      eax, edx
1248
        or      eax, 01b shl 26         ; write opcode
1249
 
4581 hidnplayr 1250
        set_io  [ebx + device.io_addr], 0
5562 hidnplayr 1251
        set_io  [ebx + device.io_addr], REG_MDI_CTRL
3545 hidnplayr 1252
        out     dx, eax
1253
 
1254
  .wait:
5247 hidnplayr 1255
        call    udelay
3545 hidnplayr 1256
        in      eax, dx
1257
        test    eax, 1 shl 28           ; ready bit
1258
        jz      .wait
1259
 
1260
        ret
1261
 
1262
 
1263
align 4
6717 hidnplayr 1264
mac_read_eeprom:
3545 hidnplayr 1265
 
1266
        mov     esi, 0
1267
        call    ee_read
4581 hidnplayr 1268
        mov     word[ebx + device.mac], si
3545 hidnplayr 1269
 
1270
        mov     esi, 1
1271
        call    ee_read
4581 hidnplayr 1272
        mov     word[ebx + device.mac+2], si
3545 hidnplayr 1273
 
1274
        mov     esi, 2
1275
        call    ee_read
4581 hidnplayr 1276
        mov     word[ebx + device.mac+4], si
3545 hidnplayr 1277
 
1278
 
1279
        ret
1280
 
1281
 
1282
; End of code
1283
 
1284
 
4581 hidnplayr 1285
data fixups
1286
end data
1287
 
1288
include '../peimport.inc'
1289
 
4629 hidnplayr 1290
my_service      db 'I8255X', 0                    ; max 16 chars include zero
3545 hidnplayr 1291
devicename      db 'Intel Etherexpress pro/100', 0
1292
 
1293
confcmd_data    db 22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1
1294
                db 0, 0x2e, 0, 0x60, 0, 0xf2, 0x48, 0, 0x40, 0xf2
1295
                db 0x80, 0x3f, 0x05                                     ; 22 bytes total
1296
 
1297
 
1298
device_id_list:
6717 hidnplayr 1299
dw 0x1029
1300
dw 0x1030
1301
dw 0x1031
1302
dw 0x1032
1303
dw 0x1033
1304
dw 0x1034
1305
dw 0x1038
1306
dw 0x1039
1307
dw 0x103A
1308
dw 0x103B
1309
dw 0x103C
1310
dw 0x103D
1311
dw 0x103E
1312
dw 0x1050
1313
dw 0x1051
1314
dw 0x1052
1315
dw 0x1053
1316
dw 0x1054
1317
dw 0x1055
1318
dw 0x1056
1319
dw 0x1057
1320
dw 0x1059
1321
dw 0x1064
1322
dw 0x1065
1323
dw 0x1066
1324
dw 0x1067
1325
dw 0x1068
1326
dw 0x1069
1327
dw 0x106A
1328
dw 0x106B
1329
dw 0x1091
1330
dw 0x1092
1331
dw 0x1093
1332
dw 0x1094
1333
dw 0x1095
1334
dw 0x10fe
1335
dw 0x1209
1336
dw 0x1229
1337
dw 0x2449
1338
dw 0x2459
1339
dw 0x245D
1340
dw 0x27DC
3545 hidnplayr 1341
 
1342
DEVICE_IDs = ($ - device_id_list) / 2
1343
 
1344
include_debug_strings                           ; All data wich FDO uses will be included here
1345
 
4581 hidnplayr 1346
align 4
1347
devices         dd 0                              ; number of currently running devices
1348
device_list     rd MAX_DEVICES                    ; This list contains all pointers to device structures the driver is handling
3545 hidnplayr 1349