Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2220 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2313 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved.    ;;
2220 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
;;                                                                 ;;
14
;; Good read about how to program this family of devices:          ;;
15
;; http://www.intel.com/design/network/manuals/8255x_opensdm.htm   ;;
16
;;                                                                 ;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18
 
19
 
20
format MS COFF
21
 
2387 hidnplayr 22
        API_VERSION             equ 0x01000100
23
        DRIVER_VERSION          equ 5
2220 hidnplayr 24
 
2387 hidnplayr 25
        MAX_DEVICES             equ 16
2220 hidnplayr 26
 
2387 hidnplayr 27
        DEBUG                   equ 1
28
        __DEBUG__               equ 1
29
        __DEBUG_LEVEL__         equ 1
2220 hidnplayr 30
 
31
include 'proc32.inc'
32
include 'imports.inc'
33
include 'fdo.inc'
34
include 'netdrv.inc'
35
 
36
public START
37
public service_proc
38
public version
39
 
40
virtual at ebx
41
 
2387 hidnplayr 42
        device:
2220 hidnplayr 43
 
2387 hidnplayr 44
        ETH_DEVICE
2220 hidnplayr 45
 
2387 hidnplayr 46
        .io_addr        dd ?
47
        .pci_bus        db ?
48
        .pci_dev        db ?
49
        .irq_line       db ?
2220 hidnplayr 50
 
2387 hidnplayr 51
        .rx_buffer      dd ?
52
        .tx_buffer      dd ?
2220 hidnplayr 53
 
2387 hidnplayr 54
        .ee_bus_width   dd ?
2220 hidnplayr 55
 
2387 hidnplayr 56
        rb 5+8 ;;;; align
2313 hidnplayr 57
 
2387 hidnplayr 58
        rxfd:
59
        .status         dw ?
60
        .command        dw ?
61
        .link           dd ?
62
        .rx_buf_addr    dd ?
63
        .count          dw ?
64
        .size           dw ?
65
        .packet         dd ?
2220 hidnplayr 66
 
2387 hidnplayr 67
        rb 12 ;;;;
2313 hidnplayr 68
 
2387 hidnplayr 69
        txfd:
70
        .status         dw ?
71
        .command        dw ?
72
        .link           dd ?
73
        .tx_desc_addr   dd ?
74
        .count          dd ?
75
        .tx_buf_addr0   dd ?
76
        .tx_buf_size0   dd ?
77
        .tx_buf_addr1   dd ?
78
        .tx_buf_size1   dd ?
2220 hidnplayr 79
 
2387 hidnplayr 80
        confcmd:
81
        .status:        dw ?
82
        .command:       dw ?
83
        .link:          dd ?
84
        .data           rb 64
2220 hidnplayr 85
 
2387 hidnplayr 86
        lstats:
87
        tx_good_frames          dd ?
88
        tx_coll16_errs          dd ?
89
        tx_late_colls           dd ?
90
        tx_underruns            dd ?
91
        tx_lost_carrier         dd ?
92
        tx_deferred             dd ?
93
        tx_one_colls            dd ?
94
        tx_multi_colls          dd ?
95
        tx_total_colls          dd ?
2220 hidnplayr 96
 
2387 hidnplayr 97
        rx_good_frames          dd ?
98
        rx_crc_errs             dd ?
99
        rx_align_errs           dd ?
100
        rx_resource_errs        dd ?
101
        rx_overrun_errs         dd ?
102
        rx_colls_errs           dd ?
103
        rx_runt_errs            dd ?
2220 hidnplayr 104
 
2387 hidnplayr 105
        device_size = $ - device
2220 hidnplayr 106
 
107
end virtual
108
 
109
 
110
; Serial EEPROM
111
 
2387 hidnplayr 112
EE_SK           equ 1 shl 16   ; serial clock
113
EE_CS           equ 1 shl 17   ; chip select
114
EE_DI           equ 1 shl 18   ; data in
115
EE_DO           equ 1 shl 19   ; data out
2220 hidnplayr 116
 
2387 hidnplayr 117
EE_READ         equ 110b
118
EE_WRITE        equ 101b
119
EE_ERASE        equ 111b
2220 hidnplayr 120
 
121
; The SCB accepts the following controls for the Tx and Rx units:
122
 
2387 hidnplayr 123
CU_START        equ 0x0010
124
CU_RESUME       equ 0x0020
125
CU_STATSADDR    equ 0x0040
126
CU_SHOWSTATS    equ 0x0050   ; Dump statistics counters.
127
CU_CMD_BASE     equ 0x0060   ; Base address to add to add CU commands.
128
CU_DUMPSTATS    equ 0x0070   ; Dump then reset stats counters.
2220 hidnplayr 129
 
2387 hidnplayr 130
RX_START        equ 0x0001
131
RX_RESUME       equ 0x0002
132
RX_ABORT        equ 0x0004
133
RX_ADDR_LOAD    equ 0x0006
134
RX_RESUMENR     equ 0x0007
135
INT_MASK        equ 0x0100
136
DRVR_INT        equ 0x0200   ; Driver generated interrupt
2220 hidnplayr 137
 
