Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
3545 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
4467 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved.    ;;
3545 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
 
4580 hidnplayr 17
format PE DLL native
18
entry START
3545 hidnplayr 19
 
4580 hidnplayr 20
        CURRENT_API             = 0x0200
21
        COMPATIBLE_API          = 0x0100
22
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
3545 hidnplayr 23
 
24
        MAX_DEVICES             = 16
25
 
26
        DEBUG                   = 1
27
        __DEBUG__               = 1
28
        __DEBUG_LEVEL__         = 2
29
 
4576 hidnplayr 30
        NUM_TX_DESC             = 6
31
        NUM_RX_DESC             = 12
3545 hidnplayr 32
 
4580 hidnplayr 33
section '.flat' readable writable executable
34
 
35
include '../proc32.inc'
4467 hidnplayr 36
include '../struct.inc'
37
include '../macros.inc'
3545 hidnplayr 38
include '../fdo.inc'
4580 hidnplayr 39
include '../netdrv_pe.inc'
3545 hidnplayr 40
 
41
; for different PHY
42
 
43
    MysonPHY            = 1
44
    AhdocPHY            = 2
45
    SeeqPHY             = 3
46
    MarvellPHY          = 4
47
    Myson981            = 5
48
    LevelOnePHY         = 6
49
    OtherPHY            = 10
50
 
51
; Offsets to the Command and Status Registers.
52
 
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
77
 
78
; Bits in the interrupt status/enable registers.
79
 
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
99
 
100
; Bits in the NetworkConfig register.
101
 
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
109
 
110
    AcceptMyPhys        = 0x00000000
111
    RxEnable            = 0x00000001
112
    RxFlowCtrl          = 0x00002000
113
    TxEnable            = 0x00040000
114
    TxModeFDX           = 0x00100000
115
    TxThreshold         = 0x00e00000
116
 
117
    PS1000              = 0x00010000
118
    PS10                = 0x00080000
119
    FD                  = 0x00100000
120
 
121
 
122
; Bits in network_desc.status
123
 
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
138
 
139
; rx_desc_control_bits
140
 
141
    RXIC                = 0x00800000    ; interrupt control
142
    RBSShift            = 0
143
 
144
; tx_desc_status_bits
145
 
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
156
 
157
; tx_desc_control_bits
158
 
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
170
 
171
; BootROM/EEPROM/MII Management Register
172
 
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
178
 
179
; ST+OP+PHYAD+REGAD+TA
180
 
181
    OP_READ             = 0x6000        ; ST:01+OP:10+PHYAD+REGAD+TA:Z0
182
    OP_WRITE            = 0x5002        ; ST:01+OP:01+PHYAD+REGAD+TA:10
183
 
184
; -------------------------------------------------------------------------
185
;      Constants for Myson PHY
186
; -------------------------------------------------------------------------
187
 
188
    MysonPHYID          = 0xd0000302
189
    MysonPHYID0         = 0x0302
190
    StatusRegister      = 18
191
    SPEED100            = 0x0400        ; bit10
192
    FULLMODE            = 0x0800        ; bit11
193
 
194
; -------------------------------------------------------------------------
195
;      Constants for Seeq 80225 PHY
196
; -------------------------------------------------------------------------
197
 
198
    SeeqPHYID0          = 0x0016
199
    MIIRegister18       = 18
200
    SPD_DET_100         = 0x80
201
    DPLX_DET_FULL       = 0x40
202
 
203
; -------------------------------------------------------------------------
204
;      Constants for Ahdoc 101 PHY
205
; -------------------------------------------------------------------------
206
 
207
    AhdocPHYID0         = 0x0022
208
    DiagnosticReg       = 18
209
    DPLX_FULL           = 0x0800
210
    Speed_100           = 0x0400
211
 
212
; --------------------------------------------------------------------------
213
;      Constants
214
; --------------------------------------------------------------------------
215
 
216
    MarvellPHYID0               = 0x0141
217
    LevelOnePHYID0              = 0x0013
218
 
219
    MII1000BaseTControlReg      = 9
220
    MII1000BaseTStatusReg       = 10
221
    SpecificReg                 = 17
222
 
223
; for 1000BaseT Control Register
224
 
225
    PHYAbletoPerform1000FullDuplex = 0x0200
226
    PHYAbletoPerform1000HalfDuplex = 0x0100
227
    PHY1000AbilityMask             = 0x300
228
 
229
; for phy specific status register, marvell phy.
230
 
231
    SpeedMask      = 0x0c000
232
    Speed_1000M    = 0x08000
233
    Speed_100M     = 0x4000
234
    Speed_10M      = 0
235
    Full_Duplex    = 0x2000
236
 
237
; for phy specific status register, levelone phy
238
 
239
    LXT1000_100M   = 0x08000
240
    LXT1000_1000M  = 0x0c000
241
    LXT1000_Full   = 0x200
242
 
243
; for PHY
244
 
245
    LinkIsUp       = 0x0004
246
    LinkIsUp2      = 0x00040000
247
 
248
 
249
 
4580 hidnplayr 250
struct  descriptor
251
        status                  dd ?
252
        control                 dd ?
253
        buffer                  dd ?
254
        next_desc               dd ?
3545 hidnplayr 255
 
4580 hidnplayr 256
        next_desc_logical       dd ?
257
        skbuff                  dd ?
258
        reserved1               dd ?
259
        reserved2               dd ?
260
ends
3545 hidnplayr 261
 
262
 
4580 hidnplayr 263
struct  device          ETH_DEVICE
3545 hidnplayr 264
 
4580 hidnplayr 265
        io_addr         dd ?
