Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1472 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
1519 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
1472 hidnplayr 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
1519 hidnplayr 6
;;  3Com network driver for KolibriOS                           ;;
7
;;                                                              ;;
8
;;  Ported to KolibriOS net-branch by hidnplayr (28/05/10)      ;;
9
;;                                                              ;;
10
;;  Thanks to: scrap metal recyclers, whom provide me with      ;;
11
;;                         loads of hardware                    ;;
12
;;             diamond: who makes me understand KolibriOS       ;;
13
;;                                                              ;;
1472 hidnplayr 14
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15
 
16
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17
;;                                                                         ;;
18
;;  3C59X.INC                                                              ;;
19
;;                                                                         ;;
20
;;  Ethernet driver for Menuet OS                                          ;;
21
;;                                                                         ;;
22
;;  Driver for 3Com fast etherlink 3c59x and                               ;;
23
;;         etherlink XL 3c900 and 3c905 cards                              ;;
24
;;  References:                                                            ;;
25
;;    www.3Com.com - data sheets                                           ;;
26
;;    DP83840A.pdf - ethernet physical layer                               ;;
27
;;    3c59x.c - linux driver                                               ;;
28
;;    ethernet driver template by Mike Hibbett                             ;;
29
;;                                                                         ;;
30
;;  Credits                                                                ;;
31
;;   Mike Hibbett,                                                         ;;
32
;;         who kindly supplied me with a 3Com905C-TX-M card                ;;
33
;;                                                                         ;;
34
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
35
;;
36
;; Copyright (c) 2004, Endre Kozma 
37
;; All rights reserved.
38
;;
39
;; Redistribution  and  use  in  source  and  binary  forms, with or without
40
;; modification, are permitted provided  that  the following  conditions are
41
;; met:
42
;;
43
;; 1. Redistributions of source code must retain the above  copyright notice,
44
;;    this list of conditions and the following disclaimer.
45
;;
46
;; 2. Redistributions  in  binary form  must  reproduce  the above copyright
47
;;    notice, this  list of conditions  and the  following disclaimer in the
48
;;    documentation and/or other  materials  provided with  the distribution.
49
;;
50
;; 3. The name of the author may not be used to  endorse or promote products
51
;;    derived from this software without  specific prior  written permission.
52
;;
53
;; THIS SOFTWARE IS  PROVIDED  BY  THE  AUTHOR  ``AS IS'' AND ANY EXPRESS OR
54
;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
55
;; OF  MERCHANTABILITY AND FITNESS  FOR A PARTICULAR  PURPOSE ARE DISCLAIMED.
56
;; IN  NO  EVENT  SHALL  THE  AUTHOR  BE  LIABLE  FOR  ANY  DIRECT, INDIRECT,
57
;; INCIDENTAL, SPECIAL, EXEMPLARY, OR  CONSEQUENTIAL DAMAGES (INCLUDING, BUT
58
;; NOT LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
59
;; DATA, OR  PROFITS; OR  BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON ANY
60
;; THEORY OF  LIABILITY, WHETHER IN  CONTRACT,  STRICT  LIABILITY,  OR  TORT
61
;; (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY WAY OUT OF THE USE OF
62
;; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63
;;
64
;;  History
65
;;  =======
66
;;  $Log: 3C59X.INC,v $
67
;;  Revision 1.3  2004/07/11 12:21:12  kozma
68
;;  Support of vortex chips (3c59x) added.
69
;;  Support of 3c920 and 3c982 added.
70
;;  Corrections.
71
;;
72
;;  Revision 1.2  2004/06/12 19:40:20  kozma
73
;;  Function e3c59x_set_available_media added in order to set
74
;;  the default media in case auto detection finds no valid link.
75
;;  Incorrect mii check removed (3c900 Cyclone works now).
76
;;  Cleanups.
77
;;
78
;;  Revision 1.1  2004/06/12 18:27:15  kozma
79
;;  Initial revision
80
;;
81
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
82
 
83
format MS COFF
84
 
2387 hidnplayr 85
        API_VERSION             equ 0x01000100
86
        DRIVER_VERSION          equ 5
1472 hidnplayr 87
 
2387 hidnplayr 88
        MAX_DEVICES             equ 16
89
        FORCE_FD                equ 0  ; forcing full duplex mode makes sense at some cards and link types
90
        PROMISCIOUS             equ 0  ; enables promiscous mode
1519 hidnplayr 91
 
2387 hidnplayr 92
        DEBUG                   equ 1
93
        __DEBUG__               equ 1
94
        __DEBUG_LEVEL__         equ 1
1472 hidnplayr 95
 
96
include 'proc32.inc'
97
include 'imports.inc'
98
include 'fdo.inc'
99
include 'netdrv.inc'
100
 
101
public START
102
public service_proc
103
public version
104
 
2387 hidnplayr 105
struc DPD {     ; Download Packet Descriptor
1472 hidnplayr 106
 
2387 hidnplayr 107
        .next_ptr         dd ?
108
        .frame_start_hdr  dd ?
109
        .frag_addr        dd ?    ; for packet data
110
        .frag_len         dd ?    ; for packet data
111
        .realaddr         dd ?
112
        .size             = 32
1472 hidnplayr 113
}
114
 
115
virtual at 0
116
  dpd DPD
117
end virtual
118
 
119
 
2387 hidnplayr 120
struc UPD {     ; Upload Packet Descriptor
1472 hidnplayr 121
 
2387 hidnplayr 122
        .next_ptr       dd ?
123
        .pkt_status     dd ?
124
        .frag_addr      dd ?
125
        .frag_len       dd ?    ; for packet data
126
        .realaddr       dd ?
127
        .size           = 32
1472 hidnplayr 128
 
129
}
130
 
131
virtual at 0
132
  upd UPD
133
end virtual
134
 
135
; Ethernet frame symbols
2387 hidnplayr 136
        ETH_ALEN                equ 6
137
        ETH_HLEN                equ (2*ETH_ALEN+2)
138
        ETH_ZLEN                equ 60 ; 60 + 4bytes auto payload for
139
                                              ; mininmum 64bytes frame length
1472 hidnplayr 140
; Registers
2387 hidnplayr 141
        REG_POWER_MGMT_CTRL     equ 0x7c
142
        REG_UP_LIST_PTR         equ 0x38
143
        REG_UP_PKT_STATUS       equ 0x30
144
        REG_TX_FREE_THRESH      equ 0x2f
145
        REG_DN_LIST_PTR         equ 0x24
146
        REG_DMA_CTRL            equ 0x20
147
        REG_TX_STATUS           equ 0x1b
148
        REG_RX_STATUS           equ 0x18
149
        REG_TX_DATA             equ 0x10
1519 hidnplayr 150
 
1472 hidnplayr 151
; Common window registers
2387 hidnplayr 152
        REG_INT_STATUS          equ 0xe
153
        REG_COMMAND             equ 0xe
1519 hidnplayr 154
 
1472 hidnplayr 155
; Register window 7
2387 hidnplayr 156
        REG_MASTER_STATUS       equ 0xc
157
        REG_POWER_MGMT_EVENT    equ 0xc
158
        REG_MASTER_LEN          equ 0x6
159
        REG_VLAN_ETHER_TYPE     equ 0x4
160
        REG_VLAN_MASK           equ 0x0
161
        REG_MASTER_ADDRESS      equ 0x0
1519 hidnplayr 162
 
1472 hidnplayr 163
; Register window 6
2387 hidnplayr 164
        REG_BYTES_XMITTED_OK    equ 0xc
165
        REG_BYTES_RCVD_OK       equ 0xa
166
        REG_UPPER_FRAMES_OK     equ 0x9
167
        REG_FRAMES_DEFERRED     equ 0x8
168
        REG_FRAMES_RCVD_OK      equ 0x7
169
        REG_FRAMES_XMITTED_OK   equ 0x6
170
        REG_RX_OVERRUNS         equ 0x5
171
        REG_LATE_COLLISIONS     equ 0x4
172
        REG_SINGLE_COLLISIONS   equ 0x3
173
        REG_MULTIPLE_COLLISIONS equ 0x2
174
        REG_SQE_ERRORS          equ 0x1
175
        REG_CARRIER_LOST        equ 0x0
1519 hidnplayr 176
 
1472 hidnplayr 177
; Register window 5
2387 hidnplayr 178
        REG_INDICATION_ENABLE   equ 0xc
179
        REG_INTERRUPT_ENABLE    equ 0xa
180
        REG_TX_RECLAIM_THRESH   equ 0x9
181
        REG_RX_FILTER           equ 0x8
182
        REG_RX_EARLY_THRESH     equ 0x6
183
        REG_TX_START_THRESH     equ 0x0
1519 hidnplayr 184
 
1472 hidnplayr 185
; Register window 4
2387 hidnplayr 186
        REG_UPPER_BYTES_OK      equ 0xe
187
        REG_BAD_SSD             equ 0xc
188
        REG_MEDIA_STATUS        equ 0xa
189
        REG_PHYSICAL_MGMT       equ 0x8
190
        REG_NETWORK_DIAGNOSTIC  equ 0x6
191
        REG_FIFO_DIAGNOSTIC     equ 0x4
192
        REG_VCO_DIAGNOSTIC      equ 0x2 ; may not supported
1519 hidnplayr 193
 
1472 hidnplayr 194
; Bits in register window 4
2387 hidnplayr 195
        BIT_AUTOSELECT          equ 24
1519 hidnplayr 196
 
1472 hidnplayr 197
; Register window 3
2387 hidnplayr 198
        REG_TX_FREE             equ 0xc
199
        REG_RX_FREE             equ 0xa
200
        REG_MEDIA_OPTIONS       equ 0x8
201
        REG_MAC_CONTROL         equ 0x6
202
        REG_MAX_PKT_SIZE        equ 0x4
203
        REG_INTERNAL_CONFIG     equ 0x0
1519 hidnplayr 204
 
1472 hidnplayr 205
; Register window 2
2387 hidnplayr 206
        REG_RESET_OPTIONS       equ 0xc
207
        REG_STATION_MASK_HI     equ 0xa
208
        REG_STATION_MASK_MID    equ 0x8
209
        REG_STATION_MASK_LO     equ 0x6
210
        REG_STATION_ADDRESS_HI  equ 0x4
211
        REG_STATION_ADDRESS_MID equ 0x2
212
        REG_STATION_ADDRESS_LO  equ 0x0
1519 hidnplayr 213
 
1472 hidnplayr 214
; Register window 1
2387 hidnplayr 215
        REG_TRIGGER_BITS        equ 0xc
216
        REG_SOS_BITS            equ 0xa
217
        REG_WAKE_ON_TIMER       equ 0x8
218
        REG_SMB_RXBYTES         equ 0x7
219
        REG_SMB_DIAG            equ 0x5
220
        REG_SMB_ARB             equ 0x4
221
        REG_SMB_STATUS          equ 0x2
222
        REG_SMB_ADDRESS         equ 0x1
223
        REG_SMB_FIFO_DATA       equ 0x0
1519 hidnplayr 224
 
1472 hidnplayr 225
; Register window 0
2387 hidnplayr 226
        REG_EEPROM_DATA         equ 0xc
227
        REG_EEPROM_COMMAND      equ 0xa
228
        REG_BIOS_ROM_DATA       equ 0x8
229
        REG_BIOS_ROM_ADDR       equ 0x4
1519 hidnplayr 230
 
1472 hidnplayr 231
; Physical management bits
2387 hidnplayr 232
        BIT_MGMT_DIR            equ 2 ; drive with the data written in mgmtData
233
        BIT_MGMT_DATA           equ 1 ; MII management data bit
234
        BIT_MGMT_CLK            equ 0 ; MII management clock
1519 hidnplayr 235
 
1472 hidnplayr 236
; MII commands
2387 hidnplayr 237
        MII_CMD_MASK            equ (1111b shl 10)
238
        MII_CMD_READ            equ (0110b shl 10)
239
        MII_CMD_WRITE           equ (0101b shl 10)
1519 hidnplayr 240
 
1472 hidnplayr 241
; MII registers
2387 hidnplayr 242
        REG_MII_BMCR            equ 0 ; basic mode control register
243
        REG_MII_BMSR            equ 1 ; basic mode status register
244
        REG_MII_ANAR            equ 4 ; auto negotiation advertisement register
245
        REG_MII_ANLPAR          equ 5 ; auto negotiation link partner ability register
246
        REG_MII_ANER            equ 6 ; auto negotiation expansion register
1519 hidnplayr 247
 
1472 hidnplayr 248
; MII bits
2387 hidnplayr 249
        BIT_MII_AUTONEG_COMPLETE     equ 5 ; auto-negotiation complete
250
        BIT_MII_PREAMBLE_SUPPRESSION equ 6
1519 hidnplayr 251
 
1472 hidnplayr 252
; eeprom bits and commands
2387 hidnplayr 253
        EEPROM_CMD_READ         equ 0x80
254
        EEPROM_BIT_BUSY         equ 15
1519 hidnplayr 255
 
1472 hidnplayr 256
; eeprom registers
2387 hidnplayr 257
        EEPROM_REG_OEM_NODE_ADDR equ 0xa
258
        EEPROM_REG_CAPABILITIES  equ 0x10
1519 hidnplayr 259
 
1472 hidnplayr 260
; Commands for command register
2387 hidnplayr 261
        SELECT_REGISTER_WINDOW  equ (1 shl 11)
1472 hidnplayr 262
 
2387 hidnplayr 263
        IS_VORTEX               equ 0x1
264
        IS_BOOMERANG            equ 0x2
265
        IS_CYCLONE              equ 0x4
266
        IS_TORNADO              equ 0x8
267
        EEPROM_8BIT             equ 0x10
268
        HAS_PWR_CTRL            equ 0x20
269
        HAS_MII                 equ 0x40
270
        HAS_NWAY                equ 0x80
271
        HAS_CB_FNS              equ 0x100
272
        INVERT_MII_PWR          equ 0x200
273
        INVERT_LED_PWR          equ 0x400
274
        MAX_COLLISION_RESET     equ 0x800
275
        EEPROM_OFFSET           equ 0x1000
276
        HAS_HWCKSM              equ 0x2000
277
        EXTRA_PREAMBLE          equ 0x4000
1472 hidnplayr 278
 
279
; Status
2387 hidnplayr 280
        IntLatch                equ 0x0001
281
        HostError               equ 0x0002
282
        TxComplete              equ 0x0004
283
        TxAvailable             equ 0x0008
284
        RxComplete              equ 0x0010
285
        RxEarly                 equ 0x0020
286
        IntReq                  equ 0x0040
287
        StatsFull               equ 0x0080
288
        DMADone                 equ 0x0100
289
        DownComplete            equ 0x0200
290
        UpComplete              equ 0x0400
291
        DMAInProgress           equ 0x0800 ; 1 shl 11  (DMA controller is still busy)
292
        CmdInProgress           equ 0x1000 ; 1 shl 12  (EL3_CMD is still busy)
1472 hidnplayr 293
 
2387 hidnplayr 294
        S_5_INTS                equ HostError + RxEarly + UpComplete + DownComplete ;+ TxComplete + RxComplete  + TxAvailable
1472 hidnplayr 295
 
296
; Commands
2387 hidnplayr 297
        TotalReset              equ 0 shl 11
298
        SelectWindow            equ 1 shl 11
299
        StartCoax               equ 2 shl 11
300
        RxDisable               equ 3 shl 11
301
        RxEnable                equ 4 shl 11
302
        RxReset                 equ 5 shl 11
303
        UpStall                 equ 6 shl 11
304
        UpUnstall               equ (6 shl 11)+1
305
        DownStall               equ (6 shl 11)+2
306
        DownUnstall             equ (6 shl 11)+3
307
        RxDiscard               equ 8 shl 11
308
        TxEnable                equ 9 shl 11
309
        TxDisable               equ 10 shl 11
310
        TxReset                 equ 11 shl 11
311
        FakeIntr                equ 12 shl 11
312
        AckIntr                 equ 13 shl 11
313
        SetIntrEnb              equ 14 shl 11
314
        SetStatusEnb            equ 15 shl 11
315
        SetRxFilter             equ 16 shl 11
316
        SetRxThreshold          equ 17 shl 11
317
        SetTxThreshold          equ 18 shl 11
318
        SetTxStart              equ 19 shl 11
319
        StartDMAUp              equ 20 shl 11
320
        StartDMADown            equ (20 shl 11)+1
321
        StatsEnable             equ 21 shl 11
322
        StatsDisable            equ 22 shl 11
323
        StopCoax                equ 23 shl 11
324
        SetFilterBit            equ 25 shl 11
1472 hidnplayr 325
 
326
; Rx mode bits
2387 hidnplayr 327
        RxStation               equ 1
328
        RxMulticast             equ 2
329
        RxBroadcast             equ 4
330
        RxProm                  equ 8
1472 hidnplayr 331
 
332
; RX/TX buffers sizes
2387 hidnplayr 333
        MAX_ETH_PKT_SIZE        equ 1536   ; max packet size
334
        NUM_RX_DESC             equ 4      ; a power of 2 number
335
        NUM_TX_DESC             equ 4      ; a power of 2 number
336
        MAX_ETH_FRAME_SIZE      equ 1520        ; size of ethernet frame + bytes alignment
1472 hidnplayr 337
 
1519 hidnplayr 338
virtual at ebx
1472 hidnplayr 339
 
2387 hidnplayr 340
        device:
1472 hidnplayr 341
 
2387 hidnplayr 342
        ETH_DEVICE
1472 hidnplayr 343
 
2387 hidnplayr 344
        .dpd_buffer       rd (dpd.size*NUM_TX_DESC)/4
345
        .upd_buffer       rd (upd.size*NUM_RX_DESC)/4
346
        .curr_upd         dd ?
347
        .prev_dpd         dd ?
1472 hidnplayr 348
 
2387 hidnplayr 349
        .io_addr          dd ?
350
        .pci_bus          db ?
351
        .pci_dev          db ?
352
        .irq_line         db ?
1519 hidnplayr 353
 
2387 hidnplayr 354
        .prev_tx_frame            dd ?
355
        .ver_id                   db ?
356
        .full_bus_master          db ?
357
        .has_hwcksm               db ?
358
        .preamble                 db ?
359
        .dn_list_ptr_cleared      db ?
1519 hidnplayr 360
 
2387 hidnplayr 361
        .size = $ - device
1519 hidnplayr 362
 
363
end virtual
364
 
1472 hidnplayr 365
section '.flat' code readable align 16
366
 
367
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
368
;;                        ;;
369
;; proc START             ;;
370
;;                        ;;
371
;; (standard driver proc) ;;
372
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
373
 
374
align 4
375
proc START stdcall, state:dword
376
 
2387 hidnplayr 377
        cmp [state], 1
378
        jne .exit
1472 hidnplayr 379
 
380
  .entry:
381
 
2387 hidnplayr 382
        DEBUGF 1,"Loading 3com network driver\n"
383
        stdcall RegService, my_service, service_proc
384
        ret
1472 hidnplayr 385
 
386
  .fail:
387
  .exit:
2387 hidnplayr 388
        xor eax, eax
389
        ret
1472 hidnplayr 390
 
391
endp
392
 
393
 
394
 
395
 
396
 
397
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
398
;;                        ;;
399
;; proc SERVICE_PROC      ;;
400
;;                        ;;
401
;; (standard driver proc) ;;
402
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
403
 
404
align 4
405
proc service_proc stdcall, ioctl:dword
406
 
2387 hidnplayr 407
        mov     edx, [ioctl]
408
        mov     eax, [IOCTL.io_code]
1472 hidnplayr 409
 
410
;------------------------------------------------------
411
 
2387 hidnplayr 412
        cmp     eax, 0 ;SRV_GETVERSION
413
        jne     @F
1472 hidnplayr 414
 
2387 hidnplayr 415
        cmp     [IOCTL.out_size], 4
416
        jl      .fail
417
        mov     eax, [IOCTL.output]
418
        mov     [eax], dword API_VERSION
1472 hidnplayr 419
 
2387 hidnplayr 420
        xor     eax, eax
421
        ret
1472 hidnplayr 422
 
423
;------------------------------------------------------
424
  @@:
2387 hidnplayr 425
        cmp     eax, 1 ;SRV_HOOK
426
        jne     .fail
1472 hidnplayr 427
 
2387 hidnplayr 428
        cmp     [IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
429
        jl      .fail
1472 hidnplayr 430
 
2387 hidnplayr 431
        mov     eax, [IOCTL.input]
432
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
433
        jne     .fail                                   ; other types of this hardware dont exist
1472 hidnplayr 434
 
435
; check if the device is already listed
436
 
2387 hidnplayr 437
        mov     ecx, [VORTEX_DEVICES]
438
        test    ecx, ecx
439
        jz      .maybeboomerang
1472 hidnplayr 440
 
2387 hidnplayr 441
        mov     esi, VORTEX_LIST
442
        mov     eax, [IOCTL.input]                      ; get the pci bus and device numbers
443
        mov     ax , [eax+1]                            ;
1472 hidnplayr 444
  .nextdevice:
2387 hidnplayr 445
        mov     ebx, [esi]
446
        cmp     ax , word [device.pci_bus]              ; compare with pci and device num in device list (notice the usage of word instead of byte)
447
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
448
        add     esi, 4
449
        loop    .nextdevice
1472 hidnplayr 450
 
451
 
452
  .maybeboomerang:
2387 hidnplayr 453
        mov     ecx, [BOOMERANG_DEVICES]
454
        test    ecx, ecx
455
        jz      .firstdevice
1472 hidnplayr 456
 
2387 hidnplayr 457
        mov     esi, BOOMERANG_LIST
458
        mov     eax, [IOCTL.input]                      ; get the pci bus and device numbers
459
        mov     ax , [eax+1]                            ;
1472 hidnplayr 460
  .nextdevice2:
2387 hidnplayr 461
        mov     ebx, [esi]
462
        cmp     ax , word [device.pci_bus]              ; compare with pci and device num in device list (notice the usage of word instead of byte)
463
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
464
        add     esi, 4
465
        loop    .nextdevice2
1472 hidnplayr 466
 
467
 
468
; This device doesnt have its own eth_device structure yet, lets create one
469
  .firstdevice:
2387 hidnplayr 470
        mov     ecx, [BOOMERANG_DEVICES]
471
        add     ecx, [VORTEX_DEVICES]
472
        cmp     ecx, MAX_DEVICES                        ; First check if the driver can handle one more card
473
        jge     .fail
1472 hidnplayr 474
 
2387 hidnplayr 475
        allocate_and_clear ebx, device.size, .fail      ; Allocate the buffer for device structure
1472 hidnplayr 476
 
477
; Fill in the direct call addresses into the struct
478
 
2387 hidnplayr 479
        mov     [device.reset], reset
480
        mov     [device.transmit], null_op
481
        mov     [device.get_MAC], read_mac
482
        mov     [device.set_MAC], write_mac
483
        mov     [device.unload], null_op
484
        mov     [device.name], my_service
1472 hidnplayr 485
 
486
; save the pci bus and device numbers
487
 
2387 hidnplayr 488
        mov     eax, [IOCTL.input]
489
        mov     cl , [eax+1]
490
        mov     [device.pci_bus], cl
491
        mov     cl , [eax+2]
492
        mov     [device.pci_dev], cl
1472 hidnplayr 493
 
494
; Now, it's time to find the base io addres of the PCI device
2387 hidnplayr 495
        find_io [device.pci_bus], [device.pci_dev], [device.io_addr]
1472 hidnplayr 496
 
497
; We've found the io address, find IRQ now
2387 hidnplayr 498
        find_irq [device.pci_bus], [device.pci_dev], [device.irq_line]
1472 hidnplayr 499
 
2387 hidnplayr 500
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
501
        [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4
1472 hidnplayr 502
 
503
; Ok, the eth_device structure is ready, let's probe the device
2387 hidnplayr 504
        call    probe                                                   ; this function will output in eax
505
        test    eax, eax
506
        jnz     .err                                                    ; If an error occured, exit
1472 hidnplayr 507
 
508
 
2387 hidnplayr 509
        movzx   ecx, [device.ver_id]
510
        test    word [hw_versions+2+ecx*4], IS_VORTEX
511
        jz      .not_vortex
1472 hidnplayr 512
 
2387 hidnplayr 513
        mov     eax, [VORTEX_DEVICES]                                   ; Add the device structure to our device list
514
        mov     [VORTEX_LIST+4*eax], ebx                                ; (IRQ handler uses this list to find device)
515
        inc     [VORTEX_DEVICES]                                        ;
1472 hidnplayr 516
 
517
  .register:
2387 hidnplayr 518
        mov     [device.type], NET_TYPE_ETH
519
        call    NetRegDev
1472 hidnplayr 520
 
2387 hidnplayr 521
        cmp     eax, -1
522
        je      .destroy
1472 hidnplayr 523
 
2387 hidnplayr 524
        call    start_device
525
        ret
1472 hidnplayr 526
 
527
  .not_vortex:
2387 hidnplayr 528
        mov     eax, [BOOMERANG_DEVICES]                                          ; Add the device structure to our device list
529
        mov     [BOOMERANG_LIST+4*eax], ebx                                ; (IRQ handler uses this list to find device)
530
        inc     [BOOMERANG_DEVICES]
1472 hidnplayr 531
 
2387 hidnplayr 532
        jmp     .register
1472 hidnplayr 533
 
534
; If the device was already loaded, find the device number and return it in eax
535
 
536
  .find_devicenum:
2387 hidnplayr 537
        DEBUGF  1,"Trying to find device number of already registered device\n"
538
        call    NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
539
                                                                        ; into a device number in edi
540
        mov     eax, edi                                                ; Application wants it in eax instead
541
        DEBUGF  1,"Kernel says: %u\n", eax
542
        ret
1472 hidnplayr 543
 
544
; If an error occured, remove all allocated data and exit (returning -1 in eax)
545
 
546
  .destroy:
2387 hidnplayr 547
        ; todo: reset device into virgin state
1472 hidnplayr 548
 
549
  .err:
2387 hidnplayr 550
        stdcall KernelFree, ebx
1472 hidnplayr 551
 
552
 
553
  .fail:
2387 hidnplayr 554
        or      eax, -1
555
        ret
1472 hidnplayr 556
 
557
;------------------------------------------------------
558
endp
559
 
560
 
561
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
562
;;                                                                        ;;
563
;;        Actual Hardware dependent code starts here                      ;;
564
;;                                                                        ;;
565
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
566
 
567
 
568
 
569
 
570
 
571
;***************************************************************************
572
;   Function
573
;      probe
574
;   Description
575
;      Searches for an ethernet card, enables it and clears the rx buffer
576
;   Destroyed registers
577
;      eax, ebx, ecx, edx, edi, esi
578
;
579
;***************************************************************************
580
 
581
align 4
1519 hidnplayr 582
probe:
1472 hidnplayr 583
 
2387 hidnplayr 584
        DEBUGF  1,"Probing 3com card\n"
1472 hidnplayr 585
 
2387 hidnplayr 586
        make_bus_master [device.pci_bus], [device.pci_dev]
1472 hidnplayr 587
 
588
; wake up the card
2387 hidnplayr 589
        call    wake_up
1472 hidnplayr 590
 
2387 hidnplayr 591
        movzx   ecx, [device.pci_bus]
592
        movzx   edx, [device.pci_dev]
593
        stdcall PciRead32, ecx ,edx ,0                                ; get device/vendor id
1472 hidnplayr 594
 
2387 hidnplayr 595
        DEBUGF  1,"Vendor id: 0x%x\n", ax
1472 hidnplayr 596
 
2387 hidnplayr 597
        cmp     ax , 0x10B7
598
        jne     .notfound
599
        shr     eax, 16
1472 hidnplayr 600
 
2387 hidnplayr 601
        DEBUGF  1,"Vendor ok!, device id: 0x%x\n", ax
1472 hidnplayr 602
 
603
; get chip version
2387 hidnplayr 604
        mov     ecx, HW_VERSIONS_SIZE/4-1
1521 hidnplayr 605
  .loop:
2387 hidnplayr 606
        cmp     ax , [hw_versions+ecx*4]
607
        jz      .found
608
        loop    .loop
609
        DEBUGF  1,"ecx: %u\n", ecx
1521 hidnplayr 610
  .notfound:
2387 hidnplayr 611
        DEBUGF  1,"Device id not found in list!\n"
612
        or      eax, -1
613
        ret
1521 hidnplayr 614
  .found:
2387 hidnplayr 615
        mov     esi, [hw_str+ecx*4]
616
        DEBUGF  1,"Hardware type: %s\n", esi
617
        mov     [device.name], esi
1472 hidnplayr 618
 
2387 hidnplayr 619
        mov     [device.ver_id], cl
620
        test    word [hw_versions+2+ecx*4], HAS_HWCKSM
621
        setnz   [device.has_hwcksm]
1472 hidnplayr 622
; set pci latency for vortex cards
2387 hidnplayr 623
        test    word [hw_versions+2+ecx*4], IS_VORTEX
624
        jz      .not_vortex
1472 hidnplayr 625
 
2387 hidnplayr 626
        mov     eax, 11111000b ; 248 = max latency
627
        movzx   ecx, [device.pci_bus]
628
        movzx   edx, [device.pci_dev]
629
        stdcall PciWrite32, ecx, edx, PCI_REG_LATENCY, eax
1472 hidnplayr 630
 
1521 hidnplayr 631
  .not_vortex:
1472 hidnplayr 632
; set RX/TX functions
2387 hidnplayr 633
        mov     ax, EEPROM_REG_CAPABILITIES
634
        call    read_eeprom
635
        test    al, 100000b ; full bus master?
636
        setnz   [device.full_bus_master]
637
        jnz     .boomerang_func
638
        mov     [device.transmit], vortex_transmit
639
        DEBUGF  1,"Device is a vortex type\n"
640
        DEBUGF  1,"I'm sorry but vortex code hasnt been tested yet\n"
641
        DEBUGF  1,"Please contact me on hidnplayr@kolibrios.org\n"
642
        DEBUGF  1,"If you can help me finish it!\n"
643
        or      eax, -1
644
        ret
645
        jmp     @f
1521 hidnplayr 646
  .boomerang_func: ; full bus master, so use boomerang functions
2387 hidnplayr 647
        mov     [device.transmit], boomerang_transmit
648
        DEBUGF  1,"Device is a boomerang type\n"
1521 hidnplayr 649
       @@:
2387 hidnplayr 650
        call    read_mac_eeprom
1472 hidnplayr 651
 
2387 hidnplayr 652
        test    byte [device.full_bus_master], 0xff
653
        jz      .set_preamble
1472 hidnplayr 654
; switch to register window 2
2387 hidnplayr 655
        set_io  0
656
        set_io  REG_COMMAND
657
        mov     ax, SELECT_REGISTER_WINDOW+2
658
        out     dx, ax
1472 hidnplayr 659
; activate xcvr by setting some magic bits
2387 hidnplayr 660
        set_io  REG_RESET_OPTIONS
661
        in      ax, dx
662
        and     ax, not 0x4010
663
        movzx   ecx, [device.ver_id]
664
        test    word [ecx*4+hw_versions+2], INVERT_LED_PWR
665
        jz      @f
666
        or      al, 0x10
1521 hidnplayr 667
       @@:
2387 hidnplayr 668
        test    word [ecx*4+hw_versions+2], INVERT_MII_PWR
669
        jz      @f
670
        or      ah, 0x40
1521 hidnplayr 671
       @@:
2387 hidnplayr 672
        out     dx, ax
1521 hidnplayr 673
  .set_preamble:
1472 hidnplayr 674
; use preamble as default
2387 hidnplayr 675
        mov     byte [device.preamble], 1 ; enable preamble
1472 hidnplayr 676
 
2387 hidnplayr 677
        call    global_reset
1472 hidnplayr 678
 
679
;--------------------------
680
; RESET
681
 
682
align 4
683
reset:
684
 
2387 hidnplayr 685
        movzx   eax, [device.irq_line]
686
        DEBUGF  1,"Attaching int handler to irq %x\n",eax:1
1472 hidnplayr 687
 
2387 hidnplayr 688
        movzx   ecx, [device.ver_id]
689
        test    word [hw_versions+2+ecx*4], IS_VORTEX
690
        jz      .not_vortex
1472 hidnplayr 691
 
2387 hidnplayr 692
        mov     esi, int_vortex
693
        jmp     .reg_int
1472 hidnplayr 694
 
695
.not_vortex:
2387 hidnplayr 696
        mov     esi, int_boomerang
1472 hidnplayr 697
 
698
.reg_int:
2387 hidnplayr 699
        stdcall AttachIntHandler, eax, esi, dword 0
700
        test    eax, eax
701
        jnz     @f
702
        DEBUGF  1,"\nCould not attach int handler!\n"
1472 hidnplayr 703
;        or      eax, -1
704
;        ret
705
  @@:
706
 
2387 hidnplayr 707
        set_io  0
708
        set_io  REG_COMMAND
709
        mov     ax, SELECT_REGISTER_WINDOW + 0
710
        out     dx, ax
1472 hidnplayr 711
 
2387 hidnplayr 712
        mov     ax, StopCoax
713
        out     dx, ax                        ; stop transceiver
1472 hidnplayr 714
 
2387 hidnplayr 715
        mov     ax, SELECT_REGISTER_WINDOW + 4
716
        out     dx, ax                        ; disable UTP
1472 hidnplayr 717
 
2387 hidnplayr 718
        set_io  REG_MEDIA_STATUS
719
        mov     ax, 0x0
1472 hidnplayr 720
 
2387 hidnplayr 721
        set_io  REG_COMMAND
722
        mov     ax, SELECT_REGISTER_WINDOW + 0
723
        out     dx, ax
1472 hidnplayr 724
 
2387 hidnplayr 725
        set_io  REG_FIFO_DIAGNOSTIC
726
        mov     ax, 0
727
        out     dx, ax                        ; disable card
1472 hidnplayr 728
 
2387 hidnplayr 729
        mov     ax, 1
730
        out     dx, ax                        ; enable card
1472 hidnplayr 731
 
2387 hidnplayr 732
        call    write_mac
1472 hidnplayr 733
 
734
 
1521 hidnplayr 735
;<<<<<<<<<<<<<<
736
 
2387 hidnplayr 737
        set_io  REG_COMMAND
738
        mov     ax, SELECT_REGISTER_WINDOW + 1
739
        out     dx, ax
1472 hidnplayr 740
 
2387 hidnplayr 741
        mov     ecx, 32
742
        set_io  0x0b
1472 hidnplayr 743
  .loop:
2387 hidnplayr 744
        in      al, dx
745
        loop    .loop
1472 hidnplayr 746
 
747
; Get rid of stary ints
2387 hidnplayr 748
        set_io  REG_COMMAND
749
        mov     ax, AckIntr + 0xff
750
        out     dx, ax
1472 hidnplayr 751
 
2387 hidnplayr 752
        mov     ax, SetStatusEnb + S_5_INTS
753
        out     dx, ax
1472 hidnplayr 754
 
2387 hidnplayr 755
        mov     ax, SetIntrEnb + S_5_INTS
756
        out     dx, ax
1472 hidnplayr 757
 
2387 hidnplayr 758
        call    set_rx_mode
759
        call    set_active_port
1472 hidnplayr 760
 
1521 hidnplayr 761
;>>>>>>>>>>
762
 
2387 hidnplayr 763
        call    create_rx_ring
764
        call    rx_reset
765
        call    tx_reset
1521 hidnplayr 766
 
767
;>>>>>>>>>>>>>>>>>>
768
 
2387 hidnplayr 769
        set_io  0
770
        set_io  REG_COMMAND
771
        mov     ax, RxEnable
772
        out     dx, ax
1472 hidnplayr 773
 
2387 hidnplayr 774
        mov     ax, TxEnable
775
        out     dx, ax
1472 hidnplayr 776
 
2387 hidnplayr 777
        set_io  REG_COMMAND
778
        mov     ax, SetRxThreshold + 208
779
        out     dx, ax
1472 hidnplayr 780
 
2387 hidnplayr 781
        mov     ax, SetTxThreshold + 60 ;16 ; recommended by the manual :)
782
        out     dx, ax
1472 hidnplayr 783
 
2387 hidnplayr 784
        mov     ax, SELECT_REGISTER_WINDOW + 1
785
        out     dx, ax
1472 hidnplayr 786
 
2387 hidnplayr 787
        xor     eax, eax
1481 hidnplayr 788
; clear packet/byte counters
1472 hidnplayr 789
 
2387 hidnplayr 790
        lea     edi, [device.bytes_tx]
791
        mov     ecx, 6
792
        rep     stosd
1481 hidnplayr 793
 
1519 hidnplayr 794
; Set the mtu, kernel will be able to send now
2387 hidnplayr 795
        mov     [device.mtu], 1514
1519 hidnplayr 796
 
2387 hidnplayr 797
        ret
1472 hidnplayr 798
 
799
 
800
 
801
 
802
 
803
align 4
1521 hidnplayr 804
start_device:
2387 hidnplayr 805
        DEBUGF  1,"Starting the device\n"
1472 hidnplayr 806
 
2387 hidnplayr 807
        set_io  0
808
        set_io  REG_COMMAND
809
        mov     ax, SetTxThreshold + 60 ;2047 ; recommended by the manual :)
810
        out     dx, ax
1472 hidnplayr 811
 
2387 hidnplayr 812
        call    check_tx_status
1472 hidnplayr 813
 
2387 hidnplayr 814
        set_io  0
815
        set_io  REG_COMMAND
1472 hidnplayr 816
; switch to register window 4
2387 hidnplayr 817
        mov     ax, SELECT_REGISTER_WINDOW+4
818
        out     dx, ax
1472 hidnplayr 819
 
820
; wait for linkDetect
2387 hidnplayr 821
        set_io  REG_MEDIA_STATUS
822
        mov     ecx, 20 ; wait for max 2s
1521 hidnplayr 823
  .link_detect_loop:
2387 hidnplayr 824
        mov     esi, 100
825
        call    Sleep ; 100 ms
826
        in      ax, dx
827
        test    ah, 1000b ; linkDetect
828
        jnz     @f
829
        loop    .link_detect_loop
830
        DEBUGF  1,"Link detect timed-out!\n"
1521 hidnplayr 831
       @@:
1472 hidnplayr 832
 
833
; print link type
2387 hidnplayr 834
        xor     eax, eax
835
        bsr     ax, word [device.mode]
836
        jz      @f
837
        sub     ax, 4
1521 hidnplayr 838
       @@:
839
 
2387 hidnplayr 840
        mov     esi, [link_str+eax*4]
841
        DEBUGF  1,"Established Link type: %s\n", esi
1472 hidnplayr 842
 
1521 hidnplayr 843
; enable interrupts
1472 hidnplayr 844
 
2387 hidnplayr 845
        set_io  REG_COMMAND
846
        mov     ax, SELECT_REGISTER_WINDOW + 1
847
        out     dx, ax
1472 hidnplayr 848
 
2387 hidnplayr 849
        mov     ax, AckIntr + 0xff
850
        out     dx, ax
1472 hidnplayr 851
 
2387 hidnplayr 852
        mov     ax, SetStatusEnb + S_5_INTS
853
        out     dx, ax
1472 hidnplayr 854
 
2387 hidnplayr 855
        mov     ax, SetIntrEnb + S_5_INTS
856
        out     dx, ax
1472 hidnplayr 857
 
2387 hidnplayr 858
        ret
1472 hidnplayr 859
 
860
 
861
 
862
 
863
 
864
 
865
 
866
align 4
867
set_rx_mode:
868
 
2387 hidnplayr 869
        DEBUGF  1,"Setting RX mode\n"
1521 hidnplayr 870
 
2387 hidnplayr 871
        set_io  0
872
        set_io  REG_COMMAND
1472 hidnplayr 873
 
2387 hidnplayr 874
if      defined PROMISCIOUS
875
        mov     ax, SetRxFilter + RxStation + RxMulticast + RxBroadcast + RxProm
1521 hidnplayr 876
else if  defined ALLMULTI
2387 hidnplayr 877
        mov     ax, SetRxFilter + RxStation + RxMulticast + RxBroadcast
1521 hidnplayr 878
else
2387 hidnplayr 879
        mov     ax, SetRxFilter + RxStation + RxBroadcast
1521 hidnplayr 880
end if
2387 hidnplayr 881
        out     dx, ax
1472 hidnplayr 882
 
2387 hidnplayr 883
        ret
1472 hidnplayr 884
 
885
 
886
 
887
 
888
 
889
;***************************************************************************
890
;   Function
891
;      global_reset
892
;   Description
893
;      resets the device
894
;   Parameters:
895
;      ebp - io_addr
896
;   Return value:
897
;   Destroyed registers
898
;      ax, ecx, edx, esi
899
;
900
;***************************************************************************1
901
 
902
align 4
903
global_reset:
904
 
2387 hidnplayr 905
        DEBUGF 1,"Global reset..\n"
1472 hidnplayr 906
 
907
; GlobalReset
2387 hidnplayr 908
        set_io  0
909
        set_io  REG_COMMAND
910
        xor     eax, eax
1472 hidnplayr 911
;       or      al, 0x14
2387 hidnplayr 912
        out     dx, ax
1472 hidnplayr 913
; wait for GlobalReset to complete
2387 hidnplayr 914
        mov     ecx, 64000
1521 hidnplayr 915
  .loop:
2387 hidnplayr 916
        in      ax , dx
917
        test    ah , 10000b ; check CmdInProgress
918
        loopz   .loop
1521 hidnplayr 919
 
2387 hidnplayr 920
        DEBUGF 1,"Waiting for nic to boot..\n"
1472 hidnplayr 921
; wait for 2 seconds for NIC to boot
2387 hidnplayr 922
        mov     esi, 2000
923
        call    Sleep ; 2 seconds
1472 hidnplayr 924
 
2387 hidnplayr 925
        DEBUGF 1,"Ok!\n"
1472 hidnplayr 926
 
2387 hidnplayr 927
        ret
1472 hidnplayr 928
 
929
 
930
 
931
;***************************************************************************
932
;   Function
933
;      tx_reset
934
;   Description
935
;      resets and enables transmitter engine
936
;
937
;***************************************************************************
938
 
939
align 4
940
tx_reset:
2387 hidnplayr 941
        DEBUGF 1,"tx reset\n"
1472 hidnplayr 942
 
943
; TxReset
2387 hidnplayr 944
        set_io  0
945
        set_io  REG_COMMAND
946
        mov     ax, TxReset
947
        out     dx, ax
1472 hidnplayr 948
; Wait for TxReset to complete
2387 hidnplayr 949
        mov     ecx, 200000
1472 hidnplayr 950
.tx_reset_loop:
2387 hidnplayr 951
        in      ax, dx
952
        test    ah, 10000b ; check CmdInProgress
953
        jz      .tx_set_prev
954
        dec     ecx
955
        jnz     .tx_reset_loop
1472 hidnplayr 956
.tx_set_prev:
957
; init last_dpd
2387 hidnplayr 958
        lea     eax, [device.dpd_buffer + (NUM_TX_DESC-1)*dpd.size]
959
        mov     [device.prev_dpd], eax
1472 hidnplayr 960
 
961
.tx_enable:
2387 hidnplayr 962
        ret
1472 hidnplayr 963
 
964
 
965
 
966
;***************************************************************************
967
;   Function
968
;      rx_reset
969
;   Description
970
;      resets and enables receiver engine
971
;
972
;***************************************************************************
973
 
974
align 4
975
rx_reset:
976
 
2387 hidnplayr 977
        DEBUGF 1,"rx reset\n"
1472 hidnplayr 978
 
2387 hidnplayr 979
        set_io  0
980
        set_io  REG_COMMAND
981
        mov     ax, RxReset or 0x4
982
        out     dx, ax
1519 hidnplayr 983
 
1472 hidnplayr 984
; wait for RxReset to complete
2387 hidnplayr 985
        mov     ecx, 200000
1519 hidnplayr 986
  .loop:
2387 hidnplayr 987
        in      ax, dx
988
        test    ah, 10000b ; check CmdInProgress
989
        jz      .done
990
        dec     ecx
991
        jnz     .loop
1521 hidnplayr 992
  .done:
1519 hidnplayr 993
 
2387 hidnplayr 994
        lea     eax, [device.upd_buffer]
995
        mov     [device.curr_upd], eax
996
        GetRealAddr
997
        set_io  0
998
        set_io  REG_UP_LIST_PTR
999
        out     dx, eax
1521 hidnplayr 1000
 
1001
  .rx_enable:
2387 hidnplayr 1002
        ret
1521 hidnplayr 1003
 
1004
 
1005
align 4
1006
create_rx_ring:
1472 hidnplayr 1007
; create upd ring
2387 hidnplayr 1008
        lea     eax, [device.upd_buffer]
1009
        GetRealAddr
1010
        mov     edi, eax                                                ; real addr of first descr
1472 hidnplayr 1011
 
2387 hidnplayr 1012
        lea     esi, [device.upd_buffer]                                ; ptr to first descr
1013
        lea     edx, [device.upd_buffer + (NUM_RX_DESC-1)*upd.size]     ; ptr to last descr
1472 hidnplayr 1014
 
2387 hidnplayr 1015
        mov     ecx, NUM_RX_DESC
1472 hidnplayr 1016
 
1519 hidnplayr 1017
  .upd_loop:
2387 hidnplayr 1018
        mov     [edx + upd.next_ptr], edi
1472 hidnplayr 1019
 
2387 hidnplayr 1020
        push    ecx edx
1021
        stdcall KernelAlloc, MAX_ETH_FRAME_SIZE
1022
        pop     edx ecx
1023
        mov     [esi + upd.realaddr], eax
1024
        call    GetPgAddr
1025
        mov     [esi + upd.frag_addr], eax
1026
        and     [esi + upd.pkt_status], 0
1027
        mov     [esi + upd.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31)
1472 hidnplayr 1028
 
2387 hidnplayr 1029
        DEBUGF  1,"UPD: lin=%x phys=%x len=%x next ptr=%x\n", [esi+upd.realaddr]:8, [esi+upd.frag_addr]:8, [esi+upd.frag_len]:8, edi
1030
        DEBUGF  1,"UPD: cur=%x prev=%x\n", esi, edx
1472 hidnplayr 1031
 
2387 hidnplayr 1032
        mov     edx, esi
1033
        add     esi, upd.size
1034
        add     edi, upd.size
1035
        dec     ecx
1036
        jnz     .upd_loop
1472 hidnplayr 1037
 
2387 hidnplayr 1038
        ret
1472 hidnplayr 1039
 
1040
 
1041
 
1042
;---------------------------------------------------------------------------
1043
;   Function
1044
;      try_link_detect
1045
;   Description
1046
;      try_link_detect checks if link exists
1047
;   Parameters
1048
;      ebx = device structure
1049
;   Return value
1050
;      al - 0 ; no link detected
1051
;      al - 1 ; link detected
1052
;   Destroyed registers
1053
;      eax, ebx, ecx, edx, edi, esi
1054
;
1055
;---------------------------------------------------------------------------
1056
 
1057
align 4
1058
try_link_detect:
1059
 
2387 hidnplayr 1060
        DEBUGF  1,"trying to detect link\n"
1472 hidnplayr 1061
 
1062
; create self-directed packet
2387 hidnplayr 1063
        stdcall KernelAlloc, 20 ; create a buffer for the self-directed packet
1064
        test    eax, eax
1065
        jz      .fail
1521 hidnplayr 1066
 
2387 hidnplayr 1067
        pushd   20              ; Packet parameters for device.transmit
1068
        push    eax             ;
1521 hidnplayr 1069
 
2387 hidnplayr 1070
        mov     edi, eax
1521 hidnplayr 1071
 
2387 hidnplayr 1072
        lea     esi, [device.mac]
1073
        movsw
1074
        movsd
1075
        sub     esi, 6
1076
        movsw
1077
        movsd
1078
        mov     ax , 0x0608
1079
        stosw
1472 hidnplayr 1080
 
1081
; download self-directed packet
2387 hidnplayr 1082
        call    [device.transmit]
1472 hidnplayr 1083
 
1084
; switch to register window 4
2387 hidnplayr 1085
        set_io  0
1086
        set_io  REG_COMMAND
1087
        mov     ax, SELECT_REGISTER_WINDOW+4
1088
        out     dx, ax
1472 hidnplayr 1089
 
1090
; See if we have received the packet by now..
2387 hidnplayr 1091
        cmp     [device.packets_rx], 0
1092
        jnz     .link_detected
1472 hidnplayr 1093
 
1094
; switch to register window 4
2387 hidnplayr 1095
        set_io  REG_COMMAND
1096
        mov     ax, SELECT_REGISTER_WINDOW+4
1097
        out     dx, ax
1472 hidnplayr 1098
 
1099
; read linkbeatdetect
2387 hidnplayr 1100
        set_io  REG_MEDIA_STATUS
1101
        in      ax, dx
1102
        test    ah, 1000b ; test linkBeatDetect
1103
        jnz     .link_detected
1104
        xor     al, al
1105
        jmp     .finish
1472 hidnplayr 1106
 
1521 hidnplayr 1107
  .link_detected:
2387 hidnplayr 1108
        DEBUGF  1,"link detected!\n"
1109
        setb    al
1472 hidnplayr 1110
 
1521 hidnplayr 1111
  .finish:
2387 hidnplayr 1112
        test    al, al
1113
        jz      @f
1114
        or      byte [device.mode+1], 100b
1521 hidnplayr 1115
       @@:
2387 hidnplayr 1116
        ret
1472 hidnplayr 1117
 
1521 hidnplayr 1118
  .fail:
2387 hidnplayr 1119
        ret
1472 hidnplayr 1120
 
1121
 
1521 hidnplayr 1122
 
1472 hidnplayr 1123
;***************************************************************************
1124
;   Function
1125
;      try_phy
1126
;   Description
1127
;      try_phy checks the auto-negotiation function
1128
;      in the PHY at PHY index. It can also be extended to
1129
;      include link detection for non-IEEE 802.3u
1521 hidnplayr 1130
;      auto-negotiation devices, for instance the BCM5000.              ; TODO: BCM5000
1472 hidnplayr 1131
;   Parameters
1132
;       ah - PHY index
1133
;       ebx - device stucture
1134
;   Return value
1135
;      al - 0 link is auto-negotiated
1136
;      al - 1 no link is auto-negotiated
1137
;   Destroyed registers
1138
;       eax, ebx, ecx, edx, esi
1139
;
1140
;***************************************************************************
1141
 
1142
align 4
1143
try_phy:
1144
 
2387 hidnplayr 1145
        DEBUGF 1,"PHY=%u\n", ah
1146
        DEBUGF 1,"Detecting if device is auto-negotiation capable\n"
1472 hidnplayr 1147
 
2387 hidnplayr 1148
        mov     al, REG_MII_BMCR
1149
        push    eax
1150
        call    mdio_read       ; returns with window #4
1151
        or      ah , 0x80       ; software reset
1152
        mov     esi, eax
1153
        mov     eax, dword [esp]
1154
        call    mdio_write      ; returns with window #4
1472 hidnplayr 1155
 
1156
; wait for reset to complete
2387 hidnplayr 1157
        mov     esi, 2000
1158
        stdcall Sleep      ; 2s
1159
        mov     eax, [esp]
1160
        call    mdio_read       ; returns with window #4
1161
        test    ah , 0x80
1162
        jnz     .fail1
1163
        mov     eax, [esp]
1472 hidnplayr 1164
 
1165
; wait for a while after reset
2387 hidnplayr 1166
        mov     esi, 20
1167
        stdcall Sleep      ; 20ms
1168
        mov     eax, [esp]
1169
        mov     al , REG_MII_BMSR
1170
        call    mdio_read        ; returns with window #4
1171
        test    al , 1           ; extended capability supported?
1172
        jz      .fail2
1472 hidnplayr 1173
 
1174
; auto-neg capable?
2387 hidnplayr 1175
        test    al , 1000b
1176
        jz      .fail2           ; not auto-negotiation capable
1472 hidnplayr 1177
 
2387 hidnplayr 1178
        DEBUGF  1,"Device is auto-negotiation capable\n"
1521 hidnplayr 1179
 
1472 hidnplayr 1180
; auto-neg complete?
2387 hidnplayr 1181
        test    al , 100000b
1182
        jnz     .auto_neg_ok
1472 hidnplayr 1183
 
2387 hidnplayr 1184
        DEBUGF  1,"Restarting auto-negotiation\n"
1521 hidnplayr 1185
 
1472 hidnplayr 1186
; restart auto-negotiation
2387 hidnplayr 1187
        mov     eax, [esp]
1188
        mov     al , REG_MII_ANAR
1189
        push    eax
1190
        call    mdio_read       ; returns with window #4
1191
        or      ax , 1111b shl 5; advertise only 10base-T and 100base-TX
1192
        mov     esi, eax
1193
        pop     eax
1194
        call    mdio_write      ; returns with window #4
1195
        mov     eax, [esp]
1196
        call    mdio_read       ; returns with window #4
1197
        mov     esi, eax
1198
        or      bh , 10010b     ; restart auto-negotiation
1199
        mov     eax, [esp]
1200
        call    mdio_write      ; returns with window #4
1201
        mov     esi, 4000
1202
        stdcall Sleep  ; 4 seconds
1203
        mov     eax, [esp]
1204
        mov     al , REG_MII_BMSR
1205
        call    mdio_read ; returns with window #4
1206
        test    al , 100000b ; auto-neg complete?
1207
        jnz     .auto_neg_ok
1208
        jmp     .fail3
1521 hidnplayr 1209
  .auto_neg_ok:
1472 hidnplayr 1210
 
2387 hidnplayr 1211
        DEBUGF  1,"Auto-negotiation complete\n"
1521 hidnplayr 1212
 
1472 hidnplayr 1213
; compare advertisement and link partner ability registers
2387 hidnplayr 1214
        mov     eax, [esp]
1215
        mov     al , REG_MII_ANAR
1216
        call    mdio_read       ; returns with window #4
1217
        xchg    eax, [esp]
1218
        mov     al , REG_MII_ANLPAR
1219
        call    mdio_read       ; returns with window #4
1220
        pop     esi
1221
        and     eax, esi
1222
        and     eax, 1111100000b
1223
        push    eax
1472 hidnplayr 1224
 
2387 hidnplayr 1225
        mov     word[device.mode+2], ax
1472 hidnplayr 1226
 
1227
; switch to register window 3
2387 hidnplayr 1228
        set_io  0
1229
        set_io  REG_COMMAND
1230
        mov     ax , SELECT_REGISTER_WINDOW+3
1231
        out     dx , ax
1472 hidnplayr 1232
 
1233
; set full-duplex mode
2387 hidnplayr 1234
        set_io  REG_MAC_CONTROL
1235
        in      ax , dx
1236
        and     ax , not 0x120  ; clear full duplex and flow control
1237
        pop     esi
1238
        test    esi, 1010b shl 5; check for full-duplex
1239
        jz      .half_duplex
1240
        or      ax , 0x120      ; set full duplex and flow control
1521 hidnplayr 1241
  .half_duplex:
2387 hidnplayr 1242
        DEBUGF 1,"Using half-duplex\n"
1243
        out     dx , ax
1244
        mov     al , 1
1245
        ret
1472 hidnplayr 1246
 
1521 hidnplayr 1247
 
1248
  .fail1:
2387 hidnplayr 1249
        DEBUGF  1,"reset failed!\n"
1250
        pop     eax
1251
        xor     al, al
1252
        ret
1472 hidnplayr 1253
 
1521 hidnplayr 1254
  .fail2:
2387 hidnplayr 1255
        DEBUGF  1,"This device is not auto-negotiation capable!\n"
1256
        pop     eax
1257
        xor     al, al
1258
        ret
1472 hidnplayr 1259
 
1521 hidnplayr 1260
  .fail3:
2387 hidnplayr 1261
        DEBUGF  1,"auto-negotiation reset failed!\n"
1262
        pop     eax
1263
        xor     al, al
1264
        ret
1472 hidnplayr 1265
 
1521 hidnplayr 1266
 
1267
 
1472 hidnplayr 1268
;***************************************************************************
1269
;   Function
1270
;      try_mii
1271
;   Description
1272
;      try_MII checks the on-chip auto-negotiation logic
1273
;      or an off-chip MII PHY, depending upon what is set in
1274
;      xcvrSelect by the caller.
1275
;      It exits when it finds the first device with a good link.
1276
;   Parameters
1277
;      ebp - io_addr
1278
;   Return value
1279
;      al - 0
1280
;      al - 1
1281
;   Destroyed registers
1282
;      eax, ebx, ecx, edx, esi
1283
;
1284
;***************************************************************************
1285
 
1286
align 4
1287
try_mii:
1288
 
2387 hidnplayr 1289
        DEBUGF  1,"trying to find MII PHY\n"
1472 hidnplayr 1290
 
1291
; switch to register window 3
2387 hidnplayr 1292
        set_io  0
1293
        set_io  REG_COMMAND
1294
        mov     ax, SELECT_REGISTER_WINDOW+3
1295
        out     dx, ax
1296
        set_io  REG_INTERNAL_CONFIG
1297
        in      eax, dx
1298
        and     eax, (1111b shl 20)
1299
        cmp     eax, (1000b shl 20) ; is auto-negotiation set?
1300
        jne     .mii_device
1521 hidnplayr 1301
 
2387 hidnplayr 1302
        DEBUGF  1,"auto-negotiation is set\n"
1472 hidnplayr 1303
; switch to register window 4
2387 hidnplayr 1304
        set_io  REG_COMMAND
1305
        mov     ax , SELECT_REGISTER_WINDOW+4
1306
        out     dx , ax
1521 hidnplayr 1307
 
1472 hidnplayr 1308
; PHY==24 is the on-chip auto-negotiation logic
1309
; it supports only 10base-T and 100base-TX
2387 hidnplayr 1310
        mov     ah , 24
1311
        call    try_phy
1312
        test    al , al
1313
        jz      .fail_finish
1521 hidnplayr 1314
 
2387 hidnplayr 1315
        mov     cl , 24
1316
        jmp     .check_preamble
1521 hidnplayr 1317
 
1318
  .mii_device:
2387 hidnplayr 1319
        cmp     eax, (0110b shl 20)
1320
        jne     .fail_finish
1521 hidnplayr 1321
 
2387 hidnplayr 1322
        set_io  0
1323
        set_io  REG_COMMAND
1324
        mov     ax , SELECT_REGISTER_WINDOW+4
1325
        out     dx , ax
1521 hidnplayr 1326
 
2387 hidnplayr 1327
        set_io  REG_PHYSICAL_MGMT
1328
        in      ax , dx
1329
        and     al , (1 shl BIT_MGMT_DIR) or (1 shl BIT_MGMT_DATA)
1330
        cmp     al , (1 shl BIT_MGMT_DATA)
1331
        je      .search_for_phy
1521 hidnplayr 1332
 
2387 hidnplayr 1333
        xor     al , al
1334
        ret
1521 hidnplayr 1335
 
1336
  .search_for_phy:
1472 hidnplayr 1337
; search for PHY
2387 hidnplayr 1338
        mov     cx , 31
1521 hidnplayr 1339
  .search_phy_loop:
2387 hidnplayr 1340
        DEBUGF  1,"Searching the PHY\n"
1341
        cmp     cx , 24
1342
        je      .next_phy
1343
        mov     ah , cl ; ah = phy
1344
        mov     al , REG_MII_BMCR ; al = Basic Mode Status Register
1345
        push    cx
1346
        call    mdio_read
1347
        pop     cx
1348
        test    ax , ax
1349
        jz      .next_phy
1350
        cmp     ax , 0xffff
1351
        je      .next_phy
1352
        mov     ah , cl ; ah = phy
1353
        push    cx
1354
        call    try_phy
1355
        pop     cx
1356
        test    al , al
1357
        jnz     .check_preamble
1521 hidnplayr 1358
  .next_phy:
2387 hidnplayr 1359
        loopw   .search_phy_loop
1521 hidnplayr 1360
 
1361
  .fail_finish:
2387 hidnplayr 1362
        xor     al, al
1363
        ret
1521 hidnplayr 1364
 
1472 hidnplayr 1365
; epilog
1521 hidnplayr 1366
  .check_preamble:
2387 hidnplayr 1367
        DEBUGF  1,"Using PHY: %u\nChecking PreAmble\n", cl
1368
        push    eax ; eax contains the return value of try_phy
1472 hidnplayr 1369
; check hard coded preamble forcing
2387 hidnplayr 1370
        movzx   eax, [device.ver_id]
1371
        test    word [eax*4+hw_versions+2], EXTRA_PREAMBLE
1372
        setnz   [device.preamble] ; force preamble
1373
        jnz     .finish
1521 hidnplayr 1374
 
1472 hidnplayr 1375
; check mii for preamble suppression
2387 hidnplayr 1376
        mov     ah, cl
1377
        mov     al, REG_MII_BMSR
1378
        call    mdio_read
1379
        test    al, 1000000b ; preamble suppression?
1380
        setz    [device.preamble] ; no
1521 hidnplayr 1381
 
1382
  .finish:
2387 hidnplayr 1383
        pop     eax
1384
        ret
1472 hidnplayr 1385
 
1386
 
1387
 
1388
;***************************************************************************
1389
;   Function
1390
;      test_packet
1391
;   Description
1392
;      try_loopback try a loopback packet for 10BASE2 or AUI port
1393
;   Parameters
1394
;      ebx = device structure
1395
;
1396
;***************************************************************************
1397
 
1398
align 4
1399
test_packet:
1400
 
2387 hidnplayr 1401
        DEBUGF 1,"sending test packet\n"
1472 hidnplayr 1402
 
1403
; switch to register window 3
2387 hidnplayr 1404
        set_io  0
1405
        set_io  REG_COMMAND
1406
        mov     ax, SELECT_REGISTER_WINDOW+3
1407
        out     dx, ax
1472 hidnplayr 1408
 
1409
; set fullDuplexEnable in MacControl register
2387 hidnplayr 1410
        set_io  REG_MAC_CONTROL
1411
        in      ax, dx
1412
        or      ax, 0x120
1413
        out     dx, ax
1472 hidnplayr 1414
 
1415
; switch to register window 5
2387 hidnplayr 1416
        set_io  REG_COMMAND
1417
        mov     ax, SELECT_REGISTER_WINDOW+5
1418
        out     dx, ax
1472 hidnplayr 1419
 
1420
; set RxFilter to enable individual address matches
2387 hidnplayr 1421
        mov     ax, (10000b shl 11)
1422
        set_io  REG_RX_FILTER
1423
        in      al, dx
1424
        or      al, 1
1425
        set_io  REG_COMMAND
1426
        out     dx, ax
1472 hidnplayr 1427
 
1428
; issue RxEnable and TxEnable
2387 hidnplayr 1429
        call    rx_reset
1430
        call    tx_reset
1472 hidnplayr 1431
 
1521 hidnplayr 1432
; create self-directed packet
2387 hidnplayr 1433
        stdcall KernelAlloc, 20 ; create a buffer for the self-directed packet
1434
        test    eax, eax
1435
        jz      .fail
1521 hidnplayr 1436
 
2387 hidnplayr 1437
        pushd   20              ; Packet parameters for device.transmit
1438
        push    eax             ;
1521 hidnplayr 1439
 
2387 hidnplayr 1440
        mov     edi, eax
1441
        lea     esi, [device.mac]
1442
        movsw
1443
        movsd
1444
        sub     esi, 6
1445
        movsw
1446
        movsd
1447
        mov     ax , 0x0608
1448
        stosw
1472 hidnplayr 1449
 
1521 hidnplayr 1450
; download self-directed packet
2387 hidnplayr 1451
        call    [device.transmit]
1472 hidnplayr 1452
 
1453
; wait for 2s
2387 hidnplayr 1454
        mov     esi, 2000
1455
        call    Sleep
1472 hidnplayr 1456
 
1457
; check if self-directed packet is received
2387 hidnplayr 1458
        mov     eax, [device.packets_rx]
1459
        test    eax, eax
1460
        jnz     .finish
1472 hidnplayr 1461
 
1462
; switch to register window 3
2387 hidnplayr 1463
        set_io  0
1464
        set_io  REG_COMMAND
1465
        mov     ax, SELECT_REGISTER_WINDOW+3
1466
        out     dx, ax
1472 hidnplayr 1467
 
1468
; clear fullDuplexEnable in MacControl register
2387 hidnplayr 1469
        set_io  REG_MAC_CONTROL
1470
        in      ax , dx
1471
        and     ax , not 0x120
1472
        out     dx , ax
1521 hidnplayr 1473
  .fail:
2387 hidnplayr 1474
        xor     eax, eax
1472 hidnplayr 1475
 
1521 hidnplayr 1476
  .finish:
2387 hidnplayr 1477
        ret
1472 hidnplayr 1478
 
1479
 
1480
 
1481
;***************************************************************************
1482
;   Function
1483
;      try_loopback
1484
;   Description
1485
;      tries a loopback packet for 10BASE2 or AUI port
1486
;   Parameters
1487
;      al -  0: 10Mbps AUI connector
1488
;            1: 10BASE-2
1489
;      ebp - io_addr
1490
;   Return value
1491
;      al - 0
1492
;      al - 1
1493
;   Destroyed registers
1494
;      eax, ebx, ecx, edx, edi, esi
1495
;
1496
;***************************************************************************
1497
 
1498
align 4
1499
try_loopback:
1500
 
2387 hidnplayr 1501
        DEBUGF 1,"trying loopback\n"
1472 hidnplayr 1502
 
2387 hidnplayr 1503
        push    eax
1472 hidnplayr 1504
; switch to register window 3
2387 hidnplayr 1505
        set_io  0
1506
        set_io  REG_COMMAND
1507
        mov     ax, SELECT_REGISTER_WINDOW+3
1508
        out     dx, ax
1509
        mov     eax, [esp]
1472 hidnplayr 1510
 
2387 hidnplayr 1511
        mov     cl, al
1512
        inc     cl
1513
        shl     cl, 3
1514
        or      byte [device.mode+1], cl
1472 hidnplayr 1515
 
2387 hidnplayr 1516
        test    al, al ; aui or coax?
1517
        jz      .complete_loopback
1472 hidnplayr 1518
; enable 100BASE-2 DC-DC converter
2387 hidnplayr 1519
        mov     ax, (10b shl 11) ; EnableDcConverter
1520
        out     dx, ax
1521 hidnplayr 1521
  .complete_loopback:
1522
 
2387 hidnplayr 1523
        mov     cx, 2 ; give a port 3 chances to complete a loopback
1521 hidnplayr 1524
  .next_try:
2387 hidnplayr 1525
        push    ecx
1526
        call    test_packet
1527
        pop     ecx
1528
        test    eax, eax
1529
        loopzw  .next_try
1521 hidnplayr 1530
 
1531
  .finish:
2387 hidnplayr 1532
        xchg    eax, [esp]
1533
        test    al, al
1534
        jz      .aui_finish
1521 hidnplayr 1535
 
1472 hidnplayr 1536
; issue DisableDcConverter command
2387 hidnplayr 1537
        set_io  0
1538
        set_io  REG_COMMAND
1539
        mov     ax, (10111b shl 11)
1540
        out     dx, ax
1521 hidnplayr 1541
  .aui_finish:
2387 hidnplayr 1542
        pop     eax ; al contains the result of operation
1472 hidnplayr 1543
 
2387 hidnplayr 1544
        test    al, al
1545
        jnz     @f
1546
        and     byte [device.mode+1], not 11000b
1521 hidnplayr 1547
       @@:
1472 hidnplayr 1548
 
2387 hidnplayr 1549
        ret
1472 hidnplayr 1550
 
1551
 
1552
;***************************************************************************
1553
;   Function
1554
;      set_active_port
1555
;   Description
1556
;      It selects the media port (transceiver) to be used
1557
;   Return value:
1558
;   Destroyed registers
1559
;      eax, ebx, ecx, edx, edi, esi
1560
;
1561
;***************************************************************************
1562
 
1563
align 4
1564
set_active_port:
1565
 
2387 hidnplayr 1566
        DEBUGF 1,"Trying to find the active port\n"
1472 hidnplayr 1567
 
1568
; switch to register window 3
2387 hidnplayr 1569
        set_io  0
1570
        set_io  REG_COMMAND
1571
        mov     ax, SELECT_REGISTER_WINDOW + 3
1572
        out     dx, ax
1521 hidnplayr 1573
 
2387 hidnplayr 1574
        set_io  REG_INTERNAL_CONFIG
1575
        in      eax, dx
1576
        test    eax, (1 shl 24) ; check if autoselect enable
1577
        jz      .set_first_available_media
1472 hidnplayr 1578
 
1579
; check 100BASE-TX and 10BASE-T
2387 hidnplayr 1580
        set_io  REG_MEDIA_OPTIONS
1581
        in      ax, dx
1582
        test    al, 1010b       ; check whether 100BASE-TX or 10BASE-T available
1583
        jz      .mii_device     ; they are not available
1472 hidnplayr 1584
 
1585
; set auto-negotiation
2387 hidnplayr 1586
        set_io  REG_INTERNAL_CONFIG
1587
        in      eax, dx
1588
        and     eax, not (1111b shl 20)
1589
        or      eax, (1000b shl 20)
1590
        out     dx, eax
1591
        call    try_mii
1592
        test    al, al
1593
        jz      .mii_device
1594
        DEBUGF 1,"Using auto negotiation\n"
1595
        ret
1472 hidnplayr 1596
 
1521 hidnplayr 1597
  .mii_device:
1472 hidnplayr 1598
; switch to register window 3
2387 hidnplayr 1599
        set_io  0
1472 hidnplayr 1600
; check for off-chip mii device
2387 hidnplayr 1601
        set_io  REG_MEDIA_OPTIONS
1602
        in      ax, dx
1603
        test    al, 1000000b ; check miiDevice
1604
        jz      .base_fx
1605
        set_io  REG_INTERNAL_CONFIG
1606
        in      eax, dx
1607
        and     eax, not (1111b shl 20)
1608
        or      eax, (0110b shl 20) ; set MIIDevice
1609
        out     dx, eax
1610
        call    try_mii
1611
        test    al, al
1612
        jz      .base_fx
1613
        DEBUGF 1,"Using off-chip mii device\n"
1614
        ret
1472 hidnplayr 1615
 
1521 hidnplayr 1616
  .base_fx:
1472 hidnplayr 1617
; switch to register window 3
2387 hidnplayr 1618
        set_io  0
1472 hidnplayr 1619
; check for 100BASE-FX
2387 hidnplayr 1620
        set_io  REG_MEDIA_OPTIONS
1621
        in      ax, dx ; read media option register
1622
        test    al, 100b ; check 100BASE-FX
1623
        jz      .aui_enable
1624
        set_io  REG_INTERNAL_CONFIG
1625
        in      eax, dx
1626
        and     eax, not (1111b shl 20)
1627
        or      eax, (0101b shl 20) ; set 100base-FX
1628
        out     dx, eax
1629
        call    try_link_detect
1630
        test    al, al
1631
        jz      .aui_enable
1632
        DEBUGF 1,"Using 100Base-FX\n"
1633
        ret
1472 hidnplayr 1634
 
1521 hidnplayr 1635
  .aui_enable:
1472 hidnplayr 1636
; switch to register window 3
2387 hidnplayr 1637
        set_io  0
1472 hidnplayr 1638
; check for 10Mbps AUI connector
2387 hidnplayr 1639
        set_io  REG_MEDIA_OPTIONS
1640
        in      ax, dx ; read media option register
1641
        test    al, 100000b ; check 10Mbps AUI connector
1642
        jz      .coax_available
1643
        set_io  REG_INTERNAL_CONFIG
1644
        in      eax, dx
1645
        and     eax, not (1111b shl 20)
1646
        or      eax, (0001b shl 20) ; set 10Mbps AUI connector
1647
        out     dx, eax
1648
        xor     al, al ; try 10Mbps AUI connector
1649
        call    try_loopback
1650
        test    al, al
1651
        jz      .coax_available
1652
        DEBUGF 1,"Using 10Mbps aui\n"
1653
        ret
1472 hidnplayr 1654
 
1521 hidnplayr 1655
  .coax_available:
1472 hidnplayr 1656
; switch to register window 3
2387 hidnplayr 1657
        set_io  0
1472 hidnplayr 1658
; check for coaxial 10BASE-2 port
2387 hidnplayr 1659
        set_io  REG_MEDIA_OPTIONS
1660
        in      ax, dx ; read media option register
1661
        test    al, 10000b ; check 10BASE-2
1662
        jz      .set_first_available_media
1521 hidnplayr 1663
 
2387 hidnplayr 1664
        set_io  REG_INTERNAL_CONFIG
1665
        in      eax, dx
1666
        and     eax, not (1111b shl 20)
1667
        or      eax, (0011b shl 20) ; set 10BASE-2
1668
        out     dx, eax
1669
        mov     al, 1
1670
        call    try_loopback
1671
        test    al, al
1672
        jz      .set_first_available_media
1673
        DEBUGF 1,"Using 10BASE-2 port\n"
1674
        ret
1472 hidnplayr 1675
 
1521 hidnplayr 1676
  .set_first_available_media:
2387 hidnplayr 1677
        DEBUGF  1,"Using the first available media\n"
1472 hidnplayr 1678
 
1679
;***************************************************************************
1680
;   Function
1681
;      set_available_media
1682
;   Description
1683
;      sets the first available media
1684
;   Parameters
1521 hidnplayr 1685
;      ebx - ptr to device struct
1472 hidnplayr 1686
;   Return value
1687
;      al - 0
1688
;      al - 1
1689
;   Destroyed registers
1690
;      eax, edx
1691
;
1692
;***************************************************************************
1693
 
1694
align 4
1695
set_available_media:
1696
 
2387 hidnplayr 1697
        DEBUGF  1,"Setting the available media\n"
1472 hidnplayr 1698
; switch to register window 3
2387 hidnplayr 1699
        set_io  0
1700
        set_io  REG_COMMAND
1701
        mov     ax, SELECT_REGISTER_WINDOW+3
1702
        out     dx, ax
1521 hidnplayr 1703
 
2387 hidnplayr 1704
        set_io  REG_MEDIA_OPTIONS
1705
        in      ax, dx
1706
        DEBUGF  1,"available media:%x\n", al
1707
        mov     cl, al
1521 hidnplayr 1708
 
2387 hidnplayr 1709
        set_io  REG_INTERNAL_CONFIG
1710
        in      eax, dx
1711
        and     eax, not (1111b shl 20) ; these bits hold the 'transceiver select' value
1521 hidnplayr 1712
 
2387 hidnplayr 1713
        test    cl, 10b         ; baseTXAvailable
1714
        jz      @f
1521 hidnplayr 1715
 
2387 hidnplayr 1716
        DEBUGF  1,"base TX is available\n"
1717
        or      eax, (100b shl 20)
1472 hidnplayr 1718
if defined FORCE_FD
2387 hidnplayr 1719
        mov     word [device.mode], (1 shl 8)
1472 hidnplayr 1720
else
2387 hidnplayr 1721
        mov     word [device.mode], (1 shl 7)
1472 hidnplayr 1722
end if
2387 hidnplayr 1723
        jmp     .set_media
1521 hidnplayr 1724
       @@:
1725
 
2387 hidnplayr 1726
        test    cl, 100b        ; baseFXAvailable
1727
        jz      @f
1521 hidnplayr 1728
 
2387 hidnplayr 1729
        DEBUGF  1,"base FX is available\n"
1730
        or      eax, (101b shl 20)
1731
        mov     word [device.mode], (1 shl 10)
1732
        jmp     .set_media
1521 hidnplayr 1733
       @@:
1472 hidnplayr 1734
 
2387 hidnplayr 1735
        test    cl, 1000000b    ; miiDevice
1736
        jz      @f
1521 hidnplayr 1737
 
2387 hidnplayr 1738
        DEBUGF  1,"mii-device is available\n"
1739
        or      eax, (0110b shl 20)
1740
        mov     word [device.mode], (1 shl 13)
1741
        jmp     .set_media
1521 hidnplayr 1742
       @@:
1472 hidnplayr 1743
 
2387 hidnplayr 1744
        test    cl, 1000b       ; 10bTAvailable
1745
        jz      @f
1521 hidnplayr 1746
 
2387 hidnplayr 1747
        DEBUGF  1,"10base-T is available\n"
1521 hidnplayr 1748
  .set_default:
1472 hidnplayr 1749
if FORCE_FD
2387 hidnplayr 1750
        mov     word [device.mode], (1 shl 6)
1472 hidnplayr 1751
else
2387 hidnplayr 1752
        mov     word [device.mode], (1 shl 5)
1521 hidnplayr 1753
end if
2387 hidnplayr 1754
        jmp     .set_media
1521 hidnplayr 1755
       @@:
1756
 
2387 hidnplayr 1757
        test    cl, 10000b      ; coaxAvailable
1758
        jz      @f
1521 hidnplayr 1759
 
2387 hidnplayr 1760
        DEBUGF  1,"coax is available\n"
1761
        push    eax
1762
        set_io  REG_COMMAND
1763
        mov     ax, (10b shl 11) ; EnableDcConverter
1764
        out     dx, ax
1765
        pop     eax
1521 hidnplayr 1766
 
2387 hidnplayr 1767
        or      eax, (11b shl 20)
1768
        mov     word [device.mode], (1 shl 12)
1769
        jmp     .set_media
1521 hidnplayr 1770
       @@:
1472 hidnplayr 1771
 
2387 hidnplayr 1772
        test    cl, 10000b      ; auiAvailable
1773
        jz      .set_default
1521 hidnplayr 1774
 
2387 hidnplayr 1775
        DEBUGF  1,"AUI is available\n"
1776
        or      eax, (1 shl 20)
1777
        mov     word [device.mode], (1 shl 11)
1472 hidnplayr 1778
 
1521 hidnplayr 1779
  .set_media:
2387 hidnplayr 1780
        set_io  0
1781
        set_io  REG_INTERNAL_CONFIG
1782
        out     dx, eax
1521 hidnplayr 1783
 
1472 hidnplayr 1784
if FORCE_FD
2387 hidnplayr 1785
        DEBUGF  1,"Forcing full duplex\n"
1786
        set_io  REG_MAC_CONTROL
1787
        in      ax, dx
1788
        or      ax, 0x120
1789
        out     dx, ax
1521 hidnplayr 1790
end if
1791
 
2387 hidnplayr 1792
        mov     al, 1
1793
        ret
1472 hidnplayr 1794
 
1795
 
1796
 
1797
;***************************************************************************
1798
;   Function
1799
;      wake_up
1800
;   Description
1801
;      set the power state to D0
1802
;
1803
;***************************************************************************
1804
 
1805
align 4
1806
wake_up:
1807
 
2387 hidnplayr 1808
        DEBUGF 1,"Waking up NIC: "
1472 hidnplayr 1809
 
1810
; wake up - we directly do it by programming PCI
1811
; check if the device is power management capable
2387 hidnplayr 1812
        movzx   ecx, [device.pci_bus]
1813
        movzx   edx, [device.pci_dev]
1814
        stdcall PciRead32, ecx, edx, PCI_REG_STATUS
1472 hidnplayr 1815
 
2387 hidnplayr 1816
        test    al, 10000b      ; is there "new capabilities" linked list?
1817
        jz      .device_awake
1472 hidnplayr 1818
 
1819
; search for power management register
2387 hidnplayr 1820
        stdcall PciRead16, ecx, edx, PCI_REG_CAP_PTR
1821
        cmp     al, 0x3f
1822
        jbe     .device_awake
1472 hidnplayr 1823
 
1824
; traverse the list
2387 hidnplayr 1825
        movzx   esi, al
1521 hidnplayr 1826
  .pm_loop:
2387 hidnplayr 1827
        stdcall PciRead32, ecx, edx, esi
1472 hidnplayr 1828
 
2387 hidnplayr 1829
        cmp     al , 1
1830
        je      .set_pm_state
1472 hidnplayr 1831
 
2387 hidnplayr 1832
        movzx   esi, ah
1472 hidnplayr 1833
 
2387 hidnplayr 1834
        test    ah , ah
1835
        jnz     .pm_loop
1836
        jmp     .device_awake
1472 hidnplayr 1837
 
1838
; waku up the device if necessary
1521 hidnplayr 1839
  .set_pm_state:
1472 hidnplayr 1840
 
2387 hidnplayr 1841
        add     esi, PCI_REG_PM_CTRL
1842
        stdcall PciRead32, ecx, edx, esi
1843
        test    al, 3
1844
        jz      .device_awake
1845
        and     al, not 11b ; set state to D0
1846
        stdcall PciWrite32, ecx, edx, esi, eax
1472 hidnplayr 1847
 
1521 hidnplayr 1848
  .device_awake:
2387 hidnplayr 1849
        DEBUGF 1,"Device is awake\n"
1472 hidnplayr 1850
 
2387 hidnplayr 1851
        ret
1472 hidnplayr 1852
 
1853
 
1854
 
1855
 
1856
;***************************************************************************
1857
;   Function
1858
;      write_eeprom
1859
;   Description
1860
;      reads eeprom
1861
;      Note : the caller must switch to the register window 0
1862
;             before calling this function
1863
;   Parameters:
1864
;      ax - register to be read (only the first 63 words can be read)
1865
;      cx - value to be read into the register
1866
;   Return value:
1867
;      ax - word read
1868
;   Destroyed registers
1869
;      ax, ebx, edx
1870
;
1871
;***************************************************************************
1872
;       align 4
1873
;write_eeprom:
1874
;       mov     edx, [io_addr]
1875
;       add     edx, REG_EEPROM_COMMAND
1876
;       cmp     ah, 11b
1877
;       ja      .finish ; address may have a value of maximal 1023
1878
;       shl     ax, 2
1879
;       shr     al, 2
1880
;       push    eax
1881
;; wait for busy
1882
;       mov     ebx, 0xffff
1883
;@@:
1884
;       in      ax, dx
1885
;       test    ah, 0x80
1886
;       jz      .write_enable
1887
;       dec     ebx
1888
;       jns     @r
1889
;; write enable
1890
;.write_enable:
1891
;       xor     eax, eax
1892
;       mov     eax, (11b shl 4)
1893
;       out     dx, ax
1894
;; wait for busy
1895
;       mov     ebx, 0xffff
1896
;@@:
1897
;       in      ax, dx
1898
;       test    ah, 0x80
1899
;       jz      .erase_loop
1900
;       dec     ebx
1901
;       jns     @r
1902
;.erase_loop:
1903
;       pop     eax
1904
;       push    eax
1905
;       or      ax, (11b shl 6) ; erase register
1906
;       out     dx, ax
1907
;       mov     ebx, 0xffff
1908
;@@:
1909
;       in      ax, dx
1910
;       test    ah, 0x80
1911
;       jz      .write_reg
1912
;       dec     ebx
1913
;       jns     @r
1914
;.write_reg:
1915
;       add     edx, REG_EEPROM_DATA-REG_EEPROM_COMMAND
1916
;       mov     eax, ecx
1917
;       out     dx, ax
1918
;; write enable
1919
;       add     edx, REG_EEPROM_COMMAND-REG_EEPROM_DATA
1920
;       xor     eax, eax
1921
;       mov     eax, (11b shl 4)
1922
;       out     dx, ax
1923
; wait for busy
1924
;       mov     ebx, 0xffff
1925
;@@:
1926
;       in      ax, dx
1927
;       test    ah, 0x80
1928
;       jz      .issue_write_reg
1929
;       dec     ebx
1930
;       jns     @r
1931
;.issue_write_reg:
1932
;       pop     eax
1933
;       or      ax, 01b shl 6
1934
;       out     dx, ax
1935
;.finish:
1936
;       ret
1521 hidnplayr 1937
 
1938
 
1472 hidnplayr 1939
;***************************************************************************
1940
;   Function
1941
;      read_eeprom
1942
;   Description
1943
;      reads eeprom
1944
;   Parameters:
1945
;       ax - register to be read (only the first 63 words can be read)
1946
;      ebx = driver structure
1947
;   Return value:
1948
;      ax - word read
1949
;   Destroyed registers
1521 hidnplayr 1950
;      ax, ebx, edx
1472 hidnplayr 1951
;
1952
;***************************************************************************
1953
 
1954
align 4
1955
read_eeprom:
1956
 
2387 hidnplayr 1957
        DEBUGF 1,"Reading from eeprom.. "
1472 hidnplayr 1958
 
2387 hidnplayr 1959
        push    eax
1472 hidnplayr 1960
; switch to register window 0
2387 hidnplayr 1961
        set_io  0
1962
        set_io  REG_COMMAND
1963
        mov     ax, SELECT_REGISTER_WINDOW+0
1964
        out     dx, ax
1965
        pop     eax
1966
        and     ax, 111111b ; take only the first 6 bits into account
1967
        movzx   esi, [device.ver_id]
1472 hidnplayr 1968
 
2387 hidnplayr 1969
        test    word [esi*4+hw_versions+2], EEPROM_8BIT
1970
        jz      @f
1971
        add     ax, 0x230 ; hardware constant
1972
        jmp     .read
1472 hidnplayr 1973
@@:
1974
 
2387 hidnplayr 1975
        add     ax, EEPROM_CMD_READ
1976
        test    word [esi*4+hw_versions+2], EEPROM_OFFSET
1977
        jz      .read
1978
        add     ax, 0x30
1472 hidnplayr 1979
.read:
1980
 
2387 hidnplayr 1981
        set_io  REG_EEPROM_COMMAND
1982
        out     dx, ax
1983
        mov     ecx, 0xffff ; duration of about 162 us ;-)
1472 hidnplayr 1984
.wait_for_reading:
2387 hidnplayr 1985
        in      ax, dx
1986
        test    ah, 0x80 ; check bit eepromBusy
1987
        jz      .read_data
1988
        loop    .wait_for_reading
1472 hidnplayr 1989
.read_data:
2387 hidnplayr 1990
        set_io  REG_EEPROM_DATA
1991
        in      ax, dx
1472 hidnplayr 1992
 
2387 hidnplayr 1993
        DEBUGF 1,"ok!\n"
1472 hidnplayr 1994
 
2387 hidnplayr 1995
        ret
1472 hidnplayr 1996
 
1997
;***************************************************************************
1998
;   Function
1999
;      mdio_sync
2000
;   Description
2001
;      initial synchronization
2002
;   Parameters
2003
;      ebp - io_addr
2004
;   Return value
2005
;   Destroyed registers
2006
;      ax, edx, cl
2007
;
2008
;***************************************************************************
2009
 
2010
align 4
2011
mdio_sync:
2012
 
2387 hidnplayr 2013
        DEBUGF 1,"syncing mdio\n"
1472 hidnplayr 2014
 
2015
; switch to register window 4
2387 hidnplayr 2016
        set_io  0
2017
        set_io  REG_COMMAND
2018
        mov     ax, SELECT_REGISTER_WINDOW+4
2019
        out     dx, ax
2020
        cmp     [device.preamble], 0
2021
        je      .no_preamble
1472 hidnplayr 2022
; send 32 logic ones
2387 hidnplayr 2023
        set_io  REG_PHYSICAL_MGMT
2024
        mov     ecx, 31
1521 hidnplayr 2025
  .loop:
2387 hidnplayr 2026
        mov     ax, (1 shl BIT_MGMT_DATA) or (1 shl BIT_MGMT_DIR)
2027
        out     dx, ax
2028
        in      ax, dx ; delay
2029
        mov     ax, (1 shl BIT_MGMT_DATA) or (1 shl BIT_MGMT_DIR) or (1 shl BIT_MGMT_CLK)
2030
        out     dx, ax
2031
        in      ax, dx ; delay
2032
        loop    .loop
1521 hidnplayr 2033
  .no_preamble:
1472 hidnplayr 2034
 
2387 hidnplayr 2035
        ret
1472 hidnplayr 2036
 
2037
;***************************************************************************
2038
;   Function
2039
;      mdio_read
2040
;   Description
2041
;      read MII register
2042
;      see page 16 in D83840A.pdf
2043
;   Parameters
2044
;       ah - PHY addr
2045
;       al - register addr
2046
;      ebx = device structure
2047
;   Return value
2048
;      ax - register read
2049
;
2050
;***************************************************************************
2051
 
2052
align 4
2053
mdio_read:
2054
 
2387 hidnplayr 2055
        DEBUGF 1,"Reading MII registers\n"
1472 hidnplayr 2056
 
2387 hidnplayr 2057
        push    eax
2058
        call    mdio_sync ; returns with window #4
2059
        pop     eax
2060
        set_io  0
2061
        set_io  REG_PHYSICAL_MGMT
2062
        shl     al, 3
2063
        shr     ax, 3
2064
        and     ax, not MII_CMD_MASK
2065
        or      ax, MII_CMD_READ
1472 hidnplayr 2066
 
2387 hidnplayr 2067
        mov     esi, eax
2068
        mov     ecx, 13
1521 hidnplayr 2069
  .cmd_loop:
2387 hidnplayr 2070
        mov     ax, (1 shl BIT_MGMT_DIR) ; write mii
2071
        bt      esi, ecx
2072
        jnc     .zero_bit
2073
        or      al, (1 shl BIT_MGMT_DATA)
1472 hidnplayr 2074
 
1521 hidnplayr 2075
  .zero_bit:
2387 hidnplayr 2076
        out     dx, ax
2077
        push    ax
2078
        in      ax, dx ; delay
2079
        pop     ax
2080
        or      al, (1 shl BIT_MGMT_CLK) ; write
2081
        out     dx, ax
2082
        in      ax, dx ; delay
2083
        loop    .cmd_loop
1472 hidnplayr 2084
 
2085
; read data (18 bits with the two transition bits)
2387 hidnplayr 2086
        mov     ecx, 17
2087
        xor     esi, esi
1521 hidnplayr 2088
  .read_loop:
2387 hidnplayr 2089
        shl     esi, 1
2090
        xor     eax, eax ; read comand
2091
        out     dx, ax
2092
        in      ax, dx ; delay
2093
        in      ax, dx
2094
        test    al, (1 shl BIT_MGMT_DATA)
2095
        jz      .dont_set
2096
        inc     esi
1521 hidnplayr 2097
  .dont_set:
2387 hidnplayr 2098
        mov     ax, (1 shl BIT_MGMT_CLK)
2099
        out     dx, ax
2100
        in      ax, dx ; delay
2101
        loop    .read_loop
2102
        mov     eax, esi
1472 hidnplayr 2103
 
2387 hidnplayr 2104
        ret
1472 hidnplayr 2105
 
2106
 
2107
 
2108
;***************************************************************************
2109
;   Function
2110
;      mdio_write
2111
;   Description
2112
;      write MII register
2113
;      see page 16 in D83840A.pdf
2114
;   Parameters
2115
;       ah - PHY addr
2116
;       al - register addr
2117
;       si - word to be written
2118
;   Return value
2119
;      ax - register read
2120
;
2121
;***************************************************************************
2122
 
2123
align 4
2124
mdio_write:
2125
 
2387 hidnplayr 2126
        DEBUGF 1,"Writing MII registers\n"
1472 hidnplayr 2127
 
2387 hidnplayr 2128
        push    eax
2129
        call    mdio_sync
2130
        pop     eax
2131
        set_io  0
2132
        set_io  REG_PHYSICAL_MGMT
2133
        shl     al, 3
2134
        shr     ax, 3
2135
        and     ax, not MII_CMD_MASK
2136
        or      ax, MII_CMD_WRITE
2137
        shl     eax, 2
2138
        or      eax, 10b ; transition bits
2139
        shl     eax, 16
2140
        mov     ax, si
2141
        mov     esi, eax
2142
        mov     ecx, 31
1521 hidnplayr 2143
 
2144
  .cmd_loop:
2387 hidnplayr 2145
        mov     ax, (1 shl BIT_MGMT_DIR) ; write mii
2146
        bt      esi, ecx
2147
        jnc     @f
2148
        or      al, (1 shl BIT_MGMT_DATA)
1521 hidnplayr 2149
       @@:
2387 hidnplayr 2150
        out     dx, ax
2151
        push    eax
2152
        in      ax, dx ; delay
2153
        pop     eax
2154
        or      al, (1 shl BIT_MGMT_CLK) ; write
2155
        out     dx, ax
2156
        in      ax, dx ; delay
2157
        loop    .cmd_loop
1472 hidnplayr 2158
 
2387 hidnplayr 2159
        ret
1472 hidnplayr 2160
 
2161
 
2162
;***************************************************************************
2163
;   Function
2164
;      check_tx_status
2165
;   Description
2166
;      Checks TxStatus queue.
2167
;   Return value
2168
;      al - 0 no error was found
1545 hidnplayr 2169
;      al - 1 error was found TxReset was needed
1472 hidnplayr 2170
;   Destroyed registers
2171
;      eax, ecx, edx, ebp
2172
;
2173
;***************************************************************************
2174
 
2175
align 4
2176
check_tx_status:
2177
 
2387 hidnplayr 2178
        DEBUGF 1,"Checking TX status\n"
1472 hidnplayr 2179
 
2180
; clear TxStatus queue
2387 hidnplayr 2181
        set_io  0
2182
        set_io  REG_TX_STATUS
2183
        mov     ecx, 31 ; max number of queue entries
1521 hidnplayr 2184
 
2185
  .tx_status_loop:
2387 hidnplayr 2186
        in      al, dx
2187
        test    al, al
2188
        jz      .finish ; no error
2189
        test    al, 0x3f
2190
        jnz     .error
1521 hidnplayr 2191
  .no_error_found:
1472 hidnplayr 2192
; clear current TxStatus entry which advances the next one
2387 hidnplayr 2193
        xor     al, al
2194
        out     dx, al
2195
        loop    .tx_status_loop
1472 hidnplayr 2196
 
1521 hidnplayr 2197
  .finish:
2198
 
2387 hidnplayr 2199
        ret
1472 hidnplayr 2200
 
1545 hidnplayr 2201
  .error:
2387 hidnplayr 2202
        call    tx_reset
2203
        ret
1472 hidnplayr 2204
 
2205
 
1545 hidnplayr 2206
 
1472 hidnplayr 2207
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2208
;;                                         ;;
2209
;; Transmit (vortex)                       ;;
2210
;;                                         ;;
2211
;; In: buffer pointer in [esp+4]           ;;
2212
;;     size of buffer in [esp+8]           ;;
2213
;;     pointer to device structure in ebx  ;;
2214
;;                                         ;;
2215
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2216
 
2217
align 4
2218
vortex_transmit:
2219
 
2387 hidnplayr 2220
        DEBUGF 1,"Sending packet (vortex)\n"
1472 hidnplayr 2221
 
2387 hidnplayr 2222
        cmp     dword [esp+8], MAX_ETH_FRAME_SIZE
2223
        ja      .finish ; packet is too long
1472 hidnplayr 2224
 
2387 hidnplayr 2225
        call    check_tx_status
1472 hidnplayr 2226
 
2227
; switch to register window 7
2387 hidnplayr 2228
        set_io  0
2229
        set_io  REG_COMMAND
2230
        mov     ax, SELECT_REGISTER_WINDOW+7
2231
        out     dx, ax
1472 hidnplayr 2232
; check for master operation in progress
2387 hidnplayr 2233
        set_io  REG_MASTER_STATUS
2234
        in      ax, dx
2235
        test    ah, 0x80
2236
        jnz     .finish ; no DMA for sending
1472 hidnplayr 2237
; program frame address to be sent
2387 hidnplayr 2238
        set_io  REG_MASTER_ADDRESS
2239
        mov     eax, [esp+4]
2240
        call    GetPgAddr
2241
        out     dx, eax
1472 hidnplayr 2242
; program frame length
2387 hidnplayr 2243
        set_io  REG_MASTER_LEN
2244
        mov     eax, [esp+8]
1472 hidnplayr 2245
;;;        and     eax, not 3
2387 hidnplayr 2246
        out     dx, ax
1472 hidnplayr 2247
; start DMA Down
2387 hidnplayr 2248
        set_io  REG_COMMAND
2249
        mov     ax, (10100b shl 11) + 1 ; StartDMADown
2250
        out     dx, ax
1472 hidnplayr 2251
.finish:
2387 hidnplayr 2252
        call    KernelFree
2253
        add     esp, 4
2254
        ret
1472 hidnplayr 2255
 
2256
 
2257
 
2258
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2259
;;                                         ;;
2260
;; Transmit (boomerang)                    ;;
2261
;;                                         ;;
2262
;; In: buffer pointer in [esp+4]           ;;
2263
;;     size of buffer in [esp+8]           ;;
2264
;;     pointer to device structure in ebx  ;;
2265
;;                                         ;;
2266
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2267
 
2268
align 4
2269
boomerang_transmit:
2270
 
2387 hidnplayr 2271
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8]
2272
        mov     eax, [esp+4]
