Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2455 mario79 3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved.    ;;
2288 clevermous 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;                                                                 ;;
7
;;  I8255X.INC                                                     ;;
8
;;                                                                 ;;
9
;;  Ethernet driver for Menuet OS                                  ;;
10
;;                                                                 ;;
11
;;  Version 0.3  11 August 2003                                    ;;
12
;;                                                                 ;;
13
;;  This driver is based on the eepro100 driver from               ;;
14
;;  the etherboot 5.0.6 project. The copyright statement is        ;;
15
;;                                                                 ;;
16
;;          GNU GENERAL PUBLIC LICENSE                             ;;
17
;;             Version 2, June 1991                                ;;
18
;;                                                                 ;;
19
;;  remaining parts Copyright 2002 Mike Hibbett,                   ;;
20
;;   mikeh@oceanfree.net                                           ;;
21
;;                                                                 ;;
22
;;  See file COPYING for details                                   ;;
23
;;                                                                 ;;
24
;;                                                                 ;;
25
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26
 
27
$Revision: 2455 $
28
 
29
 
30
;********************************************************************
31
;   Interface
32
;      I8255x_reset
33
;      I8255x_probe
34
;      I8255x_poll
35
;      I8255x_transmit
36
;
37
;      These functions are referenced in ethernet.inc
38
;
39
;********************************************************************
40
 
41
 
42
rxfd_status             equ  eth_data_start
43
rxfd_command            equ  eth_data_start + 2
44
rxfd_link               equ  eth_data_start + 4
45
rxfd_rx_buf_addr        equ  eth_data_start + 8
46
rxfd_count              equ  eth_data_start + 12
47
rxfd_size               equ  eth_data_start + 14
48
rxfd_packet             equ  eth_data_start + 16
49
 
50
 
51
 
52
uglobal
53
eeprom_data:
54
              times 16  dd 0
55
 
56
align 4
57
 
58
lstats:
59
tx_good_frames:
60
                dd 0
61
tx_coll16_errs:
62
                 dd 0
63
tx_late_colls:
64
               dd 0
65
tx_underruns:
66
              dd 0
67
tx_lost_carrier:
68
                 dd 0
69
tx_deferred:
70
             dd 0
71
tx_one_colls:
72
              dd 0
73
tx_multi_colls:
74
                dd 0
75
tx_total_colls:
76
                dd 0
77
rx_good_frames:
78
                dd 0
79
rx_crc_errs:
80
             dd 0
81
rx_align_errs:
82
               dd 0
83
rx_resource_errs:
84
                  dd 0
85
rx_overrun_errs:
86
                 dd 0
87
rx_colls_errs:
88
               dd 0
89
rx_runt_errs:
90
              dd 0
91
done_marker:
92
             dd 0
93
 
94
align 4
95
 
96
confcmd:
97
confcmd_status:
98
                        dw    0
99
confcmd_command:
100
                        dw    0
101
confcmd_link:
102
                        dd    0
103
endg
104
 
105
iglobal
106
confcmd_data:
107
                        db    22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1
108
                        db    0, 0x2e, 0, 0x60, 0, 0xf2, 0x48, 0, 0x40, 0xf2
109
                        db    0x80, 0x3f, 0x05
110
endg
111
 
112
uglobal
113
align 4
114
 
115
txfd:
116
txfd_status:
117
                        dw   0
118
txfd_command:
119
                        dw   0
120
txfd_link:
121
                        dd   0
122
txfd_tx_desc_addr:
123
                        dd   0
124
txfd_count:
125
                        dd   0
126
txfd_tx_buf_addr0:
127
                        dd   0
128
txfd_tx_buf_size0:
129
                        dd   0
130
txfd_tx_buf_addr1:
131
                        dd   0
132
txfd_tx_buf_size1:
133
                        dd   0
134
 
135
align 4
136
 
137
hdr:
138
hdr_dst_addr:
139
                        times 6 db 0
140
hdr_src_addr:
141
                        times 6 db 0
142
hdr_type:
143
                        dw   0
144
endg
145
 
146
 