266
        pci_bus         dd ?
267
        pci_dev         dd ?
268
        irq_line        db ?
269
        dev_id          dw ?
270
        flags           dd ?
271
        crvalue         dd ?
272
        bcrvalue        dd ?
273
        cur_rx          dd ?
274
        cur_tx          dd ?
275
        default_port    dd ?
276
        PHYType         dd ?
3545 hidnplayr 277
 
278
; MII transceiver section.
4580 hidnplayr 279
        mii_cnt         dd ?    ; MII device addresses.
280
        phys            db ?    ; MII device addresses.
3545 hidnplayr 281
 
4580 hidnplayr 282
; descriptors
283
        rb 0x100 - ($ and 0xff) ; align 256
284
        tx_desc         rb NUM_TX_DESC*sizeof.descriptor
285
        rx_desc         rb NUM_RX_DESC*sizeof.descriptor
3545 hidnplayr 286
 
4580 hidnplayr 287
ends
3545 hidnplayr 288
 
289
 
290
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
291
;;                        ;;
292
;; proc START             ;;
293
;;                        ;;
294
;; (standard driver proc) ;;
295
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
296
 
4580 hidnplayr 297
proc START c, reason:dword, cmdline:dword
3545 hidnplayr 298
 
4580 hidnplayr 299
        cmp     [reason], DRV_ENTRY
300
        jne     .fail
3545 hidnplayr 301
 
4580 hidnplayr 302
        DEBUGF  1,"Loading driver\n"
303
        invoke  RegService, my_service, service_proc
3545 hidnplayr 304
        ret
305
 
306
  .fail:
4580 hidnplayr 307
        xor     eax, eax
3545 hidnplayr 308
        ret
309
 
310
endp
311
 
312
 
313
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
314
;;                        ;;
315
;; proc SERVICE_PROC      ;;
316
;;                        ;;
317
;; (standard driver proc) ;;
318
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
319
 
320
proc service_proc stdcall, ioctl:dword
321
 
322
        mov     edx, [ioctl]
4470 hidnplayr 323
        mov     eax, [edx + IOCTL.io_code]
3545 hidnplayr 324
 
325
;------------------------------------------------------
326
 
327
        cmp     eax, 0 ;SRV_GETVERSION
328
        jne     @F
329
 
4470 hidnplayr 330
        cmp     [edx + IOCTL.out_size], 4
3545 hidnplayr 331
        jb      .fail
4470 hidnplayr 332
        mov     eax, [edx + IOCTL.output]
3545 hidnplayr 333
        mov     [eax], dword API_VERSION
334
 
335
        xor     eax, eax
336
        ret
337
 
338
;------------------------------------------------------
339
  @@:
340
        cmp     eax, 1 ;SRV_HOOK
341
        jne     .fail
342
 
4470 hidnplayr 343
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
3545 hidnplayr 344
        jb      .fail
345
 
4470 hidnplayr 346
        mov     eax, [edx + IOCTL.input]
3545 hidnplayr 347
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
348
        jne     .fail                                   ; other types arent supported for this card yet
349
 
350
; check if the device is already listed
351
 
352
        mov     esi, device_list
353
        mov     ecx, [devices]
354
        test    ecx, ecx
355
        jz      .firstdevice
356
 
4470 hidnplayr 357
;        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
358
        mov     ax, [eax+1]                             ;
3545 hidnplayr 359
  .nextdevice:
360
        mov     ebx, [esi]
4580 hidnplayr 361
        cmp     al, byte[ebx + device.pci_bus]
3545 hidnplayr 362
        jne     @f
4580 hidnplayr 363
        cmp     ah, byte[ebx + device.pci_dev]
3545 hidnplayr 364
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
365
       @@:
366
        add     esi, 4
367
        loop    .nextdevice
368
 
369
 
370
; This device doesnt have its own eth_device structure yet, lets create one
371
  .firstdevice:
372
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
373
        jae     .fail
374
 
4580 hidnplayr 375
        allocate_and_clear ebx, sizeof.device, .fail
3545 hidnplayr 376
 
377
; Fill in the direct call addresses into the struct
378
 
4580 hidnplayr 379
        mov     [ebx + device.reset], reset
380
        mov     [ebx + device.transmit], transmit
381
        mov     [ebx + device.unload], unload
382
        mov     [ebx + device.name], my_service
3545 hidnplayr 383
 
384
; save the pci bus and device numbers
385
 
4470 hidnplayr 386
        mov     eax, [edx + IOCTL.input]
3545 hidnplayr 387
        movzx   ecx, byte[eax+1]
4580 hidnplayr 388
        mov     [ebx + device.pci_bus], ecx
3545 hidnplayr 389
        movzx   ecx, byte[eax+2]
4580 hidnplayr 390
        mov     [ebx + device.pci_dev], ecx
3545 hidnplayr 391
 
392
; Now, it's time to find the base io addres of the PCI device
393
 
4580 hidnplayr 394
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
395
        mov     [ebx + device.io_addr], eax
3545 hidnplayr 396
 
397
; We've found the io address, find IRQ now
398
 
4580 hidnplayr 399
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
400
        mov     [ebx + device.irq_line], al
3545 hidnplayr 401
 
4580 hidnplayr 402
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
403
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:8
3545 hidnplayr 404
 
405
; Ok, the eth_device structure is ready, let's probe the device
406
; Because initialization fires IRQ, IRQ handler must be aware of this device
407
        mov     eax, [devices]                                          ; Add the device structure to our device list
408
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
409
        inc     [devices]                                               ;
410
 
411
        call    probe                                                   ; this function will output in eax
412
        test    eax, eax