2273
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
2274
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
2275
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
2276
        [eax+13]:2,[eax+12]:2
1472 hidnplayr 2277
 
2387 hidnplayr 2278
        cmp     dword [esp+8], MAX_ETH_FRAME_SIZE
2279
        jg      .fail
1472 hidnplayr 2280
 
2387 hidnplayr 2281
        call    check_tx_status
1519 hidnplayr 2282
 
1472 hidnplayr 2283
; calculate descriptor address
2387 hidnplayr 2284
        mov     esi, [device.prev_dpd]
2285
        DEBUGF  1,"Previous DPD: %x\n", esi
2286
        add     esi, dpd.size
2287
        lea     ecx, [device.dpd_buffer + (NUM_TX_DESC)*dpd.size]
2288
        cmp     esi, ecx
2289
        jl      @f
2290
        lea     esi, [device.dpd_buffer]        ; Wrap if needed
1519 hidnplayr 2291
       @@:
2387 hidnplayr 2292
        DEBUGF  1,"Found a free DPD: %x\n", esi
1472 hidnplayr 2293
 
2294
; check DnListPtr
2387 hidnplayr 2295
        set_io  0
2296
        set_io  REG_DN_LIST_PTR
2297
        in      eax, dx
1472 hidnplayr 2298
; mark if Dn_List_Ptr is cleared
2387 hidnplayr 2299
        test    eax, eax
