Subversion Repositories Kolibri OS

Rev

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

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