Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1561 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3155 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved.    ;;
1561 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  MTD80x driver for KolibriOS                                    ;;
7
;;                                                                 ;;
8
;;  Based on mtd80x.c from the etherboot project                   ;;
9
;;                                                                 ;;
10
;;  Written by hidnplayr@kolibrios.org                             ;;
11
;;                                                                 ;;
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
13
;;             Version 2, June 1991                                ;;
14
;;                                                                 ;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16
 
17
format MS COFF
18
 
2852 hidnplayr 19
        API_VERSION             =   0x01000100
20
        DRIVER_VERSION          =   5
1561 hidnplayr 21
 
2852 hidnplayr 22
        MAX_DEVICES             =   16
1561 hidnplayr 23
 
2852 hidnplayr 24
        DEBUG                   =   1
25
        __DEBUG__               =   1
26
        __DEBUG_LEVEL__         =   1
1561 hidnplayr 27
 
2852 hidnplayr 28
        NUM_TX_DESC             =   4
29
        NUM_RX_DESC             =   4
1561 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
 
41
; for different PHY
42
 
2852 hidnplayr 43
    MysonPHY            =   1
44
    AhdocPHY            =   2
45
    SeeqPHY             =   3
46
    MarvellPHY          =   4
47
    Myson981            =   5
48
    LevelOnePHY         =   6
49
    OtherPHY            =   10
1561 hidnplayr 50
 
51
; Offsets to the Command and Status Registers.
52
 
2852 hidnplayr 53
    PAR0                =   0x0        ; physical address 0-3
54
    PAR1                =   0x04       ; physical address 4-5
55
    MAR0                =   0x08       ; multicast address 0-3
56
    MAR1                =   0x0C       ; multicast address 4-7
57
    FAR0                =   0x10       ; flow-control address 0-3
58
    FAR1                =   0x14       ; flow-control address 4-5
59
    TCRRCR              =   0x18       ; receive & transmit configuration
60
    BCR                 =   0x1C       ; bus command
61
    TXPDR               =   0x20       ; transmit polling demand
62
    RXPDR               =   0x24       ; receive polling demand
63
    RXCWP               =   0x28       ; receive current word pointer
64
    TXLBA               =   0x2C       ; transmit list base address
65
    RXLBA               =   0x30       ; receive list base address
66
    ISR                 =   0x34       ; interrupt status
67
    IMR                 =   0x38       ; interrupt mask
68
    FTH                 =   0x3C       ; flow control high/low threshold
69
    MANAGEMENT          =   0x40       ; bootrom/eeprom and mii management
70
    TALLY               =   0x44       ; tally counters for crc and mpa
71
    TSR                 =   0x48       ; tally counter for transmit status
72
    BMCRSR              =   0x4c       ; basic mode control and status
73
    PHYIDENTIFIER       =   0x50       ; phy identifier
74
    ANARANLPAR          =   0x54       ; auto-negotiation advertisement and link partner ability
75
    ANEROCR             =   0x58       ; auto-negotiation expansion and pci conf.
76
    BPREMRPSR           =   0x5c       ; bypass & receive error mask and phy status
1561 hidnplayr 77
 
78
; Bits in the interrupt status/enable registers.
79
 
2852 hidnplayr 80
    RFCON               =   0x00020000 ; receive flow control xon packet
81
    RFCOFF              =   0x00010000 ; receive flow control xoff packet
82
    LSCStatus           =   0x00008000 ; link status change
83
    ANCStatus           =   0x00004000 ; autonegotiation completed
84
    FBE                 =   0x00002000 ; fatal bus error
85
    FBEMask             =   0x00001800 ; mask bit12-11
86
    ParityErr           =   0x00000000 ; parity error
87
    TargetErr           =   0x00001000 ; target abort
88
    MasterErr           =   0x00000800 ; master error
89
    TUNF                =   0x00000400 ; transmit underflow
90
    ROVF                =   0x00000200 ; receive overflow
91
    ETI                 =   0x00000100 ; transmit early int
92
    ERI                 =   0x00000080 ; receive early int
93
    CNTOVF              =   0x00000040 ; counter overflow
94
    RBU                 =   0x00000020 ; receive buffer unavailable
95
    TBU                 =   0x00000010 ; transmit buffer unavilable
96
    TI                  =   0x00000008 ; transmit interrupt
97
    RI                  =   0x00000004 ; receive interrupt
98
    RxErr               =   0x00000002 ; receive error
1561 hidnplayr 99
 
100
; Bits in the NetworkConfig register.
101
 
2852 hidnplayr 102
    RxModeMask          =   0xe0
103
    AcceptAllPhys       =   0x80        ; promiscuous mode
104
    AcceptBroadcast     =   0x40        ; accept broadcast
105
    AcceptMulticast     =   0x20        ; accept mutlicast
106
    AcceptRunt          =   0x08        ; receive runt pkt
107
    ALP                 =   0x04        ; receive long pkt
108
    AcceptErr           =   0x02        ; receive error pkt
1561 hidnplayr 109
 
2852 hidnplayr 110
    AcceptMyPhys        =   0x00000000
111
    RxEnable            =   0x00000001
112
    RxFlowCtrl          =   0x00002000
113
    TxEnable            =   0x00040000
114
    TxModeFDX           =   0x00100000
115
    TxThreshold         =   0x00e00000
1561 hidnplayr 116
 
2852 hidnplayr 117
    PS1000              =   0x00010000
118
    PS10                =   0x00080000
119
    FD                  =   0x00100000
1561 hidnplayr 120
 
121
 
122
; Bits in network_desc.status
123
 
2852 hidnplayr 124
    RXOWN               =   0x80000000 ; own bit
125
    FLNGMASK            =   0x0fff0000 ; frame length
126
    FLNGShift           =   16
127
    MARSTATUS           =   0x00004000 ; multicast address received
128
    BARSTATUS           =   0x00002000 ; broadcast address received
129
    PHYSTATUS           =   0x00001000 ; physical address received
130
    RXFSD               =   0x00000800 ; first descriptor
131
    RXLSD               =   0x00000400 ; last descriptor
132
    ErrorSummary        =   0x80       ; error summary
133
    RUNT                =   0x40       ; runt packet received
134
    LONG                =   0x20       ; long packet received
135
    FAE                 =   0x10       ; frame align error
136
    CRC                 =   0x08       ; crc error
137
    RXER                =   0x04       ; receive error
1561 hidnplayr 138
 
139
; rx_desc_control_bits
140
 
2852 hidnplayr 141
    RXIC                =   0x00800000 ; interrupt control
142
    RBSShift            =   0
1561 hidnplayr 143
 
144
; tx_desc_status_bits
145
 
2852 hidnplayr 146
    TXOWN               =   0x80000000 ; own bit
147
    JABTO               =   0x00004000 ; jabber timeout
148
    CSL                 =   0x00002000 ; carrier sense lost