147
;***************************************************************************
148
;   Function
149
;      wait_for_cmd_done
150
;
151
;   Description
152
;       waits for the hardware to complete a command
153
;       port address in edx
154
;
155
;       al destroyed
156
;***************************************************************************
157
wait_for_cmd_done:
158
        in      al, dx
159
        cmp     al, 0
160
        jne     wait_for_cmd_done
161
        ret
162
 
163
 
164
 
165
;***************************************************************************
166
;   Function
167
;      mdio_read
168
;
169
;   Description
170
;       This probably reads a register in the "physical media interface chip"
171
;         Phy_id in ebx
172
;         location in ecx
173
;
174
;       Data returned in eax
175
;
176
;***************************************************************************
177
mdio_read:
178
        mov     edx, [io_addr]
179
        add     edx, 16     ; SCBCtrlMDI
180
 
181
        mov     eax, 0x08000000
182
        shl     ecx, 16
183
        or      eax, ecx
184
        shl     ebx, 21
185
        or      eax, ebx
186
 
187
        out     dx, eax
188
 
189
mrlp:
190
        call    delay_us
191
        in      eax, dx
192
        mov     ecx, eax
193
        and     ecx, 0x10000000
194
        jz      mrlp
195
 
196
        and     eax, 0xffff
197
        ret
198
 
199
 
200
 
201
;***************************************************************************
202
;   Function
203
;      mdio_write
204
;
205
;   Description
206
;       This probably writes a register in the "physical media interface chip"
207
;         Phy_id in ebx
208
;         location in ecx
209
;         data in edx
210
;       Data returned in eax
211
;
212
;***************************************************************************
213
mdio_write:
214
        mov     eax, 0x04000000
215
        shl     ecx, 16
216
        or      eax, ecx
217
        shl     ebx, 21
218
        or      eax, ebx
219
        or      eax, edx
220
 
221
        mov     edx, [io_addr]
222
        add     edx, 16     ; SCBCtrlMDI
223
        out     dx, eax
224
 
225
mwlp:
226
        call    delay_us
227
        in      eax, dx
228
        mov     ecx, eax
229
        and     ecx, 0x10000000
230
        jz      mwlp
231
 
232
        and     eax, 0xffff
233
        ret
234
 
235
 
236
 
237
;/***********************************************************************/
238
;/*                       I82557 related defines                        */
239
;/***********************************************************************/
240
 
241
; Serial EEPROM section.
242
;   A "bit" grungy, but we work our way through bit-by-bit :->.
243
;  EEPROM_Ctrl bits.
244
EE_SHIFT_CLK    equ   0x01    ; EEPROM shift clock.
245
EE_CS           equ   0x02    ; EEPROM chip select.
246
EE_DATA_WRITE   equ   0x04    ; EEPROM chip data in.
247
EE_DATA_READ    equ   0x08    ; EEPROM chip data out.
248
EE_WRITE_0      equ   0x4802
249
EE_WRITE_1      equ   0x4806
250
EE_ENB          equ   0x4802
251
 
252
 
253
; The EEPROM commands include the alway-set leading bit.
254
EE_READ_CMD     equ   6
255
 
256
; The SCB accepts the following controls for the Tx and Rx units:
257
CU_START       equ   0x0010
258
CU_RESUME      equ   0x0020
259
CU_STATSADDR   equ   0x0040
260
CU_SHOWSTATS   equ   0x0050   ; Dump statistics counters.
261
CU_CMD_BASE    equ   0x0060   ; Base address to add to add CU commands.
262
CU_DUMPSTATS   equ   0x0070   ; Dump then reset stats counters.
263
 
264
RX_START       equ   0x0001
265
RX_RESUME      equ   0x0002
266
RX_ABORT       equ   0x0004
267
RX_ADDR_LOAD   equ   0x0006
268
RX_RESUMENR    equ   0x0007
269
INT_MASK       equ   0x0100
270
DRVR_INT       equ   0x0200   ; Driver generated interrupt.
271
 
272
 
