Subversion Repositories Kolibri OS

Rev

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

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