Subversion Repositories Kolibri OS

Rev

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

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