413
        jnz     .err2                                                   ; If an error occured, exit
414
 
4580 hidnplayr 415
        mov     [ebx + device.type], NET_TYPE_ETH
416
        invoke  NetRegDev
3545 hidnplayr 417
 
418
        cmp     eax, -1
419
        je      .destroy
420
 
421
        ret
422
 
423
; If the device was already loaded, find the device number and return it in eax
424
 
425
  .find_devicenum:
426
        DEBUGF  2,"Trying to find device number of already registered device\n"
4580 hidnplayr 427
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
3545 hidnplayr 428
                                                                        ; into a device number in edi
429
        mov     eax, edi                                                ; Application wants it in eax instead
430
        DEBUGF  2,"Kernel says: %u\n", eax
431
        ret
432
 
433
; If an error occured, remove all allocated data and exit (returning -1 in eax)
434
 
435
  .destroy:
436
        ; todo: reset device into virgin state
437
 
438
  .err2:
439
        dec     [devices]
440
  .err:
441
        DEBUGF  2,"removing device structure\n"
4580 hidnplayr 442
        invoke  KernelFree, ebx
3545 hidnplayr 443
  .fail:
444
        or      eax, -1
445
        ret
446
 
447
;------------------------------------------------------
448
endp
449
 
450
 
451
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
452
;;                                                                        ;;
453
;;        Actual Hardware dependent code starts here                      ;;
454
;;                                                                        ;;
455
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
456
 
457
 
458
 
459
align 4
460
unload:
461
        ; TODO: (in this particular order)
462
        ;
463
        ; - Stop the device
464
 
465
;    /* Disable Tx Rx*/
466
;    outl( mtdx.crvalue & (~TxEnable) & (~RxEnable), mtdx.ioaddr + TCRRCR );
467
;
468
;    /* Reset the chip to erase previous misconfiguration. */
469
;    mtd_reset(nic);
470
 
471
        ; - Detach int handler
472
        ; - Remove device from local list (device_list)
473
        ; - call unregister function in kernel
474
        ; - Remove all allocated structures and buffers the card used
475
 
4580 hidnplayr 476
        or      eax, -1
3545 hidnplayr 477
 
478
ret
479
 
480
 
481
;-------
482
;
483
; PROBE
484
;
485
;-------
486
align 4
487
probe:
488
 
4580 hidnplayr 489
        DEBUGF  1,"Probing\n"
3545 hidnplayr 490
 
4580 hidnplayr 491
; Make the device a bus master
492
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
493
        or      al, PCI_CMD_MASTER
494
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
3545 hidnplayr 495
 
4580 hidnplayr 496
; Check vendor/device id's
497
        invoke PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], 0
3545 hidnplayr 498
        cmp     ax, 0x1516
499
        jne     .notfound
500
        shr     eax, 16
4580 hidnplayr 501
        mov     [ebx + device.dev_id], ax
3545 hidnplayr 502
        cmp     ax, 0x0800
4580 hidnplayr 503
        je      .mtd800
3545 hidnplayr 504
        cmp     ax, 0x0803
4580 hidnplayr 505
        je      .mtd803
3545 hidnplayr 506
        cmp     ax, 0x0891
4580 hidnplayr 507
        je      .mtd891
3545 hidnplayr 508
 
509
  .notfound:
4580 hidnplayr 510
        DEBUGF  2,"Device not supported!\n"
3545 hidnplayr 511
        xor     eax, eax
512
        dec     eax
513
        ret
514
 
4580 hidnplayr 515
  .mtd803:
516
        mov     [ebx + device.name], sz_mtd803
3545 hidnplayr 517
        DEBUGF  1,"Device has chip xcvr\n"
4580 hidnplayr 518
        jmp     .xcvr_set
3545 hidnplayr 519
 
4580 hidnplayr 520
  .mtd800:
521
        DEBUGF  1,"Device has mii xcvr\n"
522
        mov     [ebx + device.name], sz_mtd800
3545 hidnplayr 523
        jmp     .xcvr_set
524
 
4580 hidnplayr 525
  .mtd891:
3545 hidnplayr 526
        DEBUGF  1,"Device has mii xcvr\n"
4580 hidnplayr 527
        mov     [ebx + device.name], sz_mtd800
3545 hidnplayr 528
 
529
  .xcvr_set:
530
        call    read_mac
531
 
532
; Reset the chip to erase previous misconfiguration.
4580 hidnplayr 533
        set_io  [ebx + device.io_addr], 0
534
        set_io  [ebx + device.io_addr], BCR
3545 hidnplayr 535
        xor     eax, eax
536
        inc     eax
537
        out     dx, eax
538
 
539
; find the connected MII xcvrs
4580 hidnplayr 540
        cmp     [ebx + device.dev_id], 0x0803
3545 hidnplayr 541
        je      .is_803
542
 
