Subversion Repositories Kolibri OS

Rev

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