Subversion Repositories Kolibri OS

Rev

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

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