273
;***************************************************************************
274
;   Function
275
;      do_eeprom_cmd
276
;
277
;   Description
278
;       writes a cmd to the ethernet cards eeprom, by bit bashing
279
;       cmd in ebx
280
;       cmd length in ecx
281
;       return in eax
282
;***************************************************************************
283
do_eeprom_cmd:
284
        mov     edx, [io_addr]; We only require the value in dx
285
        add     dx, 14        ; the value SCBeeprom
286
 
287
        mov     ax, EE_ENB
288
        out     dx, ax
289
        call    delay_us
290
 
291
        mov     ax, 0x4803    ; EE_ENB | EE_SHIFT_CLK
292
        out     dx, ax
293
        call    delay_us
294
 
295
    ; dx holds ee_addr
296
    ; ecx holds count
297
    ; eax holds cmd
298
        xor     edi, edi      ; this will be the receive data
299
 
300
dec_001:
301
        mov     esi, 1
302
 
303
        dec     ecx
304
        shl     esi, cl
305
        inc     ecx
306
        and     esi, ebx
307
        mov     eax, EE_WRITE_0; I am assuming this doesnt affect the flags..
308
        cmp     esi, 0
309
        jz      dec_002
310
        mov     eax, EE_WRITE_1
311
 
312
dec_002:
313
        out     dx, ax
314
        call    delay_us
315
 
316
        or      ax, EE_SHIFT_CLK
317
        out     dx, ax
318
        call    delay_us
319
 
320
        shl     edi, 1
321
 
322
        in      ax, dx
323
        and     ax, EE_DATA_READ
324
        cmp     ax, 0
325
        jz      dec_003
326
        inc     edi
327
 
328
dec_003:
329
        loop    dec_001
330
 
331
        mov     ax, EE_ENB
332
        out     dx, ax
333
        call    delay_us
334
 
335
        mov     ax, 0x4800
336
        out     dx, ax
337
        call    delay_us
338
 
339
        mov     eax, edi
340
 
341
        ret
342
 
343
 
344
;***************************************************************************
345
;   Function
346
;      I8255x_probe
347
;   Description
348
;      Searches for an ethernet card, enables it and clears the rx buffer
349
;      If a card was found, it enables the ethernet -> TCPIP link
350
;
351
;***************************************************************************
352
I8255x_probe:
353
   DEBUGF 1," K : Probing i8255x device \n"
354
        mov     eax, [io_addr]
355
 
356
        mov     ebx, [pci_bus]
357
        mov     ecx, [pci_dev]
358
        mov     edx, 0x04  ; PCI_COMMAND
359
        call    pcibios_read_config_word
360
 
361
        or      ax, 0x05
362
        mov     ebx, [pci_bus]
363
        mov     ecx, [pci_dev]
364
        mov     edx, 0x04  ; PCI_COMMAND
365
        call    pcibios_write_config_word
366
 
367
        mov     ebx, 0x6000000
368
        mov     ecx, 27
369
        call    do_eeprom_cmd
370
        and     eax, 0xffe0000
371
        cmp     eax, 0xffe0000
372
        je      bige
373
 
374
        mov     ebx, 0x1800000
375
        mov     ecx, 0x40
376
        jmp     doread
377
 
378
bige:
379
        mov     ebx, 0x6000000
380
        mov     ecx, 0x100
381
 
382
doread:
383
   ; do-eeprom-cmd will destroy all registers
384
   ; we have eesize in ecx
385
   ; read_cmd in ebx
386
 
387
   ; Ignore full eeprom - just load the mac address
388
        mov     ecx, 0
389
 
390
drlp:
391
        push    ecx  ; save count
392
        push    ebx
393
        mov     eax, ecx
394
        shl     eax, 16
395
        or      ebx, eax
396
        mov     ecx, 27
397
        call    do_eeprom_cmd
398
 
399
        pop     ebx
400
        pop     ecx
401
 
402
        mov     edx, ecx
403
        shl     edx, 2
404
        mov     esi, eeprom_data
405
        add     esi, edx
406
        mov     [esi], eax
407
 
408
        inc     ecx
409
        cmp     ecx, 16
410
        jne     drlp