2300
        setz    [device.dn_list_ptr_cleared]
1519 hidnplayr 2301
 
1472 hidnplayr 2302
; finish if no more free descriptor is available - FIXME!
1519 hidnplayr 2303
;        cmp     eax, esi
2304
;        jz      .finish
1472 hidnplayr 2305
 
1481 hidnplayr 2306
; update statistics
2387 hidnplayr 2307
        inc     [device.packets_tx]
2308
        mov     ecx, [esp+8]            ; buffer size
2309
        add     dword [device.bytes_tx], ecx
2310
        adc     dword [device.bytes_tx + 4], 0
1481 hidnplayr 2311
 
1472 hidnplayr 2312
; program DPD
2387 hidnplayr 2313
        and     [esi+dpd.next_ptr], 0
2314
        mov     eax, [esp+4]            ; Tx buffer address
2315
        mov     [esi+dpd.realaddr], eax
2316
        call    GetPgAddr
2317
        mov     [esi+dpd.frag_addr], eax
2318
        mov     ecx, [esp+8]            ; packet size
2319
        or      ecx, 0x80000000         ; last fragment
2320
        mov     [esi+dpd.frag_len], ecx
1472 hidnplayr 2321
 
2387 hidnplayr 2322
        mov     ecx, [esp+8]            ; packet size