543
;        int     phy, phy_idx =   0;
544
;
545
;        for (phy =   1; phy < 32 && phy_idx < 1; phy++) {
546
;            int mii_status =   mdio_read(nic, phy, 1);
547
;
548
;            if (mii_status !=   0xffff && mii_status !=   0x0000) {
549
;                mtdx.phys[phy_idx] =   phy;
550
;
551
;                DBG ( "%s: MII PHY found at address %d, status "
552
;                      "0x%4.4x.\n", mtdx.nic_name, phy, mii_status );
553
;                /* get phy type */
554
;                {
555
;                    unsigned int data;
556
;
557
;                    data =   mdio_read(nic, mtdx.phys[phy_idx], 2);
558
;                    if (data equ=   SeeqPHYID0)
559
;                        mtdx.PHYType =   SeeqPHY;
560
;                    else if (data equ=   AhdocPHYID0)
561
;                        mtdx.PHYType =   AhdocPHY;
562
;                    else if (data equ=   MarvellPHYID0)
563
;                        mtdx.PHYType =   MarvellPHY;
564
;                    else if (data equ=   MysonPHYID0)
565
;                        mtdx.PHYType =   Myson981;
566
;                    else if (data equ=   LevelOnePHYID0)
567
;                        mtdx.PHYType =   LevelOnePHY;
568
;                    else
569
;                        mtdx.PHYType =   OtherPHY;
570
;                }
571
;                phy_idx++;
572
;            }
573
;        }
574
;
575
;        mtdx.mii_cnt =   phy_idx;
576
;        if (phy_idx equ=   0) {
577
;            printf("%s: MII PHY not found -- this device may "
578
;                   "not operate correctly.\n", mtdx.nic_name);
579
;        }
580
 
581
        jmp     .no_803
582
 
583
  .is_803:
4580 hidnplayr 584
        mov     [ebx + device.phys], 32
3545 hidnplayr 585
 
586
; get phy type
4580 hidnplayr 587
        set_io  [ebx + device.io_addr], 0
588
        set_io  [ebx + device.io_addr], PHYIDENTIFIER
3545 hidnplayr 589
        in      eax, dx
590
 
591
        cmp     eax, MysonPHYID
592
        jne     @f
4580 hidnplayr 593
        mov     [ebx + device.PHYType], MysonPHY
594
        DEBUGF  1,"Myson PHY\n"
3545 hidnplayr 595
        jmp     .no_803
596
       @@:
597
 
4580 hidnplayr 598
        mov     [ebx + device.PHYType], OtherPHY
599
        DEBUGF  1,"Other PHY\n"
3545 hidnplayr 600
  .no_803:
601
 
602
;-------
603
;
604
; RESET
605
;
606
;-------
607
align 4
608
reset:
609
 
4470 hidnplayr 610
        DEBUGF  1,"Resetting\n"
3545 hidnplayr 611
 
4580 hidnplayr 612
; attach irq handler
613
        movzx   eax, [ebx + device.irq_line]
3545 hidnplayr 614
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
4580 hidnplayr 615
        invoke  AttachIntHandler, eax, int_handler, ebx
3545 hidnplayr 616
        test    eax, eax
617
        jnz     @f
4580 hidnplayr 618
        DEBUGF  2,"Could not attach int handler!\n"
4576 hidnplayr 619
        or      eax, -1
620
        ret
3545 hidnplayr 621
  @@:
622
 
623
; Reset the chip to erase previous misconfiguration.
4580 hidnplayr 624
        set_io  [ebx + device.io_addr], 0
625
        set_io  [ebx + device.io_addr], BCR
3545 hidnplayr 626
        xor     eax, eax
627
        inc     eax
628
        out     dx, eax
629
 
630
        call    init_ring
631
 
632
; Initialize other registers.
633
; Configure the PCI bus bursts and FIFO thresholds.
4580 hidnplayr 634
        mov     [ebx + device.bcrvalue], 0x10         ; little-endian, 8 burst length
635
        mov     [ebx + device.crvalue], 0xa00         ; 128 burst length
3545 hidnplayr 636
 
4580 hidnplayr 637
        cmp     [ebx + device.dev_id], 0x891
3545 hidnplayr 638
        jne     @f
4580 hidnplayr 639
        or      [ebx + device.bcrvalue], 0x200       ; set PROG bit
640
        or      [ebx + device.crvalue], 0x02000000   ; set enhanced bit
3545 hidnplayr 641
       @@:
4580 hidnplayr 642
        or      [ebx + device.crvalue], RxEnable + TxThreshold + TxEnable
3545 hidnplayr 643
 
644
        call    set_rx_mode
645
 
4580 hidnplayr 646
        set_io  [ebx + device.io_addr], 0
647
        set_io  [ebx + device.io_addr], BCR
648
        mov     eax, [ebx + device.bcrvalue]
3545 hidnplayr 649
        out     dx, eax
650
 
4580 hidnplayr 651
        set_io  [ebx + device.io_addr], TCRRCR
652
        mov     eax, [ebx + device.crvalue]
3545 hidnplayr 653
        out     dx, eax
654
 
655
        call    getlinkstatus
656
 
657
; Restart Rx engine if stopped.
4580 hidnplayr 658
        set_io  [ebx + device.io_addr], 0
659
        set_io  [ebx + device.io_addr], RXPDR
3545 hidnplayr 660
        xor     eax, eax
661
        out     dx, eax
662
 
663
; Enable interrupts
4580 hidnplayr 664
        set_io  [ebx + device.io_addr], ISR
4576 hidnplayr 665
        mov     eax, FBE or TUNF or CNTOVF or RBU or TI or RI
3545 hidnplayr 666
        out     dx, eax
4580 hidnplayr 667
        set_io  [ebx + device.io_addr], IMR
3545 hidnplayr 668
        out     dx, eax
669
 
670
; clear packet/byte counters
671
        xor     eax, eax
4580 hidnplayr 672
        lea     edi, [ebx + device.bytes_tx]
3545 hidnplayr 673
        mov     ecx, 6
674
        rep     stosd
675
 
4580 hidnplayr 676
        mov     [ebx + device.mtu], 1514
3545 hidnplayr 677
        xor     eax, eax
678
        ret
679
 
680
 
681
 
682
 
683
align 4
684
init_ring:
685
 
686
        DEBUGF  1,"initializing rx and tx ring\n"
687
 
