Subversion Repositories Kolibri OS

Rev

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