1519 hidnplayr 2323
;        or      ecx, 0x8000             ; transmission complete notification
1472 hidnplayr 2324
 
2387 hidnplayr 2325
        or      ecx, 1 shl 31
1472 hidnplayr 2326
 
2327
;        test    byte [device.has_hwcksm], 0xff
2328
;        jz      @f
1519 hidnplayr 2329
;        or      ecx, (1 shl 26)         ; set AddTcpChecksum
1472 hidnplayr 2330
;@@:
2387 hidnplayr 2331
        mov     [esi+dpd.frame_start_hdr], ecx
1472 hidnplayr 2332
 
2387 hidnplayr 2333
        DEBUGF  1,"DPD: lin=%x phys=%x len=%x start hdr=%x\n", [esi+dpd.realaddr]:8, [esi+dpd.frag_addr]:8, [esi+dpd.frag_len]:8, [esi+dpd.frame_start_hdr]:8
1472 hidnplayr 2334
 
1519 hidnplayr 2335
; calculate physical address of dpd
2387 hidnplayr 2336
        mov     eax, esi
2337
        GetRealAddr
2338
        cmp     [device.dn_list_ptr_cleared], 0
2339
        jz      .add_to_list
1472 hidnplayr 2340
 
2341
; write Dn_List_Ptr
2387 hidnplayr 2342
        DEBUGF  1,"DPD phys addr=%x\n", eax
