Subversion Repositories Kolibri OS

Rev

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

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