688
; Initialize all Rx descriptors
4580 hidnplayr 689
        lea     esi, [ebx + device.rx_desc]
690
        mov     [ebx + device.cur_rx], esi
3545 hidnplayr 691
        mov     ecx, NUM_RX_DESC
692
  .rx_desc_loop:
4580 hidnplayr 693
        mov     [esi + descriptor.status], RXOWN
694
        mov     [esi + descriptor.control], 1536 shl RBSShift
3545 hidnplayr 695
 
4580 hidnplayr 696
        lea     eax, [esi + sizeof.descriptor]
697
        mov     [esi + descriptor.next_desc_logical], eax
3545 hidnplayr 698
        push    ecx esi
4580 hidnplayr 699
        invoke  GetPhysAddr
700
        mov     [esi + descriptor.next_desc], eax
3545 hidnplayr 701
 
4580 hidnplayr 702
        invoke  KernelAlloc, 1536
3545 hidnplayr 703
        pop     esi
704
        push    esi
4580 hidnplayr 705
        mov     [esi + descriptor.skbuff], eax
706
        invoke  GetPgAddr
3545 hidnplayr 707
        pop     esi ecx
4580 hidnplayr 708
        mov     [esi + descriptor.buffer], eax
3545 hidnplayr 709
 
4580 hidnplayr 710
        add     esi, sizeof.descriptor
3545 hidnplayr 711
        loop    .rx_desc_loop
712
 
713
; Mark the last entry as wrapping the ring.
4580 hidnplayr 714
        lea     eax, [ebx + device.rx_desc]
715
        mov     [esi - sizeof.descriptor + descriptor.next_desc_logical], eax
3545 hidnplayr 716
        push    esi
4580 hidnplayr 717
        invoke  GetPhysAddr
3545 hidnplayr 718
        pop     esi
4580 hidnplayr 719
        mov     [esi - sizeof.descriptor + descriptor.next_desc], eax
3545 hidnplayr 720
 
4580 hidnplayr 721
        set_io  [ebx + device.io_addr],   0
722
        set_io  [ebx + device.io_addr],   RXLBA
3545 hidnplayr 723
        out     dx, eax
724
 
725
; Initialize all Tx descriptors
4580 hidnplayr 726
        lea     esi, [ebx + device.tx_desc]
727
        mov     [ebx + device.cur_tx], esi
3545 hidnplayr 728
        mov     ecx, NUM_TX_DESC
729
  .tx_desc_loop:
4580 hidnplayr 730
        mov     [esi + descriptor.status], 0
3545 hidnplayr 731
 
4580 hidnplayr 732
        lea     eax, [esi + sizeof.descriptor]
733
        mov     [esi + descriptor.next_desc_logical], eax
3545 hidnplayr 734
        push    ecx esi
4580 hidnplayr 735
        invoke  GetPhysAddr
3545 hidnplayr 736
        pop     esi ecx
4580 hidnplayr 737
        mov     [esi + descriptor.next_desc], eax
738
        mov     [esi + descriptor.skbuff], 0
739
        add     esi, sizeof.descriptor
3545 hidnplayr 740
        loop    .tx_desc_loop
741
 
742
; Mark the last entry as wrapping the ring.
4580 hidnplayr 743
        lea     eax, [ebx + device.tx_desc]
744
        mov     [esi - sizeof.descriptor + descriptor.next_desc_logical], eax
3545 hidnplayr 745
        push    esi
4580 hidnplayr 746
        invoke  GetPhysAddr
3545 hidnplayr 747
        pop     esi
4580 hidnplayr 748
        mov     [esi - sizeof.descriptor + descriptor.next_desc], eax
3545 hidnplayr 749
 
4580 hidnplayr 750
        set_io  [ebx + device.io_addr],   0
751
        set_io  [ebx + device.io_addr],   TXLBA
3545 hidnplayr 752
        out     dx, eax
753
 
754
        ret
755
 
756
 
757
align 4
758
set_rx_mode:
759
 
760
        DEBUGF  1,"Setting RX mode\n"
761
 
762
; Too many to match, or accept all multicasts.
4580 hidnplayr 763
        set_io  [ebx + device.io_addr], 0
764
        set_io  [ebx + device.io_addr], MAR0
3545 hidnplayr 765
        xor     eax, eax
766
        not     eax
767
        out     dx, eax
4580 hidnplayr 768
        set_io  [ebx + device.io_addr], MAR1
3545 hidnplayr 769
        out     dx, eax
770
 
4580 hidnplayr 771
        and     [ebx + device.crvalue], not (RxModeMask)
772
        or      [ebx + device.crvalue], AcceptBroadcast + AcceptMulticast + AcceptMyPhys
3545 hidnplayr 773
 
774
        ret
775
 
776
 
777
align 4
778
getlinkstatus:
779
 
780
        DEBUGF  1,"Getting link status\n"
781
 
4580 hidnplayr 782
        mov     [ebx + device.state], ETH_LINK_DOWN     ; assume link is dead
3545 hidnplayr 783
 
4580 hidnplayr 784
        cmp     [ebx + device.PHYType], MysonPHY
3545 hidnplayr 785
        jne     .no_myson_phy
4580 hidnplayr 786
        set_io  [ebx + device.io_addr], 0
787
        set_io  [ebx + device.io_addr], BMCRSR
3545 hidnplayr 788
        in      eax, dx
789
        test    eax, LinkIsUp2
4580 hidnplayr 790
        jnz     getlinktype
3545 hidnplayr 791
        ret
792
 
793
  .no_myson_phy:
4580 hidnplayr 794
        set_io  [ebx + device.io_addr], 0
