Subversion Repositories Kolibri OS

Rev

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

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