411
 
412
   ; OK, we have the MAC address.
413
   ; Now reset the card
414
 
415
        mov     edx, [io_addr]
416
        add     dx, 8     ; SCBPort
417
        xor     eax, eax  ; The reset cmd == 0
418
        out     dx, eax
419
 
420
        mov     esi, 10
421
        call    delay_ms  ; Give the card time to warm up.
422
 
423
        mov     eax, lstats
424
        mov     edx, [io_addr]
425
        add     edx, 4        ; SCBPointer
426
        out     dx, eax
427
 
428
        mov     eax, 0x0140     ; INT_MASK | CU_STATSADDR
429
        mov     edx, [io_addr]
430
        add     edx, 2        ; SCBCmd
431
        out     dx, ax
432
 
433
        call    wait_for_cmd_done
434
 
435
        mov     eax, 0
436
        mov     edx, [io_addr]
437
        add     edx, 4        ; SCBPointer
438
        out     dx, eax
439
 
440
        mov     eax, 0x0106     ; INT_MASK | RX_ADDR_LOAD
441
        mov     edx, [io_addr]
442
        add     edx, 2        ; SCBCmd
443
        out     dx, ax
444
 
445
        call    wait_for_cmd_done
446
 
447
   ; build rxrd structure
448
        mov     ax, 0x0001
449
        mov     [rxfd_status], ax
450
        mov     ax, 0x0000
451
        mov     [rxfd_command], ax
452
 
453
        mov     eax, rxfd_status
454
        sub     eax, OS_BASE
455
        mov     [rxfd_link], eax
456
 
457
        mov     eax, Ether_buffer
458
        sub     eax, OS_BASE
459
        mov     [rxfd_rx_buf_addr], eax
460
 
461
        mov     ax, 0
462
        mov     [rxfd_count], ax
463
 
464
        mov     ax, 1528
465
        mov     [rxfd_size], ax
466
 
467
        mov     edx, [io_addr]
468
        add     edx, 4       ; SCBPointer
469
 
470
        mov     eax, rxfd_status
471
        sub     eax, OS_BASE
472
        out     dx, eax
473
 
474
        mov     edx, [io_addr]
475
        add     edx, 2       ; SCBCmd
476
 
477
        mov     ax, 0x0101     ; INT_MASK | RX_START
478
        out     dx, ax
479
 
480
        call    wait_for_cmd_done
481
 
482
   ; start the reciver
483
 
484
        mov     ax, 0
485
        mov     [rxfd_status], ax
486
 
487
        mov     ax, 0xc000
488
        mov     [rxfd_command], ax
489
 
490
        mov     edx, [io_addr]
491
        add     edx, 4       ; SCBPointer
492
 
493
        mov     eax, rxfd_status
494
        sub     eax, OS_BASE
495
        out     dx, eax
496
 
497
        mov     edx, [io_addr]
498
        add     edx, 2       ; SCBCmd
499
 
500
        mov     ax, 0x0101     ; INT_MASK | RX_START
501
        out     dx, ax
502
 
503
   ; Init TX Stuff
504
 
505
        mov     edx, [io_addr]
506
        add     edx, 4       ; SCBPointer
507
 
508
        mov     eax, 0
509
        out     dx, eax
510
 
511
        mov     edx, [io_addr]
512
        add     edx, 2       ; SCBCmd
513
 
514
        mov     ax, 0x0160     ; INT_MASK | CU_CMD_BASE
515
        out     dx, ax
516
 
517
        call    wait_for_cmd_done
518
 
519
   ; Set TX Base address
520
 
521
   ; First, set up confcmd values
522
 
523
        mov     ax, 2
524
        mov     [confcmd_command], ax
525
        mov     eax, txfd
526
        sub     eax, OS_BASE
527
        mov     [confcmd_link], eax
528
 
529
        mov     ax, 1
530
        mov     [txfd_command], ax     ; CmdIASetup
531
 
532
        mov     ax, 0
533
        mov     [txfd_status], ax
534
 
535
        mov     eax, confcmd
536
        sub     eax, OS_BASE