795
        set_io  [ebx + device.io_addr], BMCRSR
796
        in      eax, dx
797
        test    eax, LinkIsUp
798
        jnz     getlinktype
3545 hidnplayr 799
        ret
800
 
801
getlinktype:
802
 
803
        DEBUGF  1,"Getting link type\n"
4580 hidnplayr 804
        cmp     [ebx + device.PHYType], MysonPHY
3545 hidnplayr 805
        jne     .no_myson_phy
806
 
807
        DEBUGF  1,"myson PHY\n"
4580 hidnplayr 808
        set_io  [ebx + device.io_addr], 0
809
        set_io  [ebx + device.io_addr], TCRRCR
3545 hidnplayr 810
        in      eax, dx
811
        test    eax, FD
4580 hidnplayr 812
        jz      @f
3545 hidnplayr 813
        DEBUGF  1,"full duplex\n"
4580 hidnplayr 814
        or      [ebx + device.state], ETH_LINK_FD
3545 hidnplayr 815
       @@:
816
        test    eax, PS10
4580 hidnplayr 817
        jnz     @f
3545 hidnplayr 818
        DEBUGF  1,"100mbit\n"
4580 hidnplayr 819
        or      [ebx + device.state], ETH_LINK_100M
820
        ret
3545 hidnplayr 821
       @@:
4580 hidnplayr 822
        DEBUGF  1,"10mbit\n"
823
        or      [ebx + device.state], ETH_LINK_10M
3545 hidnplayr 824
        ret
825
 
826
  .no_myson_phy:
4580 hidnplayr 827
        DEBUGF  1,"not a myson PHY\n"
828
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
3545 hidnplayr 829
 
830
;        if (mtdx.PHYType equ=   SeeqPHY) { /* this PHY is SEEQ 80225 */
831
;            unsigned int data;
832
;
833
;            data =   mdio_read(dev, mtdx.phys[0], MIIRegister18);
834
;            if (data & SPD_DET_100)
835
;                mtdx.line_speed =   2; /* 100M */
836
;            else
837
;                mtdx.line_speed =   1; /* 10M */
838
;            if (data & DPLX_DET_FULL)
839
;                mtdx.duplexmode =   2; /* full duplex mode */
840
;            else
841
;                mtdx.duplexmode =   1; /* half duplex mode */
842
;        } else if (mtdx.PHYType equ=   AhdocPHY) {
843
;            unsigned int data;
844
;
845
;            data =   mdio_read(dev, mtdx.phys[0], DiagnosticReg);
846
;            if (data & Speed_100)
847
;                mtdx.line_speed =   2; /* 100M */
848
;            else
849
;                mtdx.line_speed =   1; /* 10M */
850
;            if (data & DPLX_FULL)
851
;                mtdx.duplexmode =   2; /* full duplex mode */
852
;            else
853
;                mtdx.duplexmode =   1; /* half duplex mode */
854
;        }
855
;        else if (mtdx.PHYType equ=   MarvellPHY) {
856
;            unsigned int data;
857
;
858
;            data =   mdio_read(dev, mtdx.phys[0], SpecificReg);
859
;            if (data & Full_Duplex)
860
;                mtdx.duplexmode =   2; /* full duplex mode */
861
;            else
862
;                mtdx.duplexmode =   1; /* half duplex mode */
863
;            data &=   SpeedMask;
864
;            if (data equ=   Speed_1000M)
865
;                mtdx.line_speed =   3; /* 1000M */
866
;            else if (data equ=   Speed_100M)
867
;                mtdx.line_speed =   2; /* 100M */
868
;            else
869
;                mtdx.line_speed =   1; /* 10M */
870
;        }
871
;        else if (mtdx.PHYType equ=   Myson981) {
872
;            unsigned int data;
873
;
874
;            data =   mdio_read(dev, mtdx.phys[0], StatusRegister);
875
;
876
;            if (data & SPEED100)
877
;                mtdx.line_speed =   2;
878
;            else
879
;                mtdx.line_speed =   1;
880
;
881
;            if (data & FULLMODE)
882
;                mtdx.duplexmode =   2;
883
;            else
884
;                mtdx.duplexmode =   1;
885
;        }
886
;        else if (mtdx.PHYType equ=   LevelOnePHY) {
887
;            unsigned int data;
888
;
889
;            data =   mdio_read(dev, mtdx.phys[0], SpecificReg);
890
;            if (data & LXT1000_Full)
891
;                mtdx.duplexmode =   2; /* full duplex mode */
892
;            else
893
;                mtdx.duplexmode =   1; /* half duplex mode */
894
;            data &=   SpeedMask;
895
;            if (data equ=   LXT1000_1000M)
896
;                mtdx.line_speed =   3; /* 1000M */
897
;            else if (data equ=   LXT1000_100M)
898
;                mtdx.line_speed =   2; /* 100M */
899
;            else
900
 ;               mtdx.line_speed =   1; /* 10M */
901
  ;      }
902
 
903
;        // chage crvalue
904
;        // mtdx.crvalue&equ(~PS10)&(~FD);
905
;        mtdx.crvalue &=   (~PS10) & (~FD) & (~PS1000);
906
;        if (mtdx.line_speed equ=   1)
907
;            mtdx.crvalue |=   PS10;
908
;        else if (mtdx.line_speed equ=   3)
909
;            mtdx.crvalue |=   PS1000;
910
;        if (mtdx.duplexmode equ=   2)
911
;            mtdx.crvalue |=   FD;
912
 
913
        ret
914
 
915
 
916
 
917
 