2387 hidnplayr 138
CmdIASetup      equ 0x0001
139
CmdConfigure    equ 0x0002
140
CmdTx           equ 0x0004 ;;;;
141
CmdTxFlex       equ 0x0008 ;;;
142
Cmdsuspend      equ 0x4000
2220 hidnplayr 143
 
144
 
2387 hidnplayr 145
reg_scb_status  equ 0
146
reg_scb_cmd     equ 2
147
reg_scb_ptr     equ 4
148
reg_port        equ 8
2220 hidnplayr 149
reg_eeprom_ctrl equ 12
2387 hidnplayr 150
reg_eeprom      equ 14
151
reg_mdi_ctrl    equ 16
2220 hidnplayr 152
 
153
 
154
macro delay {
2387 hidnplayr 155
        push    eax
156
        in      eax, dx
157
        in      eax, dx
158
        in      eax, dx
159
        in      eax, dx
160
        in      eax, dx
161
        in      eax, dx
162
        in      eax, dx
163
        in      eax, dx
164
        in      eax, dx
165
        in      eax, dx
166
        pop     eax
2220 hidnplayr 167
}
168
 
169
section '.flat' code readable align 16
170
 
171
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
172
;;                        ;;
173
;; proc START             ;;
174
;;                        ;;
175
;; (standard driver proc) ;;
176
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
177
 
178
proc START stdcall, state:dword
179
 
2387 hidnplayr 180
        cmp [state], 1
181
        jne .exit
2220 hidnplayr 182
 
183
  .entry:
184
 
2387 hidnplayr 185
        DEBUGF 1,"Loading i8255x driver\n"
186
        stdcall RegService, my_service, service_proc
187
        ret
2220 hidnplayr 188
 
189
  .fail:
190
  .exit:
2387 hidnplayr 191
        xor eax, eax
192
        ret
2220 hidnplayr 193
 
194
endp
195
 
196
 
197
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
198
;;                        ;;
199
;; proc SERVICE_PROC      ;;
200
;;                        ;;
201
;; (standard driver proc) ;;
202
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
203
 
204
align 4
205
proc service_proc stdcall, ioctl:dword
206
 
2387 hidnplayr 207
        mov     edx, [ioctl]
208
        mov     eax, [IOCTL.io_code]
2220 hidnplayr 209
 
210
;------------------------------------------------------
211
 
2387 hidnplayr 212
        cmp     eax, 0 ;SRV_GETVERSION
213
        jne     @F
2220 hidnplayr 214
 
2387 hidnplayr 215
        cmp     [IOCTL.out_size], 4
216
        jl      .fail
217
        mov     eax, [IOCTL.output]
218
        mov     [eax], dword API_VERSION
2220 hidnplayr 219
 
2387 hidnplayr 220
        xor     eax, eax
221
        ret
2220 hidnplayr 222
 
223
;------------------------------------------------------
224
  @@:
2387 hidnplayr 225
        cmp     eax, 1 ;SRV_HOOK
226
        jne     .fail
2220 hidnplayr 227
 
