Subversion Repositories Kolibri OS

Rev

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

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