Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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