537
        mov     [txfd_link], eax
538
 
539
 
540
 
541
   ; ETH_ALEN is 6 bytes
542
 
543
        mov     esi, eeprom_data
544
        mov     edi, node_addr
545
        mov     ecx, 3
546
drp000:
547
        mov     eax, [esi]
548
        mov     [edi], al
549
        shr     eax, 8
550
        inc     edi
551
        mov     [edi], al
552
        inc     edi
553
        add     esi, 4
554
        loop    drp000
555
 
556
   ; Hard code your MAC address into node_addr at this point,
557
   ; If you cannot read the MAC address from the eeprom in the previous step.
558
   ; You also have to write the mac address into txfd_tx_desc_addr, rather
559
   ; than taking data from eeprom_data
560
 
561
        mov     esi, eeprom_data
562
        mov     edi, txfd_tx_desc_addr
563
        mov     ecx, 3
564
drp001:
565
        mov     eax, [esi]
566
        mov     [edi], al
567
        shr     eax, 8
568
        inc     edi
569
        mov     [edi], al
570
        inc     edi
571
        add     esi, 4
572
        loop    drp001
573
 
574
 
575
        mov     esi, eeprom_data + (6 * 4)
576
        mov     eax, [esi]
577
        shr     eax, 8
578
        and     eax, 0x3f
579
        cmp     eax, 4        ; DP83840
580
        je      drp002
581
        cmp     eax, 10        ; DP83840A
582
        je      drp002
583
        jmp     drp003
584
 
585
drp002:
586
        mov     ebx, [esi]
587
        and     ebx, 0x1f
588
        push    ebx
589
        mov     ecx, 23
590
        call    mdio_read
591
        pop     ebx
592
        or      eax, 0x0422
593
        mov     ecx, 23
594
        mov     edx, eax
595
        call    mdio_write
596
 
597
drp003:
598
        mov     ax, 0x4002     ; Cmdsuspend | CmdConfigure
599
        mov     [confcmd_command], ax
600
        mov     ax, 0
601
        mov     [confcmd_status], ax
602
        mov     eax, txfd
603
        mov     [confcmd_link], eax
604
        mov     ebx, confcmd_data
605
        mov     al, 0x88     ; fifo of 8 each
606
        mov     [ebx + 1], al
607
        mov     al, 0
608
        mov     [ebx + 4], al
609
        mov     al, 0x80
610
        mov     [ebx + 5], al
611
        mov     al, 0x48
612
        mov     [ebx + 15], al
613
        mov     al, 0x80
614
        mov     [ebx + 19], al
615
        mov     al, 0x05
616
        mov     [ebx + 21], al
617
 
618
        mov     eax, txfd
619
        sub     eax, OS_BASE
620
        mov     edx, [io_addr]
621
        add     edx, 4        ; SCBPointer
622
        out     dx, eax
623
 
624
        mov     eax, 0x0110     ; INT_MASK | CU_START
625
        mov     edx, [io_addr]
626
        add     edx, 2        ; SCBCmd
627
        out     dx, ax
628
 
629
        call    wait_for_cmd_done
630
        jmp     skip
631
 
632
   ; wait for thing to start
633
drp004:
634
        mov     ax, [txfd_status]
635
        cmp     ax, 0
636
        je      drp004
637
 
638
skip:
639
   ; Indicate that we have successfully reset the card
640
        mov     eax, [pci_data]
641
        mov     [eth_status], eax
642
 
643
I8255x_exit:
644
        ret
645
 
646
 
647
 
648
;***************************************************************************
649
;   Function
650
;      I8255x_reset
651
;   Description
652
;      Place the chip (ie, the ethernet card) into a virgin state
653
;      No inputs
654
;      All registers destroyed
655
;
656
;***************************************************************************
657
I8255x_reset:
658
        ret
659
 
660
 
661
 
662
;***************************************************************************
663
; Function
664
;    I8255x_poll
665
;
666
; Description
667
;    Polls the ethernet card for a received packet
668
;    Received data, if any, ends up in Ether_buffer
669
;
670
;***************************************************************************
671
I8255x_poll:
672
        mov     ax, 0  ; assume no data
