Subversion Repositories Kolibri OS

Rev

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