918
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
919
;;                                         ;;
920
;; Transmit                                ;;
921
;;                                         ;;
922
;; In: buffer pointer in [esp+4]           ;;
923
;;     size of buffer in [esp+8]           ;;
924
;;     pointer to device structure in ebx  ;;
925
;;                                         ;;
926
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
927
 
4580 hidnplayr 928
proc transmit stdcall bufferptr, buffersize
3545 hidnplayr 929
 
4580 hidnplayr 930
        pushf
931
        cli
932
 
933
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
934
        mov     eax, [bufferptr]
3545 hidnplayr 935
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
936
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
937
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
938
        [eax+13]:2,[eax+12]:2
939
 
4580 hidnplayr 940
        cmp     [buffersize], 1514
3545 hidnplayr 941
        ja      .fail
4580 hidnplayr 942
        cmp     [buffersize], 60
943
        jb      .fail
3545 hidnplayr 944
 
4580 hidnplayr 945
        mov     esi, [ebx + device.cur_tx]
4576 hidnplayr 946
 
4580 hidnplayr 947
        test    [esi + descriptor.status], TXOWN
4576 hidnplayr 948
        jnz     .fail
949
 
4580 hidnplayr 950
        push    [esi + descriptor.next_desc_logical]
951
        pop     [ebx + device.cur_tx]
3545 hidnplayr 952
 
4580 hidnplayr 953
        mov     eax, [bufferptr]
954
        mov     [esi + descriptor.skbuff], eax
955
        invoke  GetPhysAddr
956
        mov     [esi + descriptor.buffer], eax
3545 hidnplayr 957
 
4580 hidnplayr 958
        mov     eax, [buffersize]
4576 hidnplayr 959
        mov     ecx, eax
3545 hidnplayr 960
        shl     eax, PKTSShift               ; packet size
4576 hidnplayr 961
        shl     ecx, TBSShift
962
        or      eax, ecx
963
        or      eax, TXIC + TXLD + TXFD + CRCEnable + PADEnable
4580 hidnplayr 964
        mov     [esi + descriptor.control], eax
965
        mov     [esi + descriptor.status], TXOWN
3545 hidnplayr 966
 
967
; Update stats
4580 hidnplayr 968
        inc     [ebx + device.packets_tx]
969
        mov     eax, [buffersize]
970
        add     dword[ebx + device.bytes_tx], eax
971
        adc     dword[ebx + device.bytes_tx + 4], 0
3545 hidnplayr 972
 
4576 hidnplayr 973
; TX Poll
4580 hidnplayr 974
        set_io  [ebx + device.io_addr], 0
975
        set_io  [ebx + device.io_addr], TXPDR
3545 hidnplayr 976
        xor     eax, eax
977
        out     dx, eax
978
 
4580 hidnplayr 979
        DEBUGF  1,"Transmit OK\n"
980
        popf
3545 hidnplayr 981
        xor     eax, eax
4580 hidnplayr 982
        ret
3545 hidnplayr 983
 
984
  .fail:
4580 hidnplayr 985
        DEBUGF  2,"Transmit failed\n"
986
        invoke  KernelFree, [bufferptr]
987
        popf
3545 hidnplayr 988
        or      eax, -1
4580 hidnplayr 989
        ret
3545 hidnplayr 990
 
4580 hidnplayr 991
endp
3545 hidnplayr 992
 
993
 
4580 hidnplayr 994
 
3545 hidnplayr 995
align 4
996
read_mac:
997
 
4580 hidnplayr 998
        set_io  [ebx + device.io_addr], 0
999
        set_io  [ebx + device.io_addr], PAR0
1000
        lea     edi, [ebx + device.mac]
3545 hidnplayr 1001
        insd
4580 hidnplayr 1002
        set_io  [ebx + device.io_addr], PAR1
3545 hidnplayr 1003
        insw