2343
        set_io  0
2344
        set_io  REG_DN_LIST_PTR
2345
        out     dx, eax
2346
        jmp     .finish
1472 hidnplayr 2347
 
1519 hidnplayr 2348
  .add_to_list:
2387 hidnplayr 2349
        DEBUGF  1,"Adding To list\n"
2350
        push    eax
1472 hidnplayr 2351
; DnStall
2387 hidnplayr 2352
        set_io  0
2353
        set_io  REG_COMMAND
2354
        mov     ax, ((110b shl 11)+2)
2355
        out     dx, ax
1472 hidnplayr 2356
 
2357
; wait for DnStall to complete
2387 hidnplayr 2358
        DEBUGF  1,"Waiting for DnStall\n"
2359
        mov     ecx, 6000
1519 hidnplayr 2360
  .wait_for_stall:
2387 hidnplayr 2361
        in      ax, dx                  ; read REG_INT_STATUS
2362
        test    ah, 10000b
2363
        jz      .dnstall_ok
2364
        dec     ecx
2365
        jnz     .wait_for_stall
1472 hidnplayr 2366
 
1519 hidnplayr 2367
  .dnstall_ok:
2387 hidnplayr 2368
        DEBUGF  1,"DnStall ok!\n"
2369
        mov     ecx, [device.prev_dpd]