149
    LC                  =   0x00001000 ; late collision
150
    EC                  =   0x00000800 ; excessive collision
151
    UDF                 =   0x00000400 ; fifo underflow
152
    DFR                 =   0x00000200 ; deferred
153
    HF                  =   0x00000100 ; heartbeat fail
154
    NCRMask             =   0x000000ff ; collision retry count
155
    NCRShift            =   0
1561 hidnplayr 156
 
157
; tx_desc_control_bits
158
 
2852 hidnplayr 159
    TXIC                =   0x80000000 ; interrupt control
160
    ETIControl          =   0x40000000 ; early transmit interrupt
161
    TXLD                =   0x20000000 ; last descriptor
162
    TXFD                =   0x10000000 ; first descriptor
163
    CRCEnable           =   0x08000000 ; crc control
164
    PADEnable           =   0x04000000 ; padding control
165
    RetryTxLC           =   0x02000000 ; retry late collision
166
    PKTSMask            =   0x3ff800   ; packet size bit21-11
167
    PKTSShift           =   11
168
    TBSMask             =   0x000007ff ; transmit buffer bit 10-0
169
    TBSShift            =   0
1561 hidnplayr 170
 
171
; BootROM/EEPROM/MII Management Register
172
 
2852 hidnplayr 173
    MASK_MIIR_MII_READ  =   0x00000000
174
    MASK_MIIR_MII_WRITE =   0x00000008
175
    MASK_MIIR_MII_MDO   =   0x00000004
176
    MASK_MIIR_MII_MDI   =   0x00000002
177
    MASK_MIIR_MII_MDC   =   0x00000001
1561 hidnplayr 178
 
179
; ST+OP+PHYAD+REGAD+TA
180
 
2852 hidnplayr 181
    OP_READ             =   0x6000 ; ST:01+OP:10+PHYAD+REGAD+TA:Z0
182
    OP_WRITE            =   0x5002 ; ST:01+OP:01+PHYAD+REGAD+TA:10
1561 hidnplayr 183
 
184
; -------------------------------------------------------------------------
185
;      Constants for Myson PHY
186
; -------------------------------------------------------------------------
187
 
2852 hidnplayr 188
    MysonPHYID          =   0xd0000302
189
    MysonPHYID0         =   0x0302
190
    StatusRegister      =   18
191
    SPEED100            =   0x0400 ; bit10
192
    FULLMODE            =   0x0800 ; bit11
1561 hidnplayr 193
 
194
; -------------------------------------------------------------------------
195
;      Constants for Seeq 80225 PHY
196
; -------------------------------------------------------------------------
197
 
2852 hidnplayr 198
    SeeqPHYID0          =   0x0016
199
    MIIRegister18       =   18
200
    SPD_DET_100         =   0x80
201
    DPLX_DET_FULL       =   0x40
1561 hidnplayr 202
 
203
; -------------------------------------------------------------------------
204
;      Constants for Ahdoc 101 PHY
205
; -------------------------------------------------------------------------
206
 
2852 hidnplayr 207
    AhdocPHYID0         =   0x0022
208
    DiagnosticReg       =   18
209
    DPLX_FULL           =   0x0800
210
    Speed_100           =   0x0400
1561 hidnplayr 211
 
212
; --------------------------------------------------------------------------
213
;      Constants
214
; --------------------------------------------------------------------------
215
 
2852 hidnplayr 216
    MarvellPHYID0       =   0x0141
217
    LevelOnePHYID0      =   0x0013
1561 hidnplayr 218
 
2852 hidnplayr 219
    MII1000BaseTControlReg      =   9
220
    MII1000BaseTStatusReg       =   10
221
    SpecificReg         =   17
1561 hidnplayr 222
 
223
; for 1000BaseT Control Register
224
 
2852 hidnplayr 225
    PHYAbletoPerform1000FullDuplex =   0x0200
226
    PHYAbletoPerform1000HalfDuplex =   0x0100
227
    PHY1000AbilityMask             =   0x300
1561 hidnplayr 228
 
229
; for phy specific status register, marvell phy.
230
 
2852 hidnplayr 231
    SpeedMask      =   0x0c000
232
    Speed_1000M    =   0x08000
233
    Speed_100M     =   0x4000
234
    Speed_10M      =   0
235
    Full_Duplex    =   0x2000
1561 hidnplayr 236
 
237
; for phy specific status register, levelone phy
238
 
2852 hidnplayr 239
    LXT1000_100M   =   0x08000
240
    LXT1000_1000M  =   0x0c000
241
    LXT1000_Full   =   0x200
1561 hidnplayr 242
 
243
; for PHY
244
 
2852 hidnplayr 245
    LinkIsUp       =   0x0004
246
    LinkIsUp2      =   0x00040000
1561 hidnplayr 247
 
248
 
249
 
250
virtual at 0
251
 
2544 hidnplayr 252
        mtd_desc:
253
        .status                 dd ?
254
        .control                dd ?
255
        .buffer                 dd ?
256
        .next_desc              dd ?
1561 hidnplayr 257
 
2544 hidnplayr 258
        .next_desc_logical      dd ?
259
        .skbuff                 dd ?
1561 hidnplayr 260
 
2544 hidnplayr 261
        .reserved1              dd ?
262
        .reserved2              dd ?
1561 hidnplayr 263
 
2544 hidnplayr 264
        .size = $
1561 hidnplayr 265
 
266
end virtual
267
 
268
 
269
virtual at ebx
270
 
2544 hidnplayr 271
        device:
1561 hidnplayr 272
 
2544 hidnplayr 273
        ETH_DEVICE
1561 hidnplayr 274
 
2544 hidnplayr 275
        .tx_desc        rb NUM_TX_DESC*mtd_desc.size
276
        .rx_desc        rb NUM_RX_DESC*mtd_desc.size
1561 hidnplayr 277
 
2544 hidnplayr 278
        .io_addr        dd ?
3205 hidnplayr 279
        .pci_bus        dd ?
280
        .pci_dev        dd ?
2544 hidnplayr 281
        .irq_line       db ?
282
        .dev_id         dw ?
1561 hidnplayr 283
 
2544 hidnplayr 284
        .flags          dd ?
1561 hidnplayr 285
 
2544 hidnplayr 286
        .crvalue        dd ?
287
        .bcrvalue       dd ?
1561 hidnplayr 288
 
2544 hidnplayr 289
        .cur_rx         dd ?
290
        .cur_tx         dd ?
1561 hidnplayr 291
 
292
; These values are keep track of the transceiver/media in use.
293
 
2544 hidnplayr 294
        .linkok         dd ?
295
        .line_speed     dd ?
296
        .duplexmode     dd ?
297
        .default_port   dd ?
298
        .PHYType        dd ?
1561 hidnplayr 299
 
300
; MII transceiver section.
301
 
2544 hidnplayr 302
        .mii_cnt        dd ?    ; MII device addresses.