673
        mov     [eth_rx_data_len], ax
674
 
675
        mov     ax, [rxfd_status]
676
        cmp     ax, 0
677
        je      i8p_exit
678
 
679
        mov     ax, 0
680
        mov     [rxfd_status], ax
681
 
682
        mov     ax, 0xc000
683
        mov     [rxfd_command], ax
684
 
685
        mov     edx, [io_addr]
686
        add     edx, 4       ; SCBPointer
687
 
688
        mov     eax, rxfd_status
689
        sub     eax, OS_BASE
690
        out     dx, eax
691
 
692
        mov     edx, [io_addr]
693
        add     edx, 2       ; SCBCmd
694
 
695
        mov     ax, 0x0101     ; INT_MASK | RX_START
696
        out     dx, ax
697
 
698
        call    wait_for_cmd_done
699
 
700
        mov     esi, rxfd_packet
701
        mov     edi, Ether_buffer
702
        mov     ecx, 1518
703
        cld
704
        rep movsb
705
 
706
        mov     ax, [rxfd_count]
707
        and     ax, 0x3fff
708
        mov     [eth_rx_data_len], ax
709
 
710
i8p_exit:
711
        ret
712
 
713
 
714
 
715
;***************************************************************************
716
;   Function
717
;      I8255x_transmit
718
;
719
;   Description
720
;       Transmits a packet of data via the ethernet card
721
;          Pointer to 48 bit destination address in edi
722
;         Type of packet in bx
723
;         size of packet in ecx
724
;         pointer to packet data in esi
725
;
726
;***************************************************************************
727
I8255x_transmit:
728
 
729
        mov     [hdr_type], bx
730
 
731
        mov     eax, [edi]
732
        mov     [hdr_dst_addr], eax
733
        mov     ax, [edi+4]
734
        mov     [hdr_dst_addr+4], ax
735
 
736
        mov     eax, [node_addr]
737
        mov     [hdr_src_addr], eax
738
        mov     ax, [node_addr+4]
739
        mov     [hdr_src_addr+4], ax
740
 
741
        mov     edx, [io_addr]
742
        in      ax, dx
743
        and     ax, 0xfc00
744
        out     dx, ax
745
 
746
        xor     ax, ax
747
        mov     [txfd_status], ax
748
        mov     ax, 0x400C        ; Cmdsuspend | CmdTx | CmdTxFlex
749
        mov     [txfd_command], ax
750
        mov     eax, txfd
751
        mov     [txfd_link], eax
752
        mov     eax, 0x02208000
753
        mov     [txfd_count], eax
754
        mov     eax, txfd_tx_buf_addr0
755
        sub     eax, OS_BASE
756
        mov     [txfd_tx_desc_addr], eax
757
        mov     eax, hdr
758
        sub     eax, OS_BASE
759
        mov     [txfd_tx_buf_addr0], eax
760
        mov     eax, 14; sizeof hdr
761
        mov     [txfd_tx_buf_size0], eax
762
 
763
   ; Copy the buffer address and size in
764
        mov     eax, esi
765
        sub     eax, OS_BASE
766
        mov     [txfd_tx_buf_addr1], eax
767
        mov     eax, ecx
768
        mov     [txfd_tx_buf_size1], eax
769
 
770
        mov     eax, txfd
771
        sub     eax, OS_BASE
772
        mov     edx, [io_addr]
773
        add     edx, 4        ; SCBPointer
774
        out     dx, eax
775
 
776
        mov     ax, 0x0110     ; INT_MASK | CU_START
777
        mov     edx, [io_addr]
778
        add     edx, 2        ; SCBCmd
779
        out     dx, ax
780
 
781
        call    wait_for_cmd_done
782
 
783
        mov     edx, [io_addr]
784
        in      ax, dx
785
 
786
I8t_001:
787
        mov     ax, [txfd_status]
788
        cmp     ax, 0
789
        je      I8t_001
790
 
791
        mov     edx, [io_addr]
792
        in      ax, dx
793
 
794
        ret