Subversion Repositories Kolibri OS

Rev

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

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