1004
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n",\
4580 hidnplayr 1005
        [ebx + device.mac+0]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,[ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
3545 hidnplayr 1006
 
1007
        ret
1008
 
1009
align 4
1010
write_mac:
1011
 
1012
        ret
1013
 
1014
 
1015
 
1016
;;;;;;;;;;;;;;;;;;;;;;;
1017
;;                   ;;
1018
;; Interrupt handler ;;
1019
;;                   ;;
1020
;;;;;;;;;;;;;;;;;;;;;;;
1021
 
1022
align 4
1023
int_handler:
1024
 
1025
        push    ebx esi edi
1026
 
4576 hidnplayr 1027
        DEBUGF  1,"INT\n"
3545 hidnplayr 1028
 
1029
; find pointer of device wich made IRQ occur
1030
 
1031
        mov     ecx, [devices]
1032
        test    ecx, ecx
1033
        jz      .nothing
1034
        mov     esi, device_list
1035
  .nextdevice:
1036
        mov     ebx, [esi]
1037
 
4580 hidnplayr 1038
        set_io  [ebx + device.io_addr], 0
1039
        set_io  [ebx + device.io_addr], ISR
3545 hidnplayr 1040
        in      eax, dx
1041
        out     dx, eax                                 ; send it back to ACK
1042
        test    eax, eax
1043
        jnz     .got_it
1044
  .continue:
1045
        add     esi, 4
1046
        dec     ecx
1047
        jnz     .nextdevice
1048
  .nothing:
1049
        pop     edi esi ebx
1050
        xor     eax, eax
1051
 
1052
        ret                                             ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
1053
 
1054
  .got_it:
1055
 
4470 hidnplayr 1056
        DEBUGF  1,"Device: %x Status: %x\n", ebx, ax
3545 hidnplayr 1057
 
1058
        test    ax, RI  ; receive interrupt
1059
        jz      .no_rx
1060
        push    ax
1061
  .rx_loop:
4580 hidnplayr 1062
        mov     esi, [ebx + device.cur_rx]
1063
        test    [esi + descriptor.status], RXOWN
1064
        jnz     .rx_done
3545 hidnplayr 1065
 
4576 hidnplayr 1066
        push    ebx
3545 hidnplayr 1067
        push    .rx_complete
1068
 
4580 hidnplayr 1069
        mov     ecx, [esi + descriptor.status]
3545 hidnplayr 1070
        shr     ecx, FLNGShift
1071
        sub     ecx, 4                  ; we dont need CRC
1072
        push    ecx
4576 hidnplayr 1073
        DEBUGF  1,"Received %u bytes\n", ecx
3545 hidnplayr 1074
 
1075
; Update stats
4580 hidnplayr 1076
        add     dword[ebx + device.bytes_rx], ecx
1077
        adc     dword[ebx + device.bytes_rx + 4], 0
1078
        inc     [ebx + device.packets_rx]
3545 hidnplayr 1079
 
4580 hidnplayr 1080
        push    [esi + descriptor.skbuff]
1081
        jmp     [Eth_input]
3545 hidnplayr 1082
 
1083
  .rx_complete:
4576 hidnplayr 1084
        pop     ebx
4580 hidnplayr 1085
        mov     esi, [ebx + device.cur_rx]
1086
        mov     [esi + descriptor.control], 1536 shl RBSShift
4576 hidnplayr 1087
        push    esi
4580 hidnplayr 1088
        invoke  KernelAlloc, 1536
4576 hidnplayr 1089
        pop     esi
4580 hidnplayr 1090
        mov     [esi + descriptor.skbuff], eax
1091
        invoke  GetPgAddr
1092
        mov     [esi + descriptor.buffer], eax
1093
        mov     [esi + descriptor.status], RXOWN
3545 hidnplayr 1094
 
4580 hidnplayr 1095
        push    [esi + descriptor.next_desc_logical]
1096
        pop     [ebx + device.cur_rx]
3545 hidnplayr 1097
 
1098
        jmp     .rx_loop
1099
 
4580 hidnplayr 1100
  .rx_done:
4576 hidnplayr 1101
        DEBUGF  1,"RX done\n"
4580 hidnplayr 1102
 
1103
; Restart Rx engine if stopped.
1104
        set_io  [ebx + device.io_addr], 0
1105
        set_io  [ebx + device.io_addr], RXPDR
1106
        xor     eax, eax
1107
        out     dx, eax
1108
 
4576 hidnplayr 1109
        pop     ax
4580 hidnplayr 1110
  .no_rx:
3545 hidnplayr 1111
 
1112
        test    ax, TI ; transmit interrupt
1113
        jz      .no_tx
4576 hidnplayr 1114
        DEBUGF  1,"TX\n"
3545 hidnplayr 1115
        push    ax
4580 hidnplayr 1116
        lea     esi, [ebx + device.tx_desc]
3545 hidnplayr 1117
        mov     ecx, NUM_TX_DESC
1118
  .tx_loop:
4580 hidnplayr 1119
        test    [esi + descriptor.status], TXOWN
3545 hidnplayr 1120
        jnz     .skip_this_one
4580 hidnplayr 1121
        mov     eax, [esi + descriptor.skbuff]
3545 hidnplayr 1122
        test    eax, eax
1123
        je      .skip_this_one
4580 hidnplayr 1124
        mov     [esi + descriptor.skbuff], 0
4576 hidnplayr 1125
        DEBUGF  1,"freeing buffer: 0x%x\n", eax
4580 hidnplayr 1126
        invoke  KernelFree, eax
3545 hidnplayr 1127
  .skip_this_one:
4580 hidnplayr 1128
        mov     esi, [esi + descriptor.next_desc_logical]
3545 hidnplayr 1129
        loop    .tx_loop
1130
        pop     ax
4580 hidnplayr 1131
  .no_tx:
3545 hidnplayr 1132
 
4580 hidnplayr 1133
        test    ax, LSCStatus
1134
        jz      .no_link_change
1135
        push    ax
1136
        call    getlinkstatus
1137
        pop     ax
1138
  .no_link_change:
1139
 
4576 hidnplayr 1140
;        test    ax, TBU
1141
;        jz      .no_tbu
1142
;        DEBUGF  2,"Transmit buffer unavailable!\n"
1143
;  .no_tbu:
3545 hidnplayr 1144
 
1145
  .fail:
1146
        pop     edi esi ebx
1147
        xor     eax, eax
1148
        inc     eax
1149
 
1150
        ret
1151
 
1152
 
1153
; End of code
1154
 
1155
 
4580 hidnplayr 1156
data fixups
1157
end data
3545 hidnplayr 1158
 
4580 hidnplayr 1159
include '../peimport.inc'
3545 hidnplayr 1160
 
4580 hidnplayr 1161
my_service      db 'mtd80x',0                   ; max 16 chars include zero
3545 hidnplayr 1162
 
4580 hidnplayr 1163
sz_mtd800       db "Myson MTD800", 0
1164
sz_mtd803       db "Surecom EP-320X", 0
1165
sz_mtd891       db "Myson MTD891", 0
3545 hidnplayr 1166
 
4580 hidnplayr 1167
 
3545 hidnplayr 1168
include_debug_strings                           ; All data wich FDO uses will be included here
1169
 
4580 hidnplayr 1170
align 4
1171
devices       dd 0
1172
device_list   rd MAX_DEVICES                    ; This list contains all pointers to device structures the driver is handling
3545 hidnplayr 1173