303
        .phys           db ?    ; MII device addresses.
1561 hidnplayr 304
 
2544 hidnplayr 305
        device_size = $ - device
1561 hidnplayr 306
 
307
end virtual
308
 
309
 
310
 
311
section '.flat' code readable align 16
312
 
313
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
314
;;                        ;;
315
;; proc START             ;;
316
;;                        ;;
317
;; (standard driver proc) ;;
318
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
319
 
320
align 4
321
proc START stdcall, state:dword
322
 
2544 hidnplayr 323
        cmp [state], 1
324
        jne .exit
1561 hidnplayr 325
 
326
  .entry:
327
 
3155 hidnplayr 328
        DEBUGF  2,"Loading %s driver\n", my_service
2544 hidnplayr 329
        stdcall RegService, my_service, service_proc
330
        ret
1561 hidnplayr 331
 
332
  .fail:
333
  .exit:
2544 hidnplayr 334
        xor eax, eax
335
        ret
1561 hidnplayr 336
 
337
endp
338
 
339
 
340
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
341
;;                        ;;
342
;; proc SERVICE_PROC      ;;
343
;;                        ;;
344
;; (standard driver proc) ;;
345
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
346
 
347
align 4
348
proc service_proc stdcall, ioctl:dword
349
 
2544 hidnplayr 350
        mov     edx, [ioctl]
351
        mov     eax, [IOCTL.io_code]
1561 hidnplayr 352
 
353
;------------------------------------------------------
354
 
2544 hidnplayr 355
        cmp     eax, 0 ;SRV_GETVERSION
356
        jne     @F
1561 hidnplayr 357
 
2544 hidnplayr 358
        cmp     [IOCTL.out_size], 4
3155 hidnplayr 359
        jb      .fail
2544 hidnplayr 360
        mov     eax, [IOCTL.output]
361
        mov     [eax], dword API_VERSION
1561 hidnplayr 362
 
2544 hidnplayr 363
        xor     eax, eax
364
        ret
1561 hidnplayr 365
 
366
;------------------------------------------------------
367
  @@:
2544 hidnplayr 368
        cmp     eax, 1 ;SRV_HOOK
369
        jne     .fail
1561 hidnplayr 370
 
2544 hidnplayr 371
        cmp     [IOCTL.inp_size], 3                     ; Data input must be at least 3 bytes
3155 hidnplayr 372
        jb      .fail
1561 hidnplayr 373
 
2544 hidnplayr 374
        mov     eax, [IOCTL.input]
375
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
376
        jne     .fail                                   ; other types arent supported for this card yet
1561 hidnplayr 377
 
378
; check if the device is already listed
379
 
2544 hidnplayr 380
        mov     esi, device_list
381
        mov     ecx, [devices]
382
        test    ecx, ecx
383
        jz      .firstdevice
1561 hidnplayr 384
 
385
;        mov     eax, [IOCTL.input]                     ; get the pci bus and device numbers
2544 hidnplayr 386
        mov     ax , [eax+1]                            ;
1561 hidnplayr 387
  .nextdevice:
2544 hidnplayr 388
        mov     ebx, [esi]
3205 hidnplayr 389
        cmp     al, byte[device.pci_bus]
390
        jne     @f
391
        cmp     ah, byte[device.pci_dev]
2544 hidnplayr 392
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
3205 hidnplayr 393
       @@:
2544 hidnplayr 394
        add     esi, 4
395
        loop    .nextdevice
1561 hidnplayr 396
 
397
 
398
; This device doesnt have its own eth_device structure yet, lets create one
399
  .firstdevice:
2544 hidnplayr 400
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
3155 hidnplayr 401
        jae     .fail
1561 hidnplayr 402
 
2544 hidnplayr 403
        allocate_and_clear ebx, device_size, .fail
1561 hidnplayr 404
 
405
; Fill in the direct call addresses into the struct
406
 
2544 hidnplayr 407
        mov     [device.reset], reset
408
        mov     [device.transmit], transmit
409
        mov     [device.get_MAC], read_mac
410
        mov     [device.set_MAC], write_mac
411
        mov     [device.unload], unload
412
        mov     [device.name], my_service
1561 hidnplayr 413
 
414
; save the pci bus and device numbers
415
 
2544 hidnplayr 416
        mov     eax, [IOCTL.input]
3205 hidnplayr 417
        movzx   ecx, byte[eax+1]
418
        mov     [device.pci_bus], ecx
419
        movzx   ecx, byte[eax+2]
420
        mov     [device.pci_dev], ecx
1561 hidnplayr 421
 
422
; Now, it's time to find the base io addres of the PCI device
423
 
3205 hidnplayr 424
        PCI_find_io
1561 hidnplayr 425
 
426
; We've found the io address, find IRQ now
427
 
3205 hidnplayr 428
        PCI_find_irq
1561 hidnplayr 429
 
2544 hidnplayr 430
        DEBUGF  2,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