2370
        mov     [ecx+dpd.next_ptr], eax
1472 hidnplayr 2371
 
2387 hidnplayr 2372
        set_io  0
2373
        set_io  REG_DN_LIST_PTR
2374
        in      eax, dx
2375
        test    eax, eax
2376
        pop     eax
2377
        jnz     .dnunstall
1519 hidnplayr 2378
 
1472 hidnplayr 2379
; if Dn_List_Ptr has been cleared fill it up
2387 hidnplayr 2380
        DEBUGF  1,"DnList Ptr has been cleared\n"
2381
        out     dx, eax
1472 hidnplayr 2382
 
1519 hidnplayr 2383
  .dnunstall:
1472 hidnplayr 2384
; DnUnStall
2387 hidnplayr 2385
        set_io  0
2386
        set_io  REG_COMMAND
2387
        mov     ax, ((110b shl 11)+3)
2388
        out     dx, ax
1472 hidnplayr 2389
 
1519 hidnplayr 2390
  .finish:
2387 hidnplayr 2391
        mov     [device.prev_dpd], esi
2392
        xor     eax, eax
2393
        ret     8
1472 hidnplayr 2394
 
1519 hidnplayr 2395
  .fail:
2387 hidnplayr 2396
        stdcall KernelFree, [esp+4]