2387 hidnplayr 228
        cmp     [IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
229
        jl      .fail
2220 hidnplayr 230
 
2387 hidnplayr 231
        mov     eax, [IOCTL.input]
232
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
233
        jne     .fail                                   ; other types arent supported for this card yet
2220 hidnplayr 234
 
235
; check if the device is already listed
236
 
2387 hidnplayr 237
        mov     esi, device_list
238
        mov     ecx, [devices]
239
        test    ecx, ecx
240
        jz      .firstdevice
2220 hidnplayr 241
 
242
;        mov     eax, [IOCTL.input]                      ; get the pci bus and device numbers
2387 hidnplayr 243
        mov     ax , [eax+1]                            ;
2220 hidnplayr 244
  .nextdevice:
2387 hidnplayr 245
        mov     ebx, [esi]
246
        cmp     ax , word [device.pci_bus]              ; compare with pci and device num in device list (notice the usage of word instead of byte)
247
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
248
        add     esi, 4
249
        loop    .nextdevice
2220 hidnplayr 250
 
251
 
252
; This device doesnt have its own eth_device structure yet, lets create one
253
  .firstdevice:
2387 hidnplayr 254
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
255
        jge     .fail
2220 hidnplayr 256
 
2387 hidnplayr 257
        push    edx
258
        stdcall KernelAlloc, device_size
259
        pop     edx
260
        test    eax, eax
261
        jz      .fail
262
        mov     ebx, eax                                ; ebx is always used as a pointer to the structure (in driver, but also in kernel code)
2220 hidnplayr 263
 
264
; Fill in the direct call addresses into the struct
265
 
2387 hidnplayr 266
        mov     [device.reset], reset
267
        mov     [device.transmit], transmit
2220 hidnplayr 268
;        mov     [device.get_MAC], read_mac
2387 hidnplayr 269
        mov     [device.set_MAC], MAC_write
270
        mov     [device.unload], unload
271
        mov     [device.name], my_service
2220 hidnplayr 272
 
273
; save the pci bus and device numbers
274
 
2387 hidnplayr 275
        mov     eax, [IOCTL.input]
276
        mov     cl , [eax+1]
277
        mov     [device.pci_bus], cl
278
        mov     cl , [eax+2]
279
        mov     [device.pci_dev], cl
2220 hidnplayr 280
 
281
; Now, it's time to find the base io addres of the PCI device
282
 
2387 hidnplayr 283
        find_io [device.pci_bus], [device.pci_dev], [device.io_addr]
2220 hidnplayr 284
 
285
; We've found the io address, find IRQ now
286
 
2387 hidnplayr 287
        find_irq [device.pci_bus], [device.pci_dev], [device.irq_line]
2220 hidnplayr 288
 
2387 hidnplayr 289
        DEBUGF  2,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
290
        [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4
2220 hidnplayr 291
 
2387 hidnplayr 292
        allocate_and_clear [device.rx_buffer], (4096), .err
293
        allocate_and_clear [device.tx_buffer], (4096), .err
2220 hidnplayr 294
 
295
; Ok, the eth_device structure is ready, let's probe the device
296
 
2387 hidnplayr 297
        call    probe                                                   ; this function will output in eax
298
        test    eax, eax
299
        jnz     .err                                                    ; If an error occured, exit
2220 hidnplayr 300
 
2387 hidnplayr 301
        mov     eax, [devices]                                          ; Add the device structure to our device list
302
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
303
        inc     [devices]                                               ;
2220 hidnplayr 304
 
305
 
2387 hidnplayr 306
        mov     [device.type], NET_TYPE_ETH
307
        call    NetRegDev
2220 hidnplayr 308
 
2387 hidnplayr 309
        cmp     eax, -1
310
        je      .err
2220 hidnplayr 311
 
2387 hidnplayr 312
        ret
2220 hidnplayr 313
 
314
; If the device was already loaded, find the device number and return it in eax
315
 
316
  .find_devicenum:
2387 hidnplayr 317
        DEBUGF  2,"Trying to find device number of already registered device\n"
318
        call    NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
319
                                                                        ; into a device number in edi
320
        mov     eax, edi                                                ; Application wants it in eax instead
321
        DEBUGF  2,"Kernel says: %u\n", eax
322
        ret
2220 hidnplayr 323
 
324
; If an error occured, remove all allocated data and exit (returning -1 in eax)
325
 
326
  .err:
2387 hidnplayr 327
        stdcall KernelFree, [device.rx_buffer]
328
        stdcall KernelFree, [device.tx_buffer]
329
        stdcall KernelFree, ebx
2220 hidnplayr 330
 
331
  .fail:
2387 hidnplayr 332
        or      eax, -1
333
        ret
2220 hidnplayr 334
 
335
;------------------------------------------------------
336
endp
337
 
338
 
339
 
340
 
341
 
342
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
343
;;                                                                        ;;
344
;;        Actual Hardware dependent code starts here                      ;;
345
;;                                                                        ;;
346
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
347
 
348
 
349
unload:
2387 hidnplayr 350
        ; TODO: (in this particular order)
351
        ;
352
        ; - Stop the device
353
        ; - Detach int handler
354
        ; - Remove device from local list (device_list)
355
        ; - call unregister function in kernel
356
        ; - Remove all allocated structures and buffers the card used
2220 hidnplayr 357
 
2387 hidnplayr 358
        or      eax,-1
2220 hidnplayr 359
 
360
ret
361
 
362
 
363
;-------------
364
;
365
; Probe
366
;
367
;-------------
368
 
369
align 4
370
probe:
371
 
2387 hidnplayr 372
        DEBUGF  1,"Probing i8255x\n"
2220 hidnplayr 373
 
2387 hidnplayr 374
        make_bus_master [device.pci_bus], [device.pci_dev]
2220 hidnplayr 375
 
376
;---------------------------
377
; First, identify the device
378
 
2387 hidnplayr 379
        movzx   ecx, [device.pci_bus]
380
        movzx   edx, [device.pci_dev]
381
        stdcall PciRead32, ecx ,edx ,0                                ; get device/vendor id
2220 hidnplayr 382
 
2387 hidnplayr 383
        DEBUGF  1,"Vendor_id=0x%x\n", ax
2220 hidnplayr 384
 
2387 hidnplayr 385
        cmp     ax, 0x8086
386
        jne     .notfound
387
        shr     eax, 16
2220 hidnplayr 388
 
2387 hidnplayr 389
        DEBUGF  1,"Device_id=0x%x\n", ax
2220 hidnplayr 390
 
2387 hidnplayr 391
        mov     ecx, DEVICE_IDs
392
        mov     edi, device_id_list
393
        repne   scasw
394
        jne     .notfound
395
        jmp     .found
2220 hidnplayr 396
 
397
  .notfound:
2387 hidnplayr 398
        DEBUGF  1,"ERROR: Unsupported device!\n"
399
        or      eax, -1
400
        ret
2220 hidnplayr 401
 
402
  .found:
403
 
2387 hidnplayr 404
        call    ee_get_width
405
        call    MAC_read_eeprom
2220 hidnplayr 406
 
2387 hidnplayr 407
        ;;; TODO: detect phy
2220 hidnplayr 408
 
409
 
410
 
411
;----------
412
;
413
;  Reset
414
;
415
;----------
416
 
417
align 4
418
reset:
419
 
420
;---------------
421
; reset the card
422
 
2387 hidnplayr 423
        set_io  0
424
        set_io  reg_port
425
        xor     eax, eax        ; Software Reset
426
        out     dx, eax
2220 hidnplayr 427
 
2387 hidnplayr 428
        mov     esi, 10
429
        call    Sleep           ; Give the card time to warm up.
2220 hidnplayr 430
 
431
;---------------------------------
432
; Tell device where to store stats
433
 
2387 hidnplayr 434
        lea     eax, [lstats]
435
        GetRealAddr
436
        set_io  reg_scb_ptr
437
        out     dx, eax
2220 hidnplayr 438
 
2387 hidnplayr 439
        mov     ax, INT_MASK + CU_STATSADDR
440
        set_io  reg_scb_cmd
441
        out     dx, ax
442
        call    cmd_wait
2220 hidnplayr 443
 
444
;-----------------
445
; Set CU base to 0
446
 
2387 hidnplayr 447
        xor     eax, eax
448
        set_io  reg_scb_ptr
449
        out     dx, eax
2220 hidnplayr 450
 
2387 hidnplayr 451
        mov     ax, INT_MASK + RX_ADDR_LOAD
452
        set_io  reg_scb_cmd
453
        out     dx, ax
454
        call    cmd_wait
2220 hidnplayr 455
 
456
;---------------------
457
; build rxfd structure
458
 
2387 hidnplayr 459
        mov     ax, 0x0001
460
        mov     [rxfd.status], ax
461
        mov     ax, 0x0000
462
        mov     [rxfd.command], ax
2220 hidnplayr 463
 
2387 hidnplayr 464
        lea     eax, [rxfd.status]
465
        GetRealAddr
466
        mov     [rxfd.link], eax
2220 hidnplayr 467
 
2387 hidnplayr 468
        lea     eax, [device.rx_buffer]
469
        GetRealAddr
470
        mov     [rxfd.rx_buf_addr], eax
2220 hidnplayr 471
 
2387 hidnplayr 472
        xor     ax, ax
473
        mov     [rxfd.count], ax
2220 hidnplayr 474
 
2387 hidnplayr 475
        mov     ax, 1528
476
        mov     [rxfd.size], ax
2220 hidnplayr 477
 
478
;-------------------------------
479
; Set ptr to first command block
480
 
2387 hidnplayr 481
        set_io  reg_scb_ptr
482
        lea     eax, [rxfd]
483
        GetRealAddr
484
        out     dx, eax
2220 hidnplayr 485
 
2387 hidnplayr 486
        set_io  reg_scb_cmd
487
        mov     ax, INT_MASK + RX_START
488
        out     dx, ax
489
        call    cmd_wait
2220 hidnplayr 490
 
491
;-------------------
492
; start the receiver
493
 
2387 hidnplayr 494
        mov     [rxfd.status], 0
495
        mov     [rxfd.command], 0xc000
2220 hidnplayr 496
 
2387 hidnplayr 497
        set_io  reg_scb_ptr
498
        lea     eax, [rxfd]
499
        GetRealAddr
500
        out     dx, eax
2220 hidnplayr 501
 
2387 hidnplayr 502
        set_io  reg_scb_cmd
503
        mov     ax, INT_MASK + RX_START
504
        out     dx, ax
505
        call    cmd_wait
2220 hidnplayr 506
 
507
;-----------------
508
; set CU base to 0
509
 
2387 hidnplayr 510
        set_io  reg_scb_ptr
511
        xor     eax, eax
512
        out     dx, eax
2220 hidnplayr 513
 
2387 hidnplayr 514
        set_io  reg_scb_cmd
515
        mov     ax, INT_MASK + CU_CMD_BASE
516
        out     dx, ax
517
        call    cmd_wait
2220 hidnplayr 518
 
519
;--------------------
520
; Set TX Base address
521
 
522
; First, set up confcmd values
523
 
2387 hidnplayr 524
        mov     [txfd.command], CmdIASetup
525
        mov     [txfd.status], 0
526
        lea     eax, [confcmd]
527
        GetRealAddr
528
        mov     [txfd.link], eax
2220 hidnplayr 529
 
2387 hidnplayr 530
        mov     word [confcmd.command], Cmdsuspend + CmdConfigure
531
        mov     word [confcmd.status], 0
532
        lea     eax, [txfd]
533
        GetRealAddr
534
        mov     [confcmd.link], eax
2220 hidnplayr 535
 
2387 hidnplayr 536
        mov     byte [confcmd.data + 1], 0x88  ; fifo of 8 each
537
        mov     byte [confcmd.data + 4], 0
538
        mov     byte [confcmd.data + 5], 0x80
539
        mov     byte [confcmd.data + 15], 0x48
540
        mov     byte [confcmd.data + 19], 0x80
541
        mov     byte [confcmd.data + 21], 0x05
2220 hidnplayr 542
 
543
 
544
; CU start
545
 
546
;        lea     eax, [txfd]
547
;        GetRealAddr
2387 hidnplayr 548
        set_io  0
549
        set_io  reg_scb_ptr
550
        out     dx, eax
2220 hidnplayr 551
 
2387 hidnplayr 552
        mov     ax, INT_MASK + CU_START
553
        set_io  reg_scb_cmd
554
        out     dx, ax
555
        call    cmd_wait
2220 hidnplayr 556
 
557
; wait for thing to start
558
 
559
;  drp004:
560
;
561
;        cmp     [txfd.status], 0
562
;        jz      drp004
563
 
564
; Indicate that we have successfully reset the card
565
 
566
 
567
;;; enable interrupts
568
 
2387 hidnplayr 569
        xor     eax, eax
2220 hidnplayr 570
 
2387 hidnplayr 571
        ret
2220 hidnplayr 572
 
573
 
574
 
575
 
576
 
577
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
578
;;                                         ;;
579
;; Transmit                                ;;
580
;;                                         ;;
2313 hidnplayr 581
;; In: buffer pointer in [esp+4]           ;;
582
;;     size of buffer in [esp+8]           ;;
2220 hidnplayr 583
;;     pointer to device structure in ebx  ;;
584
;;                                         ;;
585
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
586
 
587
align 4
588
transmit:
589
 
2387 hidnplayr 590
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8]
591
        mov     eax, [esp+4]
592
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
593
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
594
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
595
        [eax+13]:2,[eax+12]:2
2220 hidnplayr 596
 
2387 hidnplayr 597
        cmp     dword [esp+8], 1500
598
        jg      .error                          ; packet is too long
599
        cmp     dword [esp+8], 60
600
        jl      .error                          ; packet is too short
2220 hidnplayr 601
 
2387 hidnplayr 602
        set_io  0
603
        in      ax, dx
604
        and     ax, 0xfc00
605
        out     dx, ax
2220 hidnplayr 606
 
2387 hidnplayr 607
        mov     [txfd.status], 0
608
        mov     [txfd.command], Cmdsuspend + CmdTx + CmdTxFlex
609
        lea     eax, [txfd]
610
        GetRealAddr
611
        mov     [txfd.link], eax
612
        mov     [txfd.count], 0x02208000
613
        lea     eax, [txfd.tx_buf_addr0]
614
        GetRealAddr
615
        mov     [txfd.tx_desc_addr], eax
2220 hidnplayr 616
 
2387 hidnplayr 617
        mov     eax, [esp+4]
618
        mov     [txfd.tx_buf_addr0], eax
619
        mov     eax, [esp+8]
620
        mov     [txfd.tx_buf_size0], eax
2220 hidnplayr 621
 
2387 hidnplayr 622
        ; Copy the buffer address and size in
623
        mov     [txfd.tx_buf_addr1], 0
624
        mov     [txfd.tx_buf_size1], 0
2220 hidnplayr 625
 
2387 hidnplayr 626
        lea     eax, [txfd]
627
        GetRealAddr
628
        set_io  reg_scb_ptr
629
        out     dx, eax
2220 hidnplayr 630
 
2387 hidnplayr 631
        mov     ax, INT_MASK + CU_START
632
        set_io  reg_scb_cmd
633
        out     dx, ax
2220 hidnplayr 634
 
2387 hidnplayr 635
        call    cmd_wait
2220 hidnplayr 636
 
2387 hidnplayr 637
        in      ax, dx
2220 hidnplayr 638
 
639
  .I8t_001:
2387 hidnplayr 640
        cmp     [txfd.status], 0
641
        je      .I8t_001
2220 hidnplayr 642
 
2387 hidnplayr 643
        in      ax, dx
2220 hidnplayr 644
 
645
  .finish:
2387 hidnplayr 646
        xor     eax, eax
647
        ret     8
2220 hidnplayr 648
 
2387 hidnplayr 649
  .error:
650
        stdcall KernelFree, [esp+4]
651
        or      eax, -1
652
        ret     8
2220 hidnplayr 653
 
654
;;;;;;;;;;;;;;;;;;;;;;;
655
;;                   ;;
656
;; Interrupt handler ;;
657
;;                   ;;
658
;;;;;;;;;;;;;;;;;;;;;;;
659
 
660
align 4
661
int_handler:
662
 
2387 hidnplayr 663
        DEBUGF  1,"IRQ %x ",eax:2                   ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO
2220 hidnplayr 664
 
665
; find pointer of device wich made IRQ occur
666
 
2387 hidnplayr 667
        mov     esi, device_list
668
        mov     ecx, [devices]
669
        test    ecx, ecx
670
        jz      .fail
2220 hidnplayr 671
.nextdevice:
2387 hidnplayr 672
        mov     ebx, dword [esi]
2220 hidnplayr 673
 
2387 hidnplayr 674
        set_io  0
2220 hidnplayr 675
  ;;      set_io  REG_ISR
676
   ;;     in      ax , dx
677
    ;;    out     dx , ax                             ; send it back to ACK
678
 
2387 hidnplayr 679
        add     esi, 4
2220 hidnplayr 680
 
2387 hidnplayr 681
        test    ax , ax
682
        jnz     .got_it
2220 hidnplayr 683
 
2387 hidnplayr 684
        dec     ecx
685
        jnz     .nextdevice
2220 hidnplayr 686
 
2387 hidnplayr 687
        ret                                         ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
2220 hidnplayr 688
 
689
  .got_it:
690
 
691
 
692
       ;;; receive
693
 
2387 hidnplayr 694
        cmp     [rxfd.status], 0
695
        je      .nodata
2220 hidnplayr 696
 
2387 hidnplayr 697
        mov     [rxfd.status], 0
698
        mov     [rxfd.command], 0xc000
2220 hidnplayr 699
 
2387 hidnplayr 700
        set_io  reg_scb_ptr
701
        lea     eax, [rxfd.status]
702
        GetRealAddr
703
        out     dx, eax
2220 hidnplayr 704
 
2387 hidnplayr 705
        set_io  reg_scb_cmd
706
        mov     ax, INT_MASK + RX_START
707
        out     dx, ax
2220 hidnplayr 708
 
2387 hidnplayr 709
        call    cmd_wait
2220 hidnplayr 710
 
2387 hidnplayr 711
        movzx   ecx, [rxfd.count]
712
        and     ecx, 0x3fff
2220 hidnplayr 713
 
2387 hidnplayr 714
        stdcall KernelAlloc, ecx        ; Allocate a buffer to put packet into
715
        push    ecx
716
        push    eax
2220 hidnplayr 717
 
2387 hidnplayr 718
        lea     esi, [device.rx_buffer]
2220 hidnplayr 719
 
720
  .copy:
2387 hidnplayr 721
        shr     ecx, 1
722
        jnc     .nb
723
        movsb
2220 hidnplayr 724
  .nb:
2387 hidnplayr 725
        shr     ecx, 1
726
        jnc     .nw
727
        movsw
2220 hidnplayr 728
  .nw:
2387 hidnplayr 729
        jz      .nd
730
        rep     movsd
2220 hidnplayr 731
  .nd:
732
 
2387 hidnplayr 733
        jmp     EthReceiver                         ; Send it to kernel
2220 hidnplayr 734
 
735
  .nodata:
736
  .fail:
737
 
2387 hidnplayr 738
        ret
2220 hidnplayr 739
 
740
 
741
 
742
 
743
align 4
744
cmd_wait:
745
 
2387 hidnplayr 746
        in      al, dx
747
        test    al, al
748
        jnz     cmd_wait
2220 hidnplayr 749
 
2387 hidnplayr 750
        ret
2220 hidnplayr 751
 
752
 
753
 
754
 
755
 
756
 
757
align 4
2387 hidnplayr 758
ee_read:        ; esi = address to read
2220 hidnplayr 759
 
2387 hidnplayr 760
        set_io  0
761
        set_io  reg_eeprom
2220 hidnplayr 762
 
763
;-----------------------------------------------------
764
; Prepend start bit + read opcode to the address field
765
; and shift it to the very left bits of esi
766
 
2387 hidnplayr 767
        mov     ecx, 32
768
        sub     ecx, [device.ee_bus_width]
769
        shl     esi, cl
770
        or      esi, EE_READ shl 28
2220 hidnplayr 771
 
2387 hidnplayr 772
        mov     ecx, [device.ee_bus_width]
773
        add     ecx, 3
2220 hidnplayr 774
 
775
;-----------------------
776
; Write this to the chip
777
 
778
  .loop:
2387 hidnplayr 779
        mov     eax, EE_CS
780
        shl     esi, 1
781
        jnc     @f
782
        or      eax, EE_DI
2220 hidnplayr 783
       @@:
2387 hidnplayr 784
        out     dx , eax
785
        delay
2220 hidnplayr 786
 
2387 hidnplayr 787
        or      eax, EE_SK
788
        out     dx , eax
789
        delay
2220 hidnplayr 790
 
2387 hidnplayr 791
        loop    .loop
2220 hidnplayr 792
 
793
;------------------------------
794
; Now read the data from eeprom
795
 
2387 hidnplayr 796
        xor     esi, esi
797
        mov     ecx, 16
2220 hidnplayr 798
 
799
  .loop2:
2387 hidnplayr 800
        mov     eax, EE_CS + EE_SK
801
        out     dx , eax
802
        delay
2220 hidnplayr 803
 
2387 hidnplayr 804
        in      eax, dx
805
        test    eax, EE_DO
806
        jz      @f
807
        inc     esi
2220 hidnplayr 808
       @@:
2387 hidnplayr 809
        shl     esi, 1
2220 hidnplayr 810
 
2387 hidnplayr 811
        mov     eax, EE_CS
812
        out     dx , eax
813
        delay
2220 hidnplayr 814
 
2387 hidnplayr 815
        loop    .loop2
2220 hidnplayr 816
 
817
;-----------------------
818
; de-activate the eeprom
819
 
2387 hidnplayr 820
        xor     eax, eax
821
        out     dx, eax
2220 hidnplayr 822
 
823
 
2387 hidnplayr 824
        DEBUGF  1,"data=%x\n", esi
825
        ret
2220 hidnplayr 826
 
827
 
828
 
829
align 4
2387 hidnplayr 830
ee_write:       ; esi = address to write to, di = data
2220 hidnplayr 831
 
2387 hidnplayr 832
        set_io  0
833
        set_io  reg_eeprom
2220 hidnplayr 834
 
835
;-----------------------------------------------------
836
; Prepend start bit + write opcode to the address field
837
; and shift it to the very left bits of esi
838
 
2387 hidnplayr 839
        mov     ecx, 32
840
        sub     ecx, [device.ee_bus_width]
841
        shl     esi, cl
842
        or      esi, EE_WRITE shl 28
2220 hidnplayr 843
 
2387 hidnplayr 844
        mov     ecx, [device.ee_bus_width]
845
        add     ecx, 3
2220 hidnplayr 846
 
847
;-----------------------
848
; Write this to the chip
849
 
850
  .loop:
2387 hidnplayr 851
        mov     eax, EE_CS
852
        shl     esi, 1
853
        jnc     @f
854
        or      eax, EE_DI
2220 hidnplayr 855
       @@:
2387 hidnplayr 856
        out     dx , eax
857
        delay
2220 hidnplayr 858
 
2387 hidnplayr 859
        or      eax, EE_SK
860
        out     dx , eax
861
        delay
2220 hidnplayr 862
 
2387 hidnplayr 863
        loop    .loop
2220 hidnplayr 864
 
865
;-----------------------------
866
; Now write the data to eeprom
867
 
2387 hidnplayr 868
        mov     ecx, 16
2220 hidnplayr 869
 
870
  .loop2:
2387 hidnplayr 871
        mov     eax, EE_CS
872
        shl     di , 1
873
        jnc     @f
874
        or      eax, EE_DI
2220 hidnplayr 875
       @@:
2387 hidnplayr 876
        out     dx , eax
877
        delay
2220 hidnplayr 878
 
2387 hidnplayr 879
        or      eax, EE_SK
880
        out     dx , eax
881
        delay
2220 hidnplayr 882
 
2387 hidnplayr 883
        loop    .loop2
2220 hidnplayr 884
 
885
;-----------------------
886
; de-activate the eeprom
887
 
2387 hidnplayr 888
        xor     eax, eax
889
        out     dx, eax
2220 hidnplayr 890
 
891
 
2387 hidnplayr 892
        ret
2220 hidnplayr 893
 
894
 
895
 
896
align 4
897
ee_get_width:
898
 
2387 hidnplayr 899
        set_io  0
900
        set_io  reg_eeprom
2220 hidnplayr 901
 
2387 hidnplayr 902
        mov     esi, EE_READ shl 28
903
        xor     ecx, ecx
2220 hidnplayr 904
 
905
  .loop:
2387 hidnplayr 906
        mov     eax, EE_CS
907
        out     dx , eax
908
        delay
2220 hidnplayr 909
 
2387 hidnplayr 910
        or      eax, EE_SK
911
        out     dx , eax
912
        delay
2220 hidnplayr 913
 
2387 hidnplayr 914
        inc     ecx
2220 hidnplayr 915
 
2387 hidnplayr 916
        in      eax, dx
917
        test    eax, EE_DO
918
        jnz     .loop
2220 hidnplayr 919
 
2387 hidnplayr 920
        mov     [device.ee_bus_width], ecx
2220 hidnplayr 921
 
922
;------------------------------
923
; Now read the data from eeprom
924
 
2387 hidnplayr 925
        mov     ecx, 16
2220 hidnplayr 926
  .loop2:
2387 hidnplayr 927
        mov     eax, EE_CS + EE_SK
928
        out     dx , eax
929
        delay
2220 hidnplayr 930
 
2387 hidnplayr 931
        mov     eax, EE_CS
932
        out     dx , eax
933
        delay
934
        loop    .loop2
2220 hidnplayr 935
 
936
;-----------------------
937
; de-activate the eeprom
938
 
2387 hidnplayr 939
        xor     eax, eax
940
        out     dx, eax
2220 hidnplayr 941
 
2387 hidnplayr 942
        ret
2220 hidnplayr 943
 
944
 
945
 
946
; cx = phy addr
947
; dx = phy reg addr
948
 
949
; ax = data
950
 
951
align 4
952
mdio_read:
953
 
2387 hidnplayr 954
        shl     ecx, 21                 ; PHY addr
955
        shl     edx, 16                 ; PHY reg addr
2220 hidnplayr 956
 
2387 hidnplayr 957
        mov     eax, ecx
958
        or      eax, edx
959
        or      eax, 10b shl 26         ; read opcode
2220 hidnplayr 960
 
2387 hidnplayr 961
        set_io  0
962
        set_io  reg_mdi_ctrl
963
        out     dx, eax
2220 hidnplayr 964
 
965
  .wait:
2387 hidnplayr 966
        delay
967
        in      eax, dx
968
        test    eax, 1 shl 28           ; ready bit
969
        jz      .wait
2220 hidnplayr 970
 
2387 hidnplayr 971
        ret
2220 hidnplayr 972
 
973
; ax = data
974
; cx = phy addr
975
; dx = phy reg addr
976
 
977
; ax = data
978
 
979
align 4
980
mdio_write:
981
 
2387 hidnplayr 982
        and     eax, 0xffff
2220 hidnplayr 983
 
2387 hidnplayr 984
        shl     ecx, 21                 ; PHY addr
985
        shl     edx, 16                 ; PHY reg addr
2220 hidnplayr 986
 
2387 hidnplayr 987
        or      eax, ecx
988
        or      eax, edx
989
        or      eax, 01b shl 26         ; write opcode
2220 hidnplayr 990
 
2387 hidnplayr 991
        set_io  0
992
        set_io  reg_mdi_ctrl
993
        out     dx, eax
2220 hidnplayr 994
 
995
  .wait:
2387 hidnplayr 996
        delay
997
        in      eax, dx
998
        test    eax, 1 shl 28           ; ready bit
999
        jz      .wait
2220 hidnplayr 1000
 
2387 hidnplayr 1001
        ret
2220 hidnplayr 1002
 
1003
 
1004
 
1005
align 4
1006
MAC_read_eeprom:
1007
 
1008
;;;;
1009
 
2387 hidnplayr 1010
        ret
2220 hidnplayr 1011
 
1012
 
1013
align 4
1014
MAC_write:
1015
 
1016
;;;;
1017
 
2387 hidnplayr 1018
        ret
2220 hidnplayr 1019
 
1020
 
1021
 
1022
 
1023
; End of code
1024
 
2387 hidnplayr 1025
align 4                                         ; Place all initialised data here
2220 hidnplayr 1026
 
2387 hidnplayr 1027
devices       dd 0                              ; number of currently running devices
2220 hidnplayr 1028
version       dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
2387 hidnplayr 1029
my_service    db 'i8255x',0                     ; max 16 chars include zero
2220 hidnplayr 1030
devicename    db 'Intel Etherexpress pro/100',0
1031
 
1032
 
1033
device_id_list:
1034
 
2387 hidnplayr 1035
        dw 0x1029
1036
        dw 0x1030
1037
        dw 0x1031
1038
        dw 0x1032
1039
        dw 0x1033
1040
        dw 0x1034
1041
        dw 0x1038
1042
        dw 0x1039
1043
        dw 0x103A
1044
        dw 0x103B
1045
        dw 0x103C
1046
        dw 0x103D
1047
        dw 0x103E
1048
        dw 0x1050
1049
        dw 0x1051
1050
        dw 0x1052
1051
        dw 0x1053
1052
        dw 0x1054
1053
        dw 0x1055
1054
        dw 0x1056
1055
        dw 0x1057
1056
        dw 0x1059
1057
        dw 0x1064
1058
        dw 0x1065
1059
        dw 0x1066
1060
        dw 0x1067
1061
        dw 0x1068
1062
        dw 0x1069
1063
        dw 0x106A
1064
        dw 0x106B
1065
        dw 0x1091
1066
        dw 0x1092
1067
        dw 0x1093
1068
        dw 0x1094
1069
        dw 0x1095
1070
        dw 0x10fe
1071
        dw 0x1209
1072
        dw 0x1229
1073
        dw 0x2449
1074
        dw 0x2459
1075
        dw 0x245D
1076
        dw 0x27DC
2220 hidnplayr 1077
 
1078
DEVICE_IDs = ($ - device_id_list) / 2
1079
 
1080
mac_82557_D100_A  = 0
1081
mac_82557_D100_B  = 1
1082
mac_82557_D100_C  = 2
1083
mac_82558_D101_A4 = 4
1084
mac_82558_D101_B0 = 5
1085
mac_82559_D101M   = 8
1086
mac_82559_D101S   = 9
2387 hidnplayr 1087
mac_82550_D102    = 12
2220 hidnplayr 1088
mac_82550_D102_C  = 13
2387 hidnplayr 1089
mac_82551_E       = 14
1090
mac_82551_F       = 15
1091
mac_82551_10      = 16
1092
mac_unknown       = 0xFF
2220 hidnplayr 1093
 
1094
phy_100a     = 0x000003E0
1095
phy_100c     = 0x035002A8
1096
phy_82555_tx = 0x015002A8
1097
phy_nsc_tx   = 0x5C002000
1098
phy_82562_et = 0x033002A8
1099
phy_82562_em = 0x032002A8
1100
phy_82562_ek = 0x031002A8
1101
phy_82562_eh = 0x017002A8
1102
phy_82552_v  = 0xd061004d
1103
phy_unknown  = 0xFFFFFFFF
1104
 
1105
 
2387 hidnplayr 1106
include_debug_strings                           ; All data wich FDO uses will be included here
2220 hidnplayr 1107
 
1108
section '.data' data readable writable align 16 ; place all uninitialized data place here
1109
 
2387 hidnplayr 1110
device_list   rd MAX_DEVICES                    ; This list contains all pointers to device structures the driver is handling
2220 hidnplayr 1111