431
        [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:8
1561 hidnplayr 432
 
433
; Ok, the eth_device structure is ready, let's probe the device
434
; Because initialization fires IRQ, IRQ handler must be aware of this device
2544 hidnplayr 435
        mov     eax, [devices]                                          ; Add the device structure to our device list
436
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
437
        inc     [devices]                                               ;
1561 hidnplayr 438
 
2544 hidnplayr 439
        call    probe                                                   ; this function will output in eax
440
        test    eax, eax
441
        jnz     .err2                                                   ; If an error occured, exit
1561 hidnplayr 442
 
2544 hidnplayr 443
        mov     [device.type], NET_TYPE_ETH
444
        call    NetRegDev
1561 hidnplayr 445
 
2544 hidnplayr 446
        cmp     eax, -1
447
        je      .destroy
1561 hidnplayr 448
 
2544 hidnplayr 449
        ret
1561 hidnplayr 450
 
451
; If the device was already loaded, find the device number and return it in eax
452
 
453
  .find_devicenum:
2544 hidnplayr 454
        DEBUGF  2,"Trying to find device number of already registered device\n"
455
        call    NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
456
                                                                        ; into a device number in edi
457
        mov     eax, edi                                                ; Application wants it in eax instead
458
        DEBUGF  2,"Kernel says: %u\n", eax
459
        ret
1561 hidnplayr 460
 
461
; If an error occured, remove all allocated data and exit (returning -1 in eax)
462
 
463
  .destroy:
2544 hidnplayr 464
        ; todo: reset device into virgin state
1561 hidnplayr 465
 
466
  .err2:
2544 hidnplayr 467
        dec     [devices]
1561 hidnplayr 468
  .err:
2544 hidnplayr 469
        DEBUGF  2,"removing device structure\n"
470
        stdcall KernelFree, ebx
1561 hidnplayr 471
  .fail:
2544 hidnplayr 472
        or      eax, -1
473
        ret
1561 hidnplayr 474
 
475
;------------------------------------------------------
476
endp
477
 
478
 
479
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
480
;;                                                                        ;;
481
;;        Actual Hardware dependent code starts here                      ;;
482
;;                                                                        ;;
483
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
484
 
485
 
486
 
487
align 4
488
unload:
2544 hidnplayr 489
        ; TODO: (in this particular order)
490
        ;
491
        ; - Stop the device
1561 hidnplayr 492
 
493
;    /* Disable Tx Rx*/
494
;    outl( mtdx.crvalue & (~TxEnable) & (~RxEnable), mtdx.ioaddr + TCRRCR );
495
;
496
;    /* Reset the chip to erase previous misconfiguration. */
497
;    mtd_reset(nic);
498
 
2544 hidnplayr 499
        ; - Detach int handler
500
        ; - Remove device from local list (device_list)
501
        ; - call unregister function in kernel
502
        ; - Remove all allocated structures and buffers the card used
1561 hidnplayr 503
 
2544 hidnplayr 504
        or      eax,-1
1561 hidnplayr 505
 
506
ret
507
 
508
 
509
;-------
510
;
511
; PROBE
512
;
513
;-------
514
align 4
515
probe:
516
 
2544 hidnplayr 517
        DEBUGF  2,"Probing mtd80x device\n"
1561 hidnplayr 518
 
3205 hidnplayr 519
        PCI_make_bus_master
1561 hidnplayr 520
 
3205 hidnplayr 521
        stdcall PciRead32, [device.pci_bus], [device.pci_dev], 0
1561 hidnplayr 522
 
3205 hidnplayr 523
        cmp     ax, 0x1516
2544 hidnplayr 524
        jne     .notfound
525
        shr     eax, 16
526
        mov     [device.dev_id], ax
1561 hidnplayr 527
 
2544 hidnplayr 528
        cmp     ax, 0x0800
529
        je      .has_mii_xcvr
1561 hidnplayr 530
 
2544 hidnplayr 531
        cmp     ax, 0x0803
532
        je      .has_chip_xcvr
1561 hidnplayr 533
 
2544 hidnplayr 534
        cmp     ax, 0x0891
535
        je      .has_mii_xcvr
1561 hidnplayr 536
 
537
  .notfound:
2544 hidnplayr 538
        DEBUGF  1,"Device not supported!\n"
539
        xor     eax, eax
540
        dec     eax
541
        ret
1561 hidnplayr 542
 
543
  .has_chip_xcvr:
2544 hidnplayr 544
        DEBUGF  1,"Device has chip xcvr\n"
1561 hidnplayr 545
 
2544 hidnplayr 546
        jmp     .xcvr_set
1561 hidnplayr 547
 
548
  .has_mii_xcvr:
2544 hidnplayr 549
        DEBUGF  1,"Device has mii xcvr\n"
1561 hidnplayr 550
 
551
  .xcvr_set:
552
 
2544 hidnplayr 553
        call    read_mac
1561 hidnplayr 554
 
555
; Reset the chip to erase previous misconfiguration.
556
 
2544 hidnplayr 557
        set_io  0
558
        set_io  BCR
559
        xor     eax, eax
560
        inc     eax
561
        out     dx, eax
1561 hidnplayr 562
 
563
; find the connected MII xcvrs
564
 
2544 hidnplayr 565
        cmp     [device.dev_id], 0x0803
566
        je      .is_803
1561 hidnplayr 567
 
2852 hidnplayr 568
;        int     phy, phy_idx =   0;
1561 hidnplayr 569
;
2852 hidnplayr 570
;        for (phy =   1; phy < 32 && phy_idx < 1; phy++) {
571
;            int mii_status =   mdio_read(nic, phy, 1);
1561 hidnplayr 572
;
2852 hidnplayr 573
;            if (mii_status !=   0xffff && mii_status !=   0x0000) {
574
;                mtdx.phys[phy_idx] =   phy;
1561 hidnplayr 575
;
576
;                DBG ( "%s: MII PHY found at address %d, status "
577
;                      "0x%4.4x.\n", mtdx.nic_name, phy, mii_status );
578
;                /* get phy type */
579
;                {
580
;                    unsigned int data;
581
;
2852 hidnplayr 582
;                    data =   mdio_read(nic, mtdx.phys[phy_idx], 2);
583
;                    if (data equ=   SeeqPHYID0)
584
;                        mtdx.PHYType =   SeeqPHY;
585
;                    else if (data equ=   AhdocPHYID0)
586
;                        mtdx.PHYType =   AhdocPHY;
587
;                    else if (data equ=   MarvellPHYID0)
588
;                        mtdx.PHYType =   MarvellPHY;
589
;                    else if (data equ=   MysonPHYID0)
590
;                        mtdx.PHYType =   Myson981;
591
;                    else if (data equ=   LevelOnePHYID0)
592
;                        mtdx.PHYType =   LevelOnePHY;
1561 hidnplayr 593
;                    else
2852 hidnplayr 594
;                        mtdx.PHYType =   OtherPHY;
1561 hidnplayr 595
;                }
596
;                phy_idx++;
597
;            }
598
;        }
599
;
2852 hidnplayr 600
;        mtdx.mii_cnt =   phy_idx;
601
;        if (phy_idx equ=   0) {
1561 hidnplayr 602
;            printf("%s: MII PHY not found -- this device may "
603
;                   "not operate correctly.\n", mtdx.nic_name);
604
;        }
605
 
2544 hidnplayr 606
        jmp     .no_803
1561 hidnplayr 607
 
608
  .is_803:
609
 
2544 hidnplayr 610
        mov     [device.phys], 32
1561 hidnplayr 611
 
612
; get phy type
2544 hidnplayr 613
        set_io  0
614
        set_io  PHYIDENTIFIER
615
        in      eax, dx
1561 hidnplayr 616
 
2544 hidnplayr 617
        cmp     eax, MysonPHYID
618
        jne     @f
1561 hidnplayr 619
 
2544 hidnplayr 620
        mov     [device.PHYType], MysonPHY
621
        DEBUGF  1,"MysonPHY\n"
622
        jmp     .no_803
1561 hidnplayr 623
 
624
       @@:
2544 hidnplayr 625
        mov     [device.PHYType], OtherPHY
626
        DEBUGF  1,"OtherPHY\n"
1561 hidnplayr 627
 
628
  .no_803:
629
 
630
;-------
631
;
632
; RESET
633
;
634
;-------
635
align 4
636
reset:
637
 
2544 hidnplayr 638
        DEBUGF  1,"Resetting mtd80x\n"
1561 hidnplayr 639
 
640
;--------------------------------
641
; insert irq handler on given irq
642
 
2544 hidnplayr 643
        movzx   eax, [device.irq_line]
644
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
645
        stdcall AttachIntHandler, eax, int_handler, dword 0
646
        test    eax, eax
647
        jnz     @f
648
        DEBUGF  1,"\nCould not attach int handler!\n"
1561 hidnplayr 649
;        or      eax, -1
650
;        ret
651
  @@:
652
 
653
; Reset the chip to erase previous misconfiguration.
654
 
2544 hidnplayr 655
        set_io  0
656
        set_io  BCR
657
        xor     eax, eax
658
        inc     eax
659
        out     dx, eax
1561 hidnplayr 660
 
2544 hidnplayr 661
        call    init_ring
1561 hidnplayr 662
 
663
; Initialize other registers.
664
; Configure the PCI bus bursts and FIFO thresholds.
665
 
2544 hidnplayr 666
        mov     [device.bcrvalue], 0x10 ; little-endian, 8 burst length
667
        mov     [device.crvalue], 0xa00 ; 128 burst length
1561 hidnplayr 668
 
2544 hidnplayr 669
        cmp     [device.dev_id], 0x891
670
        jne     @f
671
        or      [device.bcrvalue], 0x200       ; set PROG bit
672
        or      [device.crvalue], 0x02000000   ; set enhanced bit
1561 hidnplayr 673
       @@:
674
 
2544 hidnplayr 675
        or      [device.crvalue], RxEnable + TxThreshold + TxEnable
1561 hidnplayr 676
 
2544 hidnplayr 677
        call    set_rx_mode
1561 hidnplayr 678
 
2544 hidnplayr 679
        set_io  0
680
        set_io  BCR
681
        mov     eax, [device.bcrvalue]
682
        out     dx, eax
1561 hidnplayr 683
 
2544 hidnplayr 684
        set_io  TCRRCR
685
        mov     eax, [device.crvalue]
686
        out     dx, eax
1561 hidnplayr 687
 
2544 hidnplayr 688
        call    getlinkstatus
689
        call    getlinktype
1561 hidnplayr 690
 
691
; Restart Rx engine if stopped.
692
 
2544 hidnplayr 693
        set_io  0
694
        set_io  RXPDR
695
        xor     eax, eax
696
        out     dx, eax
1561 hidnplayr 697
 
698
; Enable interrupts
699
 
2544 hidnplayr 700
        set_io  0
701
        set_io  ISR
702
        mov     eax, (FBE or TUNF or CNTOVF or RBU or TI or RI)
703
        out     dx, eax
1561 hidnplayr 704
 
2544 hidnplayr 705
        set_io  IMR
1561 hidnplayr 706
;        mov     eax, (FBE or TUNF or CNTOVF or RBU or TI or RI)
2544 hidnplayr 707
        out     dx, eax
1561 hidnplayr 708
 
709
; clear packet/byte counters
710
 
2544 hidnplayr 711
        xor     eax, eax
712
        lea     edi, [device.bytes_tx]
713
        mov     ecx, 6
714
        rep     stosd
1561 hidnplayr 715
 
2544 hidnplayr 716
        mov     [device.mtu], 1514
717
        xor     eax, eax
1561 hidnplayr 718
 
2544 hidnplayr 719
        ret
1561 hidnplayr 720
 
721
 
722
 
723
 
724
align 4
725
init_ring:
726
 
2544 hidnplayr 727
        DEBUGF  1,"initializing rx and tx ring\n"
1561 hidnplayr 728
 
729
; Initialize all Rx descriptors
730
 
2544 hidnplayr 731
        lea     esi, [device.rx_desc]
732
        mov     [device.cur_rx], esi
733
        mov     ecx, NUM_RX_DESC
1561 hidnplayr 734
  .rx_desc_loop:
2544 hidnplayr 735
        mov     [esi + mtd_desc.status], RXOWN
736
        mov     [esi + mtd_desc.control], 1536 shl RBSShift
1561 hidnplayr 737
 
2544 hidnplayr 738
        lea     eax, [esi + mtd_desc.size]
739
        mov     [esi + mtd_desc.next_desc_logical], eax
740
        push    ecx esi
741
        GetRealAddr
742
        mov     [esi + mtd_desc.next_desc], eax
1561 hidnplayr 743
 
2544 hidnplayr 744
        stdcall KernelAlloc, 1536
745
        pop     esi
746
        push    esi
747
        mov     [esi + mtd_desc.skbuff], eax
748
        call    GetPgAddr
749
        pop     esi ecx
750
        mov     [esi + mtd_desc.buffer], eax
1561 hidnplayr 751
 
2544 hidnplayr 752
        add     esi, mtd_desc.size
753
        loop    .rx_desc_loop
1561 hidnplayr 754
 
755
; Mark the last entry as wrapping the ring.
756
 
2544 hidnplayr 757
        lea     eax, [device.rx_desc]
758
        mov     [esi - mtd_desc.size + mtd_desc.next_desc_logical], eax
759
        push    esi
760
        GetRealAddr
761
        pop     esi
762
        mov     [esi - mtd_desc.size + mtd_desc.next_desc], eax
1561 hidnplayr 763
 
2544 hidnplayr 764
        set_io  0
765
        set_io  RXLBA
766
        out     dx, eax
1561 hidnplayr 767
 
768
; Initialize all Tx descriptors
769
 
2544 hidnplayr 770
        lea     esi, [device.tx_desc]
771
        mov     [device.cur_tx], esi
772
        mov     ecx, NUM_TX_DESC
1561 hidnplayr 773
  .tx_desc_loop:
2544 hidnplayr 774
        mov     [esi + mtd_desc.status], 0
1561 hidnplayr 775
 
2544 hidnplayr 776
        lea     eax, [esi + mtd_desc.size]
777
        mov     [esi + mtd_desc.next_desc_logical], eax
778
        push    ecx esi
779
        GetRealAddr
780
        pop     esi ecx
781
        mov     [esi + mtd_desc.next_desc], eax
1561 hidnplayr 782
 
2544 hidnplayr 783
        add     esi, mtd_desc.size
784
        loop    .tx_desc_loop
1561 hidnplayr 785
 
786
; Mark the last entry as wrapping the ring.
787
 
2544 hidnplayr 788
        lea     eax, [device.tx_desc]
789
        mov     [esi - mtd_desc.size + mtd_desc.next_desc_logical], eax
790
        push    esi
791
        GetRealAddr
792
        pop     esi
793
        mov     [esi - mtd_desc.size + mtd_desc.next_desc], eax
1561 hidnplayr 794
 
2544 hidnplayr 795
        set_io  0
796
        set_io  TXLBA
797
        out     dx, eax
1561 hidnplayr 798
 
2544 hidnplayr 799
        ret
1561 hidnplayr 800
 
801
 
802
align 4
803
set_rx_mode:
804
 
2544 hidnplayr 805
        DEBUGF  1,"Setting RX mode\n"
1561 hidnplayr 806
 
807
; Too many to match, or accept all multicasts.
808
 
2544 hidnplayr 809
        set_io  0
810
        set_io  MAR0
811
        xor     eax, eax
812
        not     eax
813
        out     dx, eax
814
        set_io  MAR1
815
        out     dx, eax
1561 hidnplayr 816
 
2544 hidnplayr 817
        and     [device.crvalue], not (RxModeMask)
818
        or      [device.crvalue], AcceptBroadcast + AcceptMulticast + AcceptMyPhys
1561 hidnplayr 819
 
2544 hidnplayr 820
        ret
1561 hidnplayr 821
 
822
 
823
align 4
824
getlinkstatus:
825
 
2544 hidnplayr 826
        DEBUGF  1,"Getting link status\n"
1561 hidnplayr 827
 
2544 hidnplayr 828
        mov     [device.linkok], 0
1561 hidnplayr 829
 
2544 hidnplayr 830
        cmp     [device.PHYType], MysonPHY
831
        jne     .no_myson_phy
1561 hidnplayr 832
 
2544 hidnplayr 833
        set_io  0
834
        set_io  BMCRSR
835
        mov     ecx, 1000
1561 hidnplayr 836
  .loop1:
2544 hidnplayr 837
        in      eax, dx
838
        test    eax, LinkIsUp2
839
        jnz     .link_ok
1561 hidnplayr 840
 
2544 hidnplayr 841
        push    ecx edx ebx
842
        mov     esi, 10
843
        call    Sleep
844
        pop     ebx edx ecx
845
        loop    .loop1
1561 hidnplayr 846
 
2544 hidnplayr 847
        ret
1561 hidnplayr 848
 
849
  .no_myson_phy:
850
 
2852 hidnplayr 851
;        for (i =   0; i < DelayTime; ++i) {
1561 hidnplayr 852
;            if (mdio_read(nic, mtdx.phys[0], MII_BMSR) & BMSR_LSTATUS) {
2852 hidnplayr 853
;                mtdx.linkok =   1;
1561 hidnplayr 854
;                return;
855
;            }
856
;            m80x_delay(100);
857
 
2544 hidnplayr 858
        ret
1561 hidnplayr 859
 
860
  .link_ok:
2544 hidnplayr 861
        DEBUGF  1,"Link is up\n"
862
        inc     [device.linkok]
863
        ret
1561 hidnplayr 864
 
865
 
866
 
867
 
868
align 4
869
getlinktype:
870
 
2544 hidnplayr 871
        DEBUGF  1,"Getting link type\n"
1561 hidnplayr 872
 
2544 hidnplayr 873
        cmp     [device.PHYType], MysonPHY
874
        jne     .no_myson_phy
1561 hidnplayr 875
 
2544 hidnplayr 876
        DEBUGF  1,"myson PHY\n"
1561 hidnplayr 877
 
2544 hidnplayr 878
        set_io  0
879
        set_io  TCRRCR
880
        in      eax, dx
1561 hidnplayr 881
 
2852 hidnplayr 882
        mov     [device.duplexmode], 1  ; 1 =   half duplex
2544 hidnplayr 883
        test    eax, FD
884
        jne     @f
885
        DEBUGF  1,"full duplex\n"
2852 hidnplayr 886
        inc     [device.duplexmode]     ; 2 =   full duplex
1561 hidnplayr 887
       @@:
888
 
2852 hidnplayr 889
        mov     [device.line_speed], 1  ; 1 =   10M
2544 hidnplayr 890
        test    eax, PS10
891
        jne     @f
892
        DEBUGF  1,"100mbit\n"
2852 hidnplayr 893
        inc     [device.line_speed]     ; 2 =   100M
1561 hidnplayr 894
       @@:
895
 
2544 hidnplayr 896
        ret
1561 hidnplayr 897
 
898
  .no_myson_phy:
899
 
2544 hidnplayr 900
        DEBUGF  1,"no myson phy\n"
1561 hidnplayr 901
 
2852 hidnplayr 902
;        if (mtdx.PHYType equ=   SeeqPHY) { /* this PHY is SEEQ 80225 */
1561 hidnplayr 903
;            unsigned int data;
904
;
2852 hidnplayr 905
;            data =   mdio_read(dev, mtdx.phys[0], MIIRegister18);
1561 hidnplayr 906
;            if (data & SPD_DET_100)
2852 hidnplayr 907
;                mtdx.line_speed =   2; /* 100M */
1561 hidnplayr 908
;            else
2852 hidnplayr 909
;                mtdx.line_speed =   1; /* 10M */
1561 hidnplayr 910
;            if (data & DPLX_DET_FULL)
2852 hidnplayr 911
;                mtdx.duplexmode =   2; /* full duplex mode */
1561 hidnplayr 912
;            else
2852 hidnplayr 913
;                mtdx.duplexmode =   1; /* half duplex mode */
914
;        } else if (mtdx.PHYType equ=   AhdocPHY) {
1561 hidnplayr 915
;            unsigned int data;
916
;
2852 hidnplayr 917
;            data =   mdio_read(dev, mtdx.phys[0], DiagnosticReg);
1561 hidnplayr 918
;            if (data & Speed_100)
2852 hidnplayr 919
;                mtdx.line_speed =   2; /* 100M */
1561 hidnplayr 920
;            else
2852 hidnplayr 921
;                mtdx.line_speed =   1; /* 10M */
1561 hidnplayr 922
;            if (data & DPLX_FULL)
2852 hidnplayr 923
;                mtdx.duplexmode =   2; /* full duplex mode */
1561 hidnplayr 924
;            else
2852 hidnplayr 925
;                mtdx.duplexmode =   1; /* half duplex mode */
1561 hidnplayr 926
;        }
2852 hidnplayr 927
;        else if (mtdx.PHYType equ=   MarvellPHY) {
1561 hidnplayr 928
;            unsigned int data;
929
;
2852 hidnplayr 930
;            data =   mdio_read(dev, mtdx.phys[0], SpecificReg);
1561 hidnplayr 931
;            if (data & Full_Duplex)
2852 hidnplayr 932
;                mtdx.duplexmode =   2; /* full duplex mode */
1561 hidnplayr 933
;            else
2852 hidnplayr 934
;                mtdx.duplexmode =   1; /* half duplex mode */
935
;            data &=   SpeedMask;
936
;            if (data equ=   Speed_1000M)
937
;                mtdx.line_speed =   3; /* 1000M */
938
;            else if (data equ=   Speed_100M)
939
;                mtdx.line_speed =   2; /* 100M */
1561 hidnplayr 940
;            else
2852 hidnplayr 941
;                mtdx.line_speed =   1; /* 10M */
1561 hidnplayr 942
;        }
2852 hidnplayr 943
;        else if (mtdx.PHYType equ=   Myson981) {
1561 hidnplayr 944
;            unsigned int data;
945
;
2852 hidnplayr 946
;            data =   mdio_read(dev, mtdx.phys[0], StatusRegister);
1561 hidnplayr 947
;
948
;            if (data & SPEED100)
2852 hidnplayr 949
;                mtdx.line_speed =   2;
1561 hidnplayr 950
;            else
2852 hidnplayr 951
;                mtdx.line_speed =   1;
1561 hidnplayr 952
;
953
;            if (data & FULLMODE)
2852 hidnplayr 954
;                mtdx.duplexmode =   2;
1561 hidnplayr 955
;            else
2852 hidnplayr 956
;                mtdx.duplexmode =   1;
1561 hidnplayr 957
;        }
2852 hidnplayr 958
;        else if (mtdx.PHYType equ=   LevelOnePHY) {
1561 hidnplayr 959
;            unsigned int data;
960
;
2852 hidnplayr 961
;            data =   mdio_read(dev, mtdx.phys[0], SpecificReg);
1561 hidnplayr 962
;            if (data & LXT1000_Full)
2852 hidnplayr 963
;                mtdx.duplexmode =   2; /* full duplex mode */
1561 hidnplayr 964
;            else
2852 hidnplayr 965
;                mtdx.duplexmode =   1; /* half duplex mode */
966
;            data &=   SpeedMask;
967
;            if (data equ=   LXT1000_1000M)
968
;                mtdx.line_speed =   3; /* 1000M */
969
;            else if (data equ=   LXT1000_100M)
970
;                mtdx.line_speed =   2; /* 100M */
1561 hidnplayr 971
;            else
2852 hidnplayr 972
 ;               mtdx.line_speed =   1; /* 10M */
1561 hidnplayr 973
  ;      }
974
 
975
;        // chage crvalue
976
;        // mtdx.crvalue&equ(~PS10)&(~FD);
2852 hidnplayr 977
;        mtdx.crvalue &=   (~PS10) & (~FD) & (~PS1000);
978
;        if (mtdx.line_speed equ=   1)
979
;            mtdx.crvalue |=   PS10;
980
;        else if (mtdx.line_speed equ=   3)
981
;            mtdx.crvalue |=   PS1000;
982
;        if (mtdx.duplexmode equ=   2)
983
;            mtdx.crvalue |=   FD;
1561 hidnplayr 984
;
985
 
2544 hidnplayr 986
        ret
1561 hidnplayr 987
 
988
 
989
 
990
 
991
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
992
;;                                         ;;
993
;; Transmit                                ;;
994
;;                                         ;;
995
;; In: buffer pointer in [esp+4]           ;;
996
;;     size of buffer in [esp+8]           ;;
997
;;     pointer to device structure in ebx  ;;
998
;;                                         ;;
999
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1000
 
1001
align 4
1002
transmit:
1003
 
2544 hidnplayr 1004
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8]
1005
        mov     eax, [esp+4]
1006
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
1007
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
1008
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
1009
        [eax+13]:2,[eax+12]:2
1561 hidnplayr 1010
 
2544 hidnplayr 1011
        cmp     dword [esp+8], 1514
1012
        ja      .fail
1561 hidnplayr 1013
 
2544 hidnplayr 1014
        mov     esi, [device.cur_tx]
1015
        push    [esi + mtd_desc.next_desc_logical]
1016
        pop     [device.cur_tx]
1561 hidnplayr 1017
 
2544 hidnplayr 1018
        ; todo: check if descriptor is not owned by the device!
1561 hidnplayr 1019
 
2544 hidnplayr 1020
        mov     eax, [esp + 4]
1021
        mov     [esi + mtd_desc.skbuff], eax
1022
        GetRealAddr
1023
        mov     [esi + mtd_desc.buffer], eax
1561 hidnplayr 1024
 
2544 hidnplayr 1025
        mov     eax, [esp + 8]
1026
        shl     eax, PKTSShift               ; packet size
1027
        or      eax, TXLD + TXFD + CRCEnable + PADEnable + TXIC + 1536 shl TBSShift ; buffer size
1028
        mov     [esi + mtd_desc.control], eax
1561 hidnplayr 1029
 
2544 hidnplayr 1030
        mov     [esi + mtd_desc.status], TXOWN
1561 hidnplayr 1031
 
1032
;-------------
1033
; Update stats
1034
 
2544 hidnplayr 1035
        inc     [device.packets_tx]
1036
        mov     eax, [esp+8]
1037
        add     dword [device.bytes_tx], eax
1038
        adc     dword [device.bytes_tx + 4], 0
1561 hidnplayr 1039
 
1040
; Point to transmit descriptor
1041
 
2544 hidnplayr 1042
        set_io  0
1043
        set_io  TXLBA
1044
        mov     eax, esi
1045
        GetRealAddr
1046
        out     dx, eax
1561 hidnplayr 1047
 
1048
;        set_io  TCRRCR
1049
;        mov     eax, [device.crvalue]
1050
;        out     dx, eax
1051
 
1052
; Wake the potentially-idle transmit channel.
1053
 
2544 hidnplayr 1054
        set_io  TXPDR           ; TX Poll
1055
        xor     eax, eax
1056
        out     dx, eax
1561 hidnplayr 1057
 
2544 hidnplayr 1058
        DEBUGF  1,"transmit ok\n"
1059
        xor     eax, eax
1060
        ret     8
1561 hidnplayr 1061
 
1062
  .fail:
2544 hidnplayr 1063
        DEBUGF  1,"transmit failed\n"
1064
        or      eax, -1
1065
        stdcall KernelFree, [esp + 4]
1066
        ret     8
1561 hidnplayr 1067
 
1068
 
1069
 
1070
align 4
1071
read_mac:
1072
 
2544 hidnplayr 1073
        set_io  0
1074
        set_io  PAR0
1075
        lea     edi, [device.mac]
1076
        insd
1077
        stosd
1078
        set_io  PAR1
1079
        insw
1080
        stosw
1561 hidnplayr 1081
 
2544 hidnplayr 1082
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n",\
1083
        [device.mac+0]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2
1561 hidnplayr 1084
 
2544 hidnplayr 1085
        ret
1561 hidnplayr 1086
 
1087
align 4
1088
write_mac:
1089
 
2544 hidnplayr 1090
        ret
1561 hidnplayr 1091
 
1092
 
1093
 
1094
;;;;;;;;;;;;;;;;;;;;;;;
1095
;;                   ;;
1096
;; Interrupt handler ;;
1097
;;                   ;;
1098
;;;;;;;;;;;;;;;;;;;;;;;
1099
 
1100
align 4
1101
int_handler:
1102
 
2935 hidnplayr 1103
        DEBUGF  1,"\n%s int\n", my_service
1561 hidnplayr 1104
 
1105
; find pointer of device wich made IRQ occur
1106
 
2544 hidnplayr 1107
        mov     ecx, [devices]
1108
        test    ecx, ecx
2935 hidnplayr 1109
        jz      .nothing
2544 hidnplayr 1110
        mov     esi, device_list
1561 hidnplayr 1111
  .nextdevice:
2935 hidnplayr 1112
        mov     ebx, [esi]
1561 hidnplayr 1113
 
2544 hidnplayr 1114
        set_io  0
1115
        set_io  ISR
1116
        in      eax, dx
2935 hidnplayr 1117
        out     dx, eax                                 ; send it back to ACK
2544 hidnplayr 1118
        test    eax, eax
1119
        jnz     .got_it
1561 hidnplayr 1120
  .continue:
2544 hidnplayr 1121
        add     esi, 4
1122
        dec     ecx
1123
        jnz     .nextdevice
2935 hidnplayr 1124
  .nothing:
2544 hidnplayr 1125
        ret                                             ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
1561 hidnplayr 1126
 
1127
  .got_it:
1128
 
2935 hidnplayr 1129
        DEBUGF  1,"Device: %x Status: %x ", ebx, ax
1561 hidnplayr 1130
 
2544 hidnplayr 1131
        test    ax, RI  ; receive interrupt
1132
        jz      .no_rx
1561 hidnplayr 1133
 
2544 hidnplayr 1134
        DEBUGF  1,"Receive interrupt\n"
1561 hidnplayr 1135
  .rx:
2544 hidnplayr 1136
        push    ax
1561 hidnplayr 1137
 
1138
  .rx_loop:
2544 hidnplayr 1139
        mov     esi, [device.cur_rx]
1561 hidnplayr 1140
 
2544 hidnplayr 1141
        test    [esi + mtd_desc.status], RXOWN
1142
        jnz     .fail_rx
1561 hidnplayr 1143
 
2544 hidnplayr 1144
        push    .rx_complete
1561 hidnplayr 1145
 
2544 hidnplayr 1146
        mov     ecx, [esi + mtd_desc.status]
1147
        shr     ecx, FLNGShift
1148
        sub     ecx, 4                  ; we dont need CRC
1149
        push    ecx
1561 hidnplayr 1150
 
1151
;-------------
1152
; Update stats
1153
 
2544 hidnplayr 1154
        add     dword [device.bytes_rx], ecx
1155
        adc     dword [device.bytes_rx + 4], 0
1156
        inc     dword [device.packets_rx]
1561 hidnplayr 1157
 
1158
 
2544 hidnplayr 1159
        push    [esi + mtd_desc.skbuff]
1561 hidnplayr 1160
 
2981 hidnplayr 1161
        jmp     Eth_input
1561 hidnplayr 1162
 
1163
  .rx_complete:
2544 hidnplayr 1164
        mov     esi, [device.cur_rx]
1561 hidnplayr 1165
 
2544 hidnplayr 1166
        mov     [esi + mtd_desc.control], 1536 shl RBSShift
1561 hidnplayr 1167
 
2544 hidnplayr 1168
        stdcall KernelAlloc, 1536
1169
        mov     [esi + mtd_desc.skbuff], eax
1170
        call    GetPgAddr
1171
        mov     [esi + mtd_desc.buffer], eax
1561 hidnplayr 1172
 
2544 hidnplayr 1173
        mov     [esi + mtd_desc.status], RXOWN
1561 hidnplayr 1174
 
2544 hidnplayr 1175
        mov     eax, [esi + mtd_desc.next_desc_logical]
1176
        mov     [device.cur_rx], eax
1561 hidnplayr 1177
 
2544 hidnplayr 1178
        jmp     .rx_loop
1561 hidnplayr 1179
;
1180
;    while( ( mtdx.cur_rx->status & RXOWN ) == 0 )
1181
;    {
1182
;        mtdx.cur_rx->status = RXOWN;
1183
;        mtdx.cur_rx = mtdx.cur_rx->next_desc_logical;
1184
;    }
1185
;
1186
;    /* Restart Rx engine if stopped. */
1187
;    outl(0, mtdx.ioaddr + RXPDR);
1188
 
1189
  .fail_rx:
2544 hidnplayr 1190
        DEBUGF  1,"RX failed\n"
1561 hidnplayr 1191
 
2544 hidnplayr 1192
        pop     ax
1561 hidnplayr 1193
  .no_rx:
1194
 
2544 hidnplayr 1195
        test    ax, TI ; transmit interrupt
1196
        jz      .no_tx
1561 hidnplayr 1197
 
2544 hidnplayr 1198
        DEBUGF  1,"Transmit interrupt\n"
1199
        push    ax
1561 hidnplayr 1200
 
2544 hidnplayr 1201
        lea     esi, [device.tx_desc]
1202
        mov     ecx, NUM_TX_DESC
1561 hidnplayr 1203
  .tx_loop:
1204
 
2544 hidnplayr 1205
        test    [esi + mtd_desc.status], TXOWN
1206
        jnz     .skip_this_one
1561 hidnplayr 1207
 
2544 hidnplayr 1208
        mov     eax, [esi + mtd_desc.skbuff]
1209
        test    eax, eax
1210
        je      .skip_this_one
1561 hidnplayr 1211
 
2544 hidnplayr 1212
        mov     [esi + mtd_desc.skbuff], 0
1561 hidnplayr 1213
 
2544 hidnplayr 1214
        DEBUGF  1,"freeing buffer:%x\n", eax
1215
        stdcall KernelFree, eax
1561 hidnplayr 1216
 
1217
  .skip_this_one:
2544 hidnplayr 1218
        mov     esi, [esi + mtd_desc.next_desc_logical]
1219
        loop    .tx_loop
1561 hidnplayr 1220
 
2544 hidnplayr 1221
        pop     ax
1561 hidnplayr 1222
 
1223
  .no_tx:
1224
 
2544 hidnplayr 1225
        test    ax, TBU
1226
        jz      .no_tbu
1561 hidnplayr 1227
 
2544 hidnplayr 1228
        DEBUGF  1,"Transmit buffer unavailable!\n"
1561 hidnplayr 1229
 
1230
  .no_tbu:
1231
 
1232
  .fail:
1233
 
2544 hidnplayr 1234
        ret
1561 hidnplayr 1235
 
1236
 
1237
; End of code
1238
 
2544 hidnplayr 1239
align 4                                         ; Place all initialised data here
1561 hidnplayr 1240
 
1241
devices       dd 0
1242
version       dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
2544 hidnplayr 1243
my_service    db 'mtd80x',0                    ; max 16 chars include zero
1561 hidnplayr 1244
 
1245
 
1246
;   0x1516, 0x0800, "MTD800", "Myson MTD800"
1247
;   0x1516, 0x0803, "MTD803", "Surecom EP-320X"
1248
;   0x1516, 0x0891, "MTD891", "Myson MTD891"
1249
 
1250
 
2544 hidnplayr 1251
include_debug_strings                           ; All data wich FDO uses will be included here
1561 hidnplayr 1252
 
1253
section '.data' data readable writable align 16 ; place all uninitialized data place here
1254
 
2544 hidnplayr 1255
device_list rd MAX_DEVICES                     ; This list contains all pointers to device structures the driver is handling
1561 hidnplayr 1256