2397
        or      eax, -1
2398
        ret     8
1472 hidnplayr 2399
 
1519 hidnplayr 2400
 
1472 hidnplayr 2401
;---------------------------------
2402
; Write MAC
2403
 
2404
align 4
1521 hidnplayr 2405
write_mac:
1472 hidnplayr 2406
 
2387 hidnplayr 2407
        DEBUGF 1,"Writing mac\n"
1472 hidnplayr 2408
 
2387 hidnplayr 2409
        set_io  0
2410
        set_io  REG_COMMAND
1472 hidnplayr 2411
 
2412
; switch to register window 2
2387 hidnplayr 2413
        mov     ax, SELECT_REGISTER_WINDOW+2
2414
        out     dx, ax
1472 hidnplayr 2415
 
2416
; write MAC addres back into the station address registers
2387 hidnplayr 2417
        set_io  REG_STATION_ADDRESS_LO
2418
        lea     esi, [device.mac]
2419
        outsw
2420
        inc     dx
2421
        inc     dx
2422
        outsw
2423
        inc     dx
2424
        inc     dx
2425
        outsw
1472 hidnplayr 2426
 
1521 hidnplayr 2427
 
1472 hidnplayr 2428
;----------------------------
2429
; Read MAC
2430
 
2431
align 4
1521 hidnplayr 2432
read_mac:
1472 hidnplayr 2433
 
2387 hidnplayr 2434
        set_io  0
2435
        set_io  REG_COMMAND
1472 hidnplayr 2436
 
2437
; switch to register window 2
2387 hidnplayr 2438
        mov     ax, SELECT_REGISTER_WINDOW+2
2439
        out     dx, ax
1472 hidnplayr 2440
 
2441
; write MAC addres back into the station address registers
2387 hidnplayr 2442
        set_io  REG_STATION_ADDRESS_LO
2443
        lea     edi, [device.mac]
2444
        insw
2445
        inc     dx
2446
        inc     dx
2447
        insw
2448
        inc     dx
2449
        inc     dx
2450
        insw
1472 hidnplayr 2451
 
2387 hidnplayr 2452
        DEBUGF 1,"%x-%x-%x-%x-%x-%x\n",[device.mac]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2
1472 hidnplayr 2453
 
2387 hidnplayr 2454
        ret
1472 hidnplayr 2455
 
2456
 
2457
;------------------------------------
2458
; Read MAC from eeprom
2459
 
2460
align 4
2387 hidnplayr 2461
read_mac_eeprom:        ; Tested - ok
1472 hidnplayr 2462
 
2387 hidnplayr 2463
        DEBUGF 1,"Reading mac from eeprom\n"
1472 hidnplayr 2464
 
2465
; read MAC from eeprom
2387 hidnplayr 2466
        mov     ecx, 3
1521 hidnplayr 2467
  .mac_loop:
2387 hidnplayr 2468
        lea     ax, [EEPROM_REG_OEM_NODE_ADDR+ecx-1]
2469
        push    ecx
2470
        call    read_eeprom
2471
        pop     ecx
2472
        xchg    ah, al ; htons
2473
        mov     word [device.mac+ecx*2-2], ax
2474
        loop    .mac_loop
1472 hidnplayr 2475
 
2387 hidnplayr 2476
        DEBUGF 1,"%x-%x-%x-%x-%x-%x\n",[device.mac]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2
1472 hidnplayr 2477
 
2387 hidnplayr 2478
        ret
1472 hidnplayr 2479
 
2480
 
2481
 
2482
 
2483
 
2484
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2485
;;                          ;;
2486
;; Vortex Interrupt handler ;;
2487
;;                          ;;
2488
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2489
 
2490
align 4
2491
int_vortex:
2492
 
2387 hidnplayr 2493
        DEBUGF  1,"vortex IRQ %x ",eax:2
1472 hidnplayr 2494
 
2495
; find pointer of device wich made IRQ occur
2496
 
2387 hidnplayr 2497
        mov     esi, VORTEX_LIST
2498
        mov     ecx, [VORTEX_DEVICES]
2499
        test    ecx, ecx
2500
        jz      .fail
1472 hidnplayr 2501
  .nextdevice:
2387 hidnplayr 2502
        mov     ebx, dword [esi]
1472 hidnplayr 2503
 
2504
 
2387 hidnplayr 2505
        set_io  0
2506
        set_io  REG_INT_STATUS
2507
        in      ax, dx
1472 hidnplayr 2508
;;        and     ax, INT_MASK
2387 hidnplayr 2509
        jnz     .got_it
1472 hidnplayr 2510
 
2511
 
2387 hidnplayr 2512
        add     esi, 4
1472 hidnplayr 2513
 
2387 hidnplayr 2514
        test    ax , ax
2515
        jnz     .got_it
2516
        loop    .nextdevice
1472 hidnplayr 2517
 
2518
  .fail:
2519
 
2387 hidnplayr 2520
        ret
1472 hidnplayr 2521
 
2522
.got_it:
2523
 
2387 hidnplayr 2524
        DEBUGF  1,"Device: %x Status: %x ",ebx,eax:4
1472 hidnplayr 2525
 
2387 hidnplayr 2526
        test    ax, RxComplete
2527
        jz      .noRX
1472 hidnplayr 2528
 
2387 hidnplayr 2529
        set_io  0
1472 hidnplayr 2530
  .rx_status_loop:
2531
; examine RxStatus
2387 hidnplayr 2532
        set_io  REG_RX_STATUS
2533
        in      ax, dx
2534
        test    ax, ax
2535
        jz      .finish
1472 hidnplayr 2536
 
2387 hidnplayr 2537
        test    ah, 0x80 ; rxIncomplete
2538
        jnz     .finish
1472 hidnplayr 2539
 
2387 hidnplayr 2540
        test    ah, 0x40
2541
        jz      .check_length
1472 hidnplayr 2542
 
2543
; discard the top frame received advancing the next one
2387 hidnplayr 2544
        set_io  REG_COMMAND
2545
        mov     ax, (01000b shl 11)
2546
        out     dx, ax
2547
        jmp     .rx_status_loop
1472 hidnplayr 2548
 
2549
  .check_length:
2387 hidnplayr 2550
        and     eax, 0x1fff
2551
        cmp     eax, MAX_ETH_PKT_SIZE
2552
        ja      .discard_frame ; frame is too long discard it
1472 hidnplayr 2553
 
2554
  .check_dma:
2387 hidnplayr 2555
        mov     ecx, eax
1472 hidnplayr 2556
; switch to register window 7
2387 hidnplayr 2557
        set_io  0
2558
        set_io  REG_COMMAND
2559
        mov     ax, SELECT_REGISTER_WINDOW+7
2560
        out     dx, ax
1472 hidnplayr 2561
; check for master operation in progress
2387 hidnplayr 2562
        set_io  REG_MASTER_STATUS
2563
        in      ax, dx
1472 hidnplayr 2564
 
2387 hidnplayr 2565
        test    ah, 0x80
2566
        jnz     .finish
1472 hidnplayr 2567
 
2568
  .read_frame:
2569
; program buffer address to read in
2387 hidnplayr 2570
        push    ecx
2571
        stdcall KernelAlloc, MAX_ETH_FRAME_SIZE
2572
        pop     ecx
2573
        test    eax, eax
2574
        jz      .finish
1472 hidnplayr 2575
 
2387 hidnplayr 2576
        push    .discard_frame
2577
        push    ecx
2578
        push    eax
1472 hidnplayr 2579
;        zero_to_dma eax
2387 hidnplayr 2580
        set_io  REG_MASTER_ADDRESS
2581
        out     dx, eax
1472 hidnplayr 2582
 
2583
; program frame length
2387 hidnplayr 2584
        set_io  REG_MASTER_LEN
2585
        mov     ax, 1560
2586
        out     dx, ax
1472 hidnplayr 2587
 
2588
; start DMA Up
2387 hidnplayr 2589
        set_io  REG_COMMAND
2590
        mov     ax, (10100b shl 11) ; StartDMAUp
2591
        out     dx, ax
1472 hidnplayr 2592
 
2593
; check for master operation in progress
2387 hidnplayr 2594
        set_io  REG_MASTER_STATUS   ; TODO: use timeout and reset after timeout expired
1472 hidnplayr 2595
  .dma_loop:
2387 hidnplayr 2596
        in      ax, dx
2597
        test    ah, 0x80
2598
        jnz     .dma_loop
1472 hidnplayr 2599
 
2600
; registrate the received packet to kernel
2387 hidnplayr 2601
        jmp     EthReceiver
1472 hidnplayr 2602
 
2603
; discard the top frame received
2604
  .discard_frame:
2387 hidnplayr 2605
        set_io  0
2606
        set_io  REG_COMMAND
2607
        mov     ax, (01000b shl 11)
2608
        out     dx, ax
1472 hidnplayr 2609
 
2610
  .finish:
2611
 
2612
 
2613
.noRX:
2614
 
2387 hidnplayr 2615
        test    ax, DMADone
2616
        jz      .noDMA
1472 hidnplayr 2617
 
2387 hidnplayr 2618
        push    ax
1472 hidnplayr 2619
 
2387 hidnplayr 2620
        set_io  0
2621
        set_io  12
2622
        in      ax, dx
2623
        test    ax, 0x1000
2624
        jz      .nodmaclear
1472 hidnplayr 2625
 
2387 hidnplayr 2626
        mov     ax, 0x1000
2627
        out     dx, ax
1472 hidnplayr 2628
 
2629
  .nodmaclear:
2630
 
2387 hidnplayr 2631
        pop     ax
1472 hidnplayr 2632
 
2387 hidnplayr 2633
        DEBUGF  1, "DMA Done!\n", cx
1472 hidnplayr 2634
 
2635
 
2636
 
2637
.noDMA:
2638
 
2639
 
2640
 
2641
.ACK:
2387 hidnplayr 2642
        set_io  0
2643
        set_io  REG_COMMAND
2644
        mov     ax, AckIntr + IntReq + IntLatch
2645
        out     dx, ax
1472 hidnplayr 2646
 
2387 hidnplayr 2647
        ret
1472 hidnplayr 2648
 
2649
 
2650
 
2651
 
2652
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2653
;;                             ;;
2654
;; Boomerang Interrupt handler ;;
2655
;;                             ;;
2656
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2657
 
2658
align 4
2659
int_boomerang:
2660
 
2387 hidnplayr 2661
        DEBUGF  1,"\nIRQ %x Boomerang\n",eax:2
1472 hidnplayr 2662
 
2663
; find pointer of device wich made IRQ occur
2664
 
2387 hidnplayr 2665
        mov     esi, BOOMERANG_LIST
2666
        mov     ecx, [BOOMERANG_DEVICES]
1472 hidnplayr 2667
 
2387 hidnplayr 2668
        test    ecx, ecx
2669
        jz      .fail
1472 hidnplayr 2670
  .nextdevice:
