Subversion Repositories Kolibri OS

Rev

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

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