2387 hidnplayr 2671
        mov     ebx, dword[esi]
1472 hidnplayr 2672
 
2387 hidnplayr 2673
        set_io  0
2674
        set_io  REG_INT_STATUS
2675
        in      ax, dx
2676
        test    ax, IntLatch
2677
        jnz     .got_it
1472 hidnplayr 2678
 
2387 hidnplayr 2679
        add     esi, 4
1472 hidnplayr 2680
 
2387 hidnplayr 2681
        test    ax , ax
2682
        jnz     .got_it
2683
        dec     ecx
2684
        jnz     .nextdevice
1472 hidnplayr 2685
 
2686
  .fail:
2387 hidnplayr 2687
        DEBUGF  1,"Failed!\n"
2688
        ret
1472 hidnplayr 2689
 
2690
.got_it:
2691
 
2387 hidnplayr 2692
        DEBUGF  1,"Device: %x Status: %x ", ebx, eax
2693
        push    ax
1472 hidnplayr 2694
; disable all INTS
2695
 
2387 hidnplayr 2696
        set_io  REG_COMMAND
2697
        mov     ax, SetIntrEnb
2698
        out     dx, ax
1472 hidnplayr 2699
 
2700
;--------------------------------------------------------------------------
2387 hidnplayr 2701
        test    word[esp], UpComplete
2702
        jz      .noRX
1472 hidnplayr 2703
 
2387 hidnplayr 2704
        push    ebx
1472 hidnplayr 2705
 
2706
  .receive:
2387 hidnplayr 2707
        DEBUGF  1,"UpComplete\n"
1472 hidnplayr 2708
 
2709
; check if packet is uploaded
2387 hidnplayr 2710
        mov     esi, [device.curr_upd]
2711
        test    byte [esi+upd.pkt_status+1], 0x80 ; upPktComplete
2712
        jz      .finish
2713
        DEBUGF  1, "Current upd: %x\n", esi
1472 hidnplayr 2714
; packet is uploaded check for any error
2715
  .check_error:
2387 hidnplayr 2716
        test    byte [esi+upd.pkt_status+1], 0x40 ; upError
2717
        jz      .copy_packet_length
2718
        DEBUGF  1,"Error in packet\n"
2719
        and     [esi+upd.pkt_status], 0           ; mark packet as read
2720
        jmp     .finish
1472 hidnplayr 2721
  .copy_packet_length:
2387 hidnplayr 2722
        mov     ecx, [esi+upd.pkt_status]
2723
        and     ecx, 0x1fff
1472 hidnplayr 2724
 
1519 hidnplayr 2725
;        cmp     ecx, MAX_ETH_PKT_SIZE
2726
;        jbe     .copy_packet
2727
;        and     [esi+upd.pkt_status], 0
2728
;        jmp     .finish
2729
;  .copy_packet:
1472 hidnplayr 2730
 
2387 hidnplayr 2731
        DEBUGF  1, "Received %u bytes in buffer %x\n", ecx, [esi+upd.realaddr]:8
1472 hidnplayr 2732
 
2387 hidnplayr 2733
        push    dword .loop ;.finish
2734
        push    ecx
2735
        push    [esi+upd.realaddr]
1472 hidnplayr 2736
 
1481 hidnplayr 2737
; update statistics
2387 hidnplayr 2738
        inc     [device.packets_rx]
2739
        add     dword [device.bytes_rx], ecx
2740
        adc     dword [device.bytes_rx + 4], 0
1481 hidnplayr 2741
 
1519 hidnplayr 2742
; update UPD (Alloc new buffer for next packet)
2387 hidnplayr 2743
        stdcall KernelAlloc, MAX_ETH_FRAME_SIZE
2744
        mov     [esi + upd.realaddr], eax
2745
        GetRealAddr
2746
        mov     [esi + upd.frag_addr], eax
2747
        and     [esi + upd.pkt_status], 0
2748
        mov     [esi + upd.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31)
1472 hidnplayr 2749
 
1519 hidnplayr 2750
; Update UPD pointer
2387 hidnplayr 2751
        add     esi, upd.size
2752
        lea     ecx, [device.upd_buffer+(NUM_RX_DESC)*upd.size]
2753
        cmp     esi, ecx
2754
        jl      @f
2755
        lea     esi, [device.upd_buffer]
1519 hidnplayr 2756
       @@:
2387 hidnplayr 2757
        mov     [device.curr_upd], esi
2758
        DEBUGF  1, "Next upd: %x\n", esi
1472 hidnplayr 2759
 
2387 hidnplayr 2760
        jmp     EthReceiver
1519 hidnplayr 2761
  .loop:
1472 hidnplayr 2762
 
2387 hidnplayr 2763
        mov     ebx, [esp]
2764
        jmp     .receive
1472 hidnplayr 2765
 
2766
  .finish:
2387 hidnplayr 2767
        pop     ebx
1472 hidnplayr 2768
 
2769
; check if the NIC is in the upStall state
2387 hidnplayr 2770
        set_io  0
2771
        set_io  REG_UP_PKT_STATUS
2772
        in      eax, dx
2773
        test    ah, 0x20             ; UpStalled
2774
        jz      .noUpUnStall
1519 hidnplayr 2775
 
2387 hidnplayr 2776
        DEBUGF  1, "upUnStalling\n"
1472 hidnplayr 2777
; issue upUnStall command
2387 hidnplayr 2778
        set_io  REG_COMMAND
2779
        mov     ax, ((11b shl 12)+1) ; upUnStall
2780
        out     dx, ax
1519 hidnplayr 2781
 
2387 hidnplayr 2782
        ;;;; FIXME: make upunstall work
1519 hidnplayr 2783
 
1472 hidnplayr 2784
  .noUpUnStall:
1519 hidnplayr 2785
.noRX:
2387 hidnplayr 2786
        test    word[esp], DownComplete
2787
        jz      .noTX
2788
        DEBUGF  1, "Downcomplete!\n"
1472 hidnplayr 2789
 
2387 hidnplayr 2790
        mov     ecx, NUM_TX_DESC
2791
        lea     esi, [device.dpd_buffer]
1519 hidnplayr 2792
  .txloop:
2387 hidnplayr 2793
        test    [esi+dpd.frame_start_hdr], 1 shl 31
2794
        jz      .maybenext
1519 hidnplayr 2795
 
2387 hidnplayr 2796
        and     [esi+dpd.frame_start_hdr], 0
2797
        push    ecx
2798
        stdcall KernelFree, [esi+dpd.realaddr]
2799
        pop     ecx
1519 hidnplayr 2800
 
2801
  .maybenext:
2387 hidnplayr 2802
        add     esi, dpd.size
2803
        dec     ecx
2804
        jnz     .txloop
1519 hidnplayr 2805
 
2806
.noTX:
2387 hidnplayr 2807
        pop     ax
1472 hidnplayr 2808
 
2387 hidnplayr 2809
        set_io  0
2810
        set_io  REG_COMMAND
2811
        or      ax, AckIntr
2812
        out     dx, ax
1472 hidnplayr 2813
 
2387 hidnplayr 2814
        set_io  REG_INT_STATUS
2815
        in      ax, dx
2816
        test    ax, S_5_INTS
2817
        jnz     .got_it
1472 hidnplayr 2818
 
2819
;re-enable ints
2387 hidnplayr 2820
        set_io  REG_COMMAND
2821
        mov     ax, SetIntrEnb + S_5_INTS
2822
        out     dx, ax
1472 hidnplayr 2823
 
2387 hidnplayr 2824
        ret
1472 hidnplayr 2825
 
2826
 
2827
 
2828
 
2829
; End of code
2387 hidnplayr 2830
align 4                                         ; Place all initialised data here
1472 hidnplayr 2831
 
2832
macro strtbl name, [string]
2833
{
2834
common
2387 hidnplayr 2835
        label name dword
1472 hidnplayr 2836
forward
2387 hidnplayr 2837
        local label
2838
        dd label
1472 hidnplayr 2839
forward
2387 hidnplayr 2840
        label db string, 0
1472 hidnplayr 2841
}
2842
 
2387 hidnplayr 2843
VORTEX_DEVICES       dd 0
1472 hidnplayr 2844
BOOMERANG_DEVICES    dd 0
2387 hidnplayr 2845
version              dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
2846
my_service           db '3C59X',0                    ; max 16 chars include zero
1472 hidnplayr 2847
 
2848
 
2849
strtbl link_str, \
2387 hidnplayr 2850
        "No valid link type detected", \
2851
        "10BASE-T half duplex", \
2852
        "10BASE-T full-duplex", \
2853
        "100BASE-TX half duplex", \
2854
        "100BASE-TX full duplex", \
2855
        "100BASE-T4", \
2856
        "100BASE-FX", \
2857
        "10Mbps AUI", \
2858
        "10Mbps COAX (BNC)", \
2859
        "miiDevice - not supported"
1472 hidnplayr 2860
 
2861
strtbl hw_str, \
2387 hidnplayr 2862
        "3c590 Vortex 10Mbps", \
2863
        "3c592 EISA 10Mbps Demon/Vortex", \
2864
        "3c597 EISA Fast Demon/Vortex", \
2865
        "3c595 Vortex 100baseTx", \
2866
        "3c595 Vortex 100baseT4", \
2867
        "3c595 Vortex 100base-MII", \
2868
        "3c900 Boomerang 10baseT", \
2869
        "3c900 Boomerang 10Mbps Combo", \
2870
        "3c900 Cyclone 10Mbps TPO", \
2871
        "3c900 Cyclone 10Mbps Combo", \
2872
        "3c900 Cyclone 10Mbps TPC", \
2873
        "3c900B-FL Cyclone 10base-FL", \
2874
        "3c905 Boomerang 100baseTx", \
2875
        "3c905 Boomerang 100baseT4", \
2876
        "3c905B Cyclone 100baseTx", \
2877
        "3c905B Cyclone 10/100/BNC", \
2878
        "3c905B-FX Cyclone 100baseFx", \
2879
        "3c905C Tornado", \
2880
        "3c980 Cyclone", \
2881
        "3c982 Dual Port Server Cyclone", \
2882
        "3cSOHO100-TX Hurricane", \
2883
        "3c555 Laptop Hurricane", \
2884
        "3c556 Laptop Tornado", \
2885
        "3c556B Laptop Hurricane", \
2886
        "3c575 [Megahertz] 10/100 LAN CardBus", \
2887
        "3c575 Boomerang CardBus", \
2888
        "3CCFE575BT Cyclone CardBus", \
2889
        "3CCFE575CT Tornado CardBus", \
2890
        "3CCFE656 Cyclone CardBus", \
2891
        "3CCFEM656B Cyclone+Winmodem CardBus", \
2892
        "3CXFEM656C Tornado+Winmodem CardBus", \
2893
        "3c450 HomePNA Tornado", \
2894
        "3c920 Tornado", \
2895
        "3c982 Hydra Dual Port A", \
2896
        "3c982 Hydra Dual Port B", \
2897
        "3c905B-T4", \
2898
        "3c920B-EMB-WNM Tornado"
1472 hidnplayr 2899
 
2900
 
2901
 
2902
align 4
2903
hw_versions:
2904
dw 0x5900, IS_VORTEX
2905
; 3c590 Vortex 10Mbps
2906
dw 0x5920, IS_VORTEX
2907
; 3c592 EISA 10Mbps Demon/Vortex
2908
dw 0x5970, IS_VORTEX
2909
; 3c597 EISA Fast Demon/Vortex
2910
dw 0x5950, IS_VORTEX
2911
; 3c595 Vortex 100baseTx
2912
dw 0x5951, IS_VORTEX
2913
; 3c595 Vortex 100baseT4
2914
dw 0x5952, IS_VORTEX
2915
; 3c595 Vortex 100base-MII
2916
dw 0x9000, IS_BOOMERANG
2917
; 3c900 Boomerang 10baseT
2918
dw 0x9001, IS_BOOMERANG
2919
; 3c900 Boomerang 10Mbps Combo
2920
dw 0x9004, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM
2921
; 3c900 Cyclone 10Mbps TPO
2922
dw 0x9005, IS_CYCLONE or HAS_HWCKSM
2923
; 3c900 Cyclone 10Mbps Combo
2924
dw 0x9006, IS_CYCLONE or HAS_HWCKSM
2925
; 3c900 Cyclone 10Mbps TPC
2926
dw 0x900A, IS_CYCLONE or HAS_HWCKSM
2927
; 3c900B-FL Cyclone 10base-FL
2928
dw 0x9050, IS_BOOMERANG or HAS_MII
2929
; 3c905 Boomerang 100baseTx
2930
dw 0x9051, IS_BOOMERANG or HAS_MII
2931
; 3c905 Boomerang 100baseT4
2932
dw 0x9055, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE
2933
; 3c905B Cyclone 100baseTx
2934
dw 0x9058, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM
2935
; 3c905B Cyclone 10/100/BNC
2936
dw 0x905A, IS_CYCLONE or HAS_HWCKSM
2937
; 3c905B-FX Cyclone 100baseFx
2938
dw 0x9200, IS_TORNADO or HAS_NWAY or HAS_HWCKSM
2939
; 3c905C Tornado
2940
dw 0x9800, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM
2941
; 3c980 Cyclone
2942
dw 0x9805, IS_TORNADO or HAS_NWAY or HAS_HWCKSM
2943
; 3c982 Dual Port Server Cyclone
2944
dw 0x7646, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM
2945
; 3cSOHO100-TX Hurricane
2946
dw 0x5055, IS_CYCLONE or EEPROM_8BIT or HAS_HWCKSM
2947
; 3c555 Laptop Hurricane
2948
dw 0x6055, IS_TORNADO or HAS_NWAY or EEPROM_8BIT or HAS_CB_FNS or INVERT_MII_PWR or HAS_HWCKSM
2949
; 3c556 Laptop Tornado
2950
dw 0x6056, IS_TORNADO or HAS_NWAY or EEPROM_OFFSET or HAS_CB_FNS or INVERT_MII_PWR or HAS_HWCKSM
2951
; 3c556B Laptop Hurricane
2952
dw 0x5b57, IS_BOOMERANG or HAS_MII or EEPROM_8BIT
2953
; 3c575 [Megahertz] 10/100 LAN CardBus
2954
dw 0x5057, IS_BOOMERANG or HAS_MII or EEPROM_8BIT
2955
; 3c575 Boomerang CardBus
2956
dw 0x5157, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_LED_PWR or HAS_HWCKSM
2957
; 3CCFE575BT Cyclone CardBus
2958
dw 0x5257, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR or MAX_COLLISION_RESET or HAS_HWCKSM
2959
; 3CCFE575CT Tornado CardBus
2960
dw 0x6560, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR or INVERT_LED_PWR or HAS_HWCKSM
2961
; 3CCFE656 Cyclone CardBus
2962
dw 0x6562, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR or INVERT_LED_PWR or HAS_HWCKSM
2963
; 3CCFEM656B Cyclone+Winmodem CardBus
2964
dw 0x6564, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR or MAX_COLLISION_RESET or HAS_HWCKSM
2965
; 3CXFEM656C Tornado+Winmodem CardBus
2966
dw 0x4500, IS_TORNADO or HAS_NWAY or HAS_HWCKSM
2967
; 3c450 HomePNA Tornado
2968
dw 0x9201, IS_TORNADO or HAS_NWAY or HAS_HWCKSM
2969
; 3c920 Tornado
2970
dw 0x1201, IS_TORNADO or HAS_HWCKSM or HAS_NWAY
2971
; 3c982 Hydra Dual Port A
2972
dw 0x1202, IS_TORNADO or HAS_HWCKSM or HAS_NWAY
2973
; 3c982 Hydra Dual Port B
2974
dw 0x9056, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE
2975
; 3c905B-T4
2976
dw 0x9210, IS_TORNADO or HAS_NWAY or HAS_HWCKSM
2977
; 3c920B-EMB-WNM Tornado
2978
HW_VERSIONS_SIZE = $ - hw_versions
2979
 
2387 hidnplayr 2980
include_debug_strings                           ; All data wich FDO uses will be included here
1472 hidnplayr 2981
 
2982
section '.data' data readable writable align 16 ; place all uninitialized data place here
2983
 
2387 hidnplayr 2984
VORTEX_LIST    rd MAX_DEVICES                   ; This list contains all pointers to device structures the driver is handling
1472 hidnplayr 2985
BOOMERANG_LIST rd MAX_DEVICES
2986
 
2987
 
2988
 
2989