Subversion Repositories Kolibri OS

Rev

Rev 4470 | Rev 5074 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4470 Rev 5073
Line 3... Line 3...
3
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;  3Com network driver for KolibriOS                           ;;
6
;;  3Com network driver for KolibriOS                           ;;
7
;;                                                              ;;
7
;;                                                              ;;
8
;;  Ported to KolibriOS net-branch by hidnplayr (28/05/10)      ;;
8
;;  Ported to KolibriOS net-branch by hidnplayr                 ;;
9
;;                                                              ;;
9
;;                                                              ;;
10
;;  Thanks to: scrap metal recyclers, whom provide me with      ;;
10
;;  Thanks to: scrap metal recyclers, whom provide me with      ;;
11
;;                         loads of hardware                    ;;
11
;;                         loads of hardware                    ;;
12
;;             diamond: who makes me understand KolibriOS       ;;
12
;;             diamond: who makes me understand KolibriOS       ;;
13
;;                                                              ;;
13
;;                                                              ;;
14
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
 
15
;;
-
 
16
;; Original copyright from menuetos driver:
15
 
17
;;
16
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17
;;                                                                         ;;
19
;;                                                                         ;;
18
;;  3C59X.INC                                                              ;;
20
;;  3C59X.INC                                                              ;;
19
;;                                                                         ;;
21
;;                                                                         ;;
20
;;  Ethernet driver for Menuet OS                                          ;;
22
;;  Ethernet driver for Menuet OS                                          ;;
Line 78... Line 80...
78
;;  Revision 1.1  2004/06/12 18:27:15  kozma
80
;;  Revision 1.1  2004/06/12 18:27:15  kozma
79
;;  Initial revision
81
;;  Initial revision
80
;;
82
;;
81
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
83
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 82... Line -...
82
 
-
 
Line -... Line 84...
-
 
84
 
-
 
85
 
-
 
86
format PE DLL native
83
format MS COFF
87
entry START
84
 
88
 
-
 
89
        CURRENT_API             = 0x0200
Line 85... Line 90...
85
        API_VERSION             = 0x01000100
90
        COMPATIBLE_API          = 0x0100
86
        DRIVER_VERSION          = 5
91
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
87
 
-
 
Line -... Line 92...
-
 
92
 
88
        MAX_DEVICES             = 16
93
        MAX_DEVICES             = 16
-
 
94
        FORCE_FD                = 0     ; forcing full duplex mode makes sense at some cards and link types
89
        FORCE_FD                = 0     ; forcing full duplex mode makes sense at some cards and link types
95
 
90
        PROMISCIOUS             = 0     ; enables promiscous mode
96
        NUM_RX_DESC             = 4     ; a power of 2 number
-
 
97
        NUM_TX_DESC             = 4     ; a power of 2 number
-
 
98
 
Line -... Line 99...
-
 
99
        __DEBUG__               = 1
91
 
100
        __DEBUG_LEVEL__         = 2     ; 1 = verbose, 2 = errors only
92
        DEBUG                   = 1
101
 
93
        __DEBUG__               = 1
-
 
94
        __DEBUG_LEVEL__         = 2
-
 
95
 
102
section '.flat' readable writable executable
96
include '../struct.inc'
103
 
97
include '../macros.inc'
-
 
98
include '../proc32.inc'
-
 
99
include '../imports.inc'
-
 
100
include '../fdo.inc'
-
 
101
include '../netdrv.inc'
-
 
102
 
-
 
103
public START
-
 
104
public service_proc
-
 
105
public version
-
 
106
 
-
 
107
struc DPD {     ; Download Packet Descriptor
-
 
108
 
-
 
109
        .next_ptr               dd ?
-
 
110
        .frame_start_hdr        dd ?
-
 
111
        .frag_addr              dd ?    ; for packet data
-
 
112
        .frag_len               dd ?    ; for packet data
-
 
113
        .realaddr               dd ?
-
 
114
        .size                   = 32
-
 
115
}
-
 
116
 
-
 
117
virtual at 0
-
 
118
  dpd DPD
-
 
119
end virtual
-
 
120
 
-
 
121
 
-
 
122
struc UPD {     ; Upload Packet Descriptor
-
 
123
 
-
 
124
        .next_ptr               dd ?
-
 
125
        .pkt_status             dd ?
-
 
126
        .frag_addr              dd ?
-
 
127
        .frag_len               dd ?    ; for packet data
-
 
128
        .realaddr               dd ?
-
 
129
        .size           = 32
-
 
130
 
-
 
Line 131... Line 104...
131
}
104
include '../proc32.inc'
132
 
105
include '../struct.inc'
133
virtual at 0
106
include '../macros.inc'
134
  upd UPD
107
include '../fdo.inc'
Line 233... Line 206...
233
; MII commands
206
; MII commands
234
        MII_CMD_MASK            = (1111b shl 10)
207
        MII_CMD_MASK            = (1111b shl 10)
235
        MII_CMD_READ            = (0110b shl 10)
208
        MII_CMD_READ            = (0110b shl 10)
236
        MII_CMD_WRITE           = (0101b shl 10)
209
        MII_CMD_WRITE           = (0101b shl 10)
Line 237... Line -...
237
 
-
 
238
; MII registers
-
 
239
        REG_MII_BMCR            = 0     ; basic mode control register
-
 
240
        REG_MII_BMSR            = 1     ; basic mode status register
-
 
241
        REG_MII_ANAR            = 4     ; auto negotiation advertisement register
-
 
242
        REG_MII_ANLPAR          = 5     ; auto negotiation link partner ability register
-
 
243
        REG_MII_ANER            = 6     ; auto negotiation expansion register
-
 
244
 
-
 
245
; MII bits
-
 
246
        BIT_MII_AUTONEG_COMPLETE        = 5     ; auto-negotiation complete
-
 
247
        BIT_MII_PREAMBLE_SUPPRESSION    = 6
-
 
248
 
210
 
249
; eeprom bits and commands
211
; eeprom bits and commands
250
        EEPROM_CMD_READ         = 0x80
212
        EEPROM_CMD_READ         = 0x80
Line 251... Line 213...
251
        EEPROM_BIT_BUSY         = 15
213
        EEPROM_BIT_BUSY         = 15
Line 255... Line 217...
255
        EEPROM_REG_CAPABILITIES = 0x10
217
        EEPROM_REG_CAPABILITIES = 0x10
Line 256... Line 218...
256
 
218
 
257
; Commands for command register
219
; Commands for command register
Line -... Line 220...
-
 
220
        SELECT_REGISTER_WINDOW  = (1 shl 11)
258
        SELECT_REGISTER_WINDOW  = (1 shl 11)
221
 
259
 
222
; Hw capabilities bitflags
260
        IS_VORTEX               = 0x1
223
        IS_VORTEX               = 0x0001
261
        IS_BOOMERANG            = 0x2
224
        IS_BOOMERANG            = 0x0002
262
        IS_CYCLONE              = 0x4
225
        IS_CYCLONE              = 0x0004
263
        IS_TORNADO              = 0x8
226
        IS_TORNADO              = 0x0008
264
        EEPROM_8BIT             = 0x10
227
        EEPROM_8BIT             = 0x0010
265
        HAS_PWR_CTRL            = 0x20
228
        HAS_PWR_CTRL            = 0x0020
266
        HAS_MII                 = 0x40
229
        HAS_MII                 = 0x0040
267
        HAS_NWAY                = 0x80
230
        HAS_NWAY                = 0x0080
268
        HAS_CB_FNS              = 0x100
231
        HAS_CB_FNS              = 0x0100
269
        INVERT_MII_PWR          = 0x200
232
        INVERT_MII_PWR          = 0x0200
270
        INVERT_LED_PWR          = 0x400
233
        INVERT_LED_PWR          = 0x0400
271
        MAX_COLLISION_RESET     = 0x800
234
        MAX_COLLISION_RESET     = 0x0800
272
        EEPROM_OFFSET           = 0x1000
235
        EEPROM_OFFSET           = 0x1000
Line 273... Line 236...
273
        HAS_HWCKSM              = 0x2000
236
        HAS_HWCKSM              = 0x2000
Line 286... Line 249...
286
        DownComplete            = 0x0200
249
        DownComplete            = 0x0200
287
        UpComplete              = 0x0400
250
        UpComplete              = 0x0400
288
        DMAInProgress           = 0x0800        ; 1 shl 11  (DMA controller is still busy)
251
        DMAInProgress           = 0x0800        ; 1 shl 11  (DMA controller is still busy)
289
        CmdInProgress           = 0x1000        ; 1 shl 12  (EL3_CMD is still busy)
252
        CmdInProgress           = 0x1000        ; 1 shl 12  (EL3_CMD is still busy)
Line 290... Line 253...
290
 
253
 
Line 291... Line 254...
291
        S_5_INTS                = HostError + RxEarly + UpComplete + DownComplete ;+ TxComplete + RxComplete  + TxAvailable
254
        S_5_INTS                = HostError + RxEarly + UpComplete + DownComplete + StatsFull ;+ TxComplete + RxComplete  + TxAvailable
292
 
255
 
293
; Commands
256
; Commands
294
        TotalReset              = 0 shl 11
257
        TotalReset              = 0 shl 11
Line 326... Line 289...
326
        RxBroadcast             = 4
289
        RxBroadcast             = 4
327
        RxProm                  = 8
290
        RxProm                  = 8
Line 328... Line 291...
328
 
291
 
329
; RX/TX buffers sizes
292
; RX/TX buffers sizes
330
        MAX_ETH_PKT_SIZE        = 1536          ; max packet size
-
 
331
        NUM_RX_DESC             = 4             ; a power of 2 number
-
 
332
        NUM_TX_DESC             = 4             ; a power of 2 number
293
        MAX_ETH_PKT_SIZE        = 1536          ; max packet size
Line 333... Line -...
333
        MAX_ETH_FRAME_SIZE      = 1520          ; size of ethernet frame + bytes alignment
-
 
334
 
-
 
335
virtual at ebx
-
 
Line 336... Line 294...
336
 
294
        MAX_ETH_FRAME_SIZE      = 1520          ; size of ethernet frame + bytes alignment
Line -... Line 295...
-
 
295
 
-
 
296
 
337
        device:
297
struct  tx_desc
338
 
298
 
-
 
299
        next_ptr                dd ?
-
 
300
        frame_start_hdr         dd ?
-
 
301
        frag_addr               dd ?    ; for packet data
-
 
302
        frag_len                dd ?    ; for packet data
-
 
303
        realaddr                dd ?
-
 
304
                                rd 3    ; align 32
-
 
305
ends
-
 
306
 
339
        ETH_DEVICE
307
 
340
 
308
struct  rx_desc
-
 
309
 
-
 
310
        next_ptr                dd ?
-
 
311
        pkt_status              dd ?
-
 
312
        frag_addr               dd ?
-
 
313
        frag_len                dd ?    ; for packet data
-
 
314
        realaddr                dd ?
-
 
315
                                rd 3    ; align 32
341
        .dpd_buffer       rd (dpd.size*NUM_TX_DESC)/4
316
ends
342
        .upd_buffer       rd (upd.size*NUM_RX_DESC)/4
317
 
343
        .curr_upd         dd ?
318
 
344
        .prev_dpd         dd ?
319
struct  device                  ETH_DEVICE
345
 
320
 
346
        .io_addr          dd ?
321
        io_addr                 dd ?
Line -... Line 322...
-
 
322
        pci_bus                 dd ?
-
 
323
        pci_dev                 dd ?
347
        .pci_bus          dd ?
324
        irq_line                db ?
348
        .pci_dev          dd ?
325
                                rb 3    ; alignment
349
        .irq_line         db ?
326
 
350
                rb 3    ; alignment
327
        curr_tx                 dd ?
351
 
328
        curr_rx                 dd ?
352
        .prev_tx_frame            dd ?
329
        prev_tx_frame           dd ?
-
 
330
        ver_id                  db ?
353
        .ver_id                   db ?
331
        full_bus_master         db ?
354
        .full_bus_master          db ?
332
        has_hwcksm              db ?
-
 
333
        preamble                db ?
-
 
334
        dn_list_ptr_cleared     db ?
Line 355... Line 335...
355
        .has_hwcksm               db ?
335
        internal_link           dd ?    ; link state (to be used only internally by driver)
Line 356... Line -...
356
        .preamble                 db ?
-
 
Line 357... Line 336...
357
        .dn_list_ptr_cleared      db ?
336
 
358
 
337
        rb 0x100 - ($ and 0xff) ; align 256
359
        .size = $ - device
338
        tx_desc_buffer          rd (sizeof.tx_desc*NUM_TX_DESC)/4
360
 
339
        rx_desc_buffer          rd (sizeof.rx_desc*NUM_RX_DESC)/4
361
end virtual
340
 
362
 
341
ends
Line 363... Line -...
363
section '.flat' code readable align 16
-
 
364
 
342
 
365
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
 
366
;;                        ;;
-
 
367
;; proc START             ;;
-
 
Line -... Line 343...
-
 
343
 
368
;;                        ;;
344
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 369... Line 345...
369
;; (standard driver proc) ;;
345
;;                        ;;
370
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
346
;; proc START             ;;
371
 
347
;;                        ;;
Line 372... Line 348...
372
align 4
348
;; (standard driver proc) ;;
373
proc START stdcall, state:dword
-
 
374
 
349
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
375
        cmp [state], 1
350
 
Line 376... Line 351...
376
        jne .exit
351
proc START c, reason:dword, cmdline:dword
Line 377... Line -...
377
 
-
 
378
  .entry:
-
 
379
 
-
 
380
        DEBUGF 1,"Loading driver\n"
352
 
381
        stdcall RegService, my_service, service_proc
353
        cmp     [reason], DRV_ENTRY
382
        ret
354
        jne     .fail
383
 
355
 
384
  .fail:
356
        DEBUGF  2,"Loading driver\n"
Line 430... Line 402...
430
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
402
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
431
        jne     .fail                                   ; other types of this hardware dont exist
403
        jne     .fail                                   ; other types of this hardware dont exist
Line 432... Line 404...
432
 
404
 
Line 433... Line 405...
433
; check if the device is already listed
405
; check if the device is already listed
434
 
406
 
435
        mov     ecx, [VORTEX_DEVICES]
407
        mov     ecx, [vortex_devices]
Line 436... Line 408...
436
        test    ecx, ecx
408
        test    ecx, ecx
437
        jz      .maybeboomerang
409
        jz      .maybeboomerang
438
 
410
 
439
        mov     esi, VORTEX_LIST
411
        mov     esi, vortex_list
440
        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
412
        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
441
        mov     ax , [eax+1]                            ;
413
        mov     ax , [eax+1]                            ;
442
  .nextdevice:
414
  .nextdevice:
443
        mov     ebx, [esi]
415
        mov     ebx, [esi]
444
        cmp     al, byte[device.pci_bus]
416
        cmp     al, byte[ebx + device.pci_bus]
445
        jne     @f
417
        jne     @f
446
        cmp     ah, byte[device.pci_dev]
418
        cmp     ah, byte[ebx + device.pci_dev]
447
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
419
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
Line 448... Line 420...
448
       @@:
420
       @@:
449
        add     esi, 4
421
        add     esi, 4
450
        loop    .nextdevice
422
        loop    .nextdevice
451
 
423
 
Line 452... Line 424...
452
 
424
 
453
  .maybeboomerang:
425
  .maybeboomerang:
454
        mov     ecx, [BOOMERANG_DEVICES]
426
        mov     ecx, [boomerang_devices]
455
        test    ecx, ecx
427
        test    ecx, ecx
456
        jz      .firstdevice
428
        jz      .firstdevice
457
 
429
 
458
        mov     esi, BOOMERANG_LIST
430
        mov     esi, boomerang_list
459
        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
431
        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
460
        mov     ax, [eax+1]                             ;
432
        mov     ax, [eax+1]                             ;
461
  .nextdevice2:
433
  .nextdevice2:
462
        mov     ebx, [esi]
434
        mov     ebx, [esi]
463
        cmp     al, byte[device.pci_bus]
435
        cmp     al, byte[ebx + device.pci_bus]
Line 464... Line 436...
464
        jne     @f
436
        jne     @f
465
        cmp     ah, byte[device.pci_dev]
437
        cmp     ah, byte[ebx + device.pci_dev]
466
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
438
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
467
       @@:
439
       @@:
468
        add     esi, 4
440
        add     esi, 4
469
        loop    .nextdevice2
441
        loop    .nextdevice2
Line 470... Line 442...
470
 
442
 
Line 471... Line 443...
471
 
443
 
Line 472... Line 444...
472
; This device doesnt have its own eth_device structure yet, lets create one
444
; This device doesnt have its own eth_device structure yet, lets create one
473
  .firstdevice:
445
  .firstdevice:
474
        mov     ecx, [BOOMERANG_DEVICES]
446
        mov     ecx, [boomerang_devices]
475
        add     ecx, [VORTEX_DEVICES]
447
        add     ecx, [vortex_devices]
Line 476... Line 448...
476
        cmp     ecx, MAX_DEVICES                        ; First check if the driver can handle one more card
448
        cmp     ecx, MAX_DEVICES                        ; First check if the driver can handle one more card
Line 477... Line 449...
477
        jae     .fail
449
        jae     .fail
478
 
450
 
479
        allocate_and_clear ebx, device.size, .fail      ; Allocate the buffer for device structure
451
        allocate_and_clear ebx, sizeof.device, .fail    ; Allocate the buffer for device structure
480
 
452
 
481
; Fill in the direct call addresses into the struct
453
; Fill in the direct call addresses into the struct
Line 482... Line 454...
482
 
454
 
-
 
455
        mov     [ebx + device.reset], reset
-
 
456
        mov     [ebx + device.transmit], null_op
483
        mov     [device.reset], reset
457
        mov     [ebx + device.unload], null_op
Line 484... Line 458...
484
        mov     [device.transmit], null_op
458
        mov     [ebx + device.name], my_service
-
 
459
 
-
 
460
; save the pci bus and device numbers
485
        mov     [device.unload], null_op
461
 
Line 486... Line 462...
486
        mov     [device.name], my_service
462
        mov     eax, [edx + IOCTL.input]
487
 
463
        movzx   ecx, byte[eax+1]
Line 488... Line 464...
488
; save the pci bus and device numbers
464
        mov     [ebx + device.pci_bus], ecx
489
 
465
        movzx   ecx, byte[eax+2]
490
        mov     eax, [edx + IOCTL.input]
466
        mov     [ebx + device.pci_dev], ecx
491
        movzx   ecx, byte[eax+1]
467
 
Line 492... Line 468...
492
        mov     [device.pci_bus], ecx
468
; Now, it's time to find the base io addres of the PCI device
493
        movzx   ecx, byte[eax+2]
469
 
494
        mov     [device.pci_dev], ecx
470
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
Line 495... Line 471...
495
 
471
        mov     [ebx + device.io_addr], eax
496
; Now, it's time to find the base io addres of the PCI device
472
 
497
        PCI_find_io
473
; We've found the io address, find IRQ now
Line 498... Line 474...
498
 
474
 
499
; We've found the io address, find IRQ now
475
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
500
        PCI_find_irq
476
        mov     [ebx + device.irq_line], al
Line 501... Line 477...
501
 
477
 
502
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
478
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
Line 503... Line 479...
503
        [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4
479
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:4
504
 
480
 
Line 505... Line 481...
505
; Ok, the eth_device structure is ready, let's probe the device
481
; Ok, the eth_device structure is ready, let's probe the device
506
        call    probe                                                   ; this function will output in eax
482
        call    probe                                                   ; this function will output in eax
507
        test    eax, eax
483
        test    eax, eax
508
        jnz     .err                                                    ; If an error occured, exit
484
        jnz     .err                                                    ; If an error occured, exit
Line 509... Line 485...
509
 
485
 
Line 510... Line 486...
510
 
486
 
Line 511... Line 487...
511
        movzx   ecx, [device.ver_id]
487
        movzx   ecx, [ebx + device.ver_id]
512
        test    word [hw_versions+2+ecx*4], IS_VORTEX
488
        test    word [hw_versions+2+ecx*4], IS_VORTEX
513
        jz      .not_vortex
489
        jz      .not_vortex
514
 
490
 
515
        mov     eax, [VORTEX_DEVICES]                                   ; Add the device structure to our device list
491
        mov     eax, [vortex_devices]                                   ; Add the device structure to our device list
516
        mov     [VORTEX_LIST+4*eax], ebx                                ; (IRQ handler uses this list to find device)
492
        mov     [vortex_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
517
        inc     [VORTEX_DEVICES]                                        ;
493
        inc     [vortex_devices]                                        ;
Line 518... Line 494...
518
 
494
 
Line 519... Line 495...
519
  .register:
495
  .register:
520
        mov     [device.type], NET_TYPE_ETH
496
        mov     [ebx + device.type], NET_TYPE_ETH
Line 521... Line 497...
521
        call    NetRegDev
497
        invoke  NetRegDev
522
 
498
 
523
        cmp     eax, -1
-
 
524
        je      .destroy
-
 
525
 
499
        cmp     eax, -1
-
 
500
        je      .destroy
526
        call    start_device
501
 
527
        ret
502
        call    start_device
Line 528... Line 503...
528
 
503
        ret
529
  .not_vortex:
504
 
Line 565... Line 540...
565
;;        Actual Hardware dependent code starts here                      ;;
540
;;        Actual Hardware dependent code starts here                      ;;
566
;;                                                                        ;;
541
;;                                                                        ;;
567
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
542
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
Line -... Line 543...
-
 
543
 
-
 
544
 
-
 
545
align 4
-
 
546
null_op:
Line 568... Line 547...
568
 
547
 
569
 
548
        ret
Line 583... Line 562...
583
align 4
562
align 4
584
probe:
563
probe:
Line 585... Line 564...
585
 
564
 
Line 586... Line 565...
586
        DEBUGF  1,"Probing 3com card\n"
565
        DEBUGF  1,"Probing 3com card\n"
-
 
566
 
-
 
567
; Make the device a bus master
-
 
568
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
Line 587... Line 569...
587
 
569
        or      al, PCI_CMD_MASTER
-
 
570
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
-
 
571
 
-
 
572
; wake up the card
-
 
573
        DEBUGF 1,"Checking if the device is awake\n"
-
 
574
 
-
 
575
; wake up - we directly do it by programming PCI
-
 
576
; check if the device is power management capable
-
 
577
        invoke  PciRead16, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.status
-
 
578
        test    al, PCI_STATUS_CAPA     ; is there "new capabilities" linked list?
-
 
579
        jz      .device_awake
-
 
580
 
-
 
581
; search for power management register
-
 
582
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.cap_ptr
-
 
583
        and     al, not 3
-
 
584
        cmp     al, 0x3f
-
 
585
        jbe     .device_awake           ; invalid pointer if less then PCI header size
-
 
586
 
-
 
587
; traverse the list
588
        PCI_make_bus_master
588
        movzx   esi, al
-
 
589
  .pm_loop:
-
 
590
        invoke  PciRead16, [ebx + device.pci_bus], [ebx + device.pci_dev], esi
-
 
591
        cmp     al, 1
-
 
592
        je      .set_pm_state
-
 
593
        movzx   esi, ah                 ; load address of next capability
-
 
594
        test    ah, ah                  ; 0 if none left
-
 
595
        jnz     .pm_loop
-
 
596
        jmp     .device_awake
-
 
597
 
-
 
598
; wake up the device if necessary
-
 
599
  .set_pm_state:
-
 
600
        DEBUGF 1,"Waking up the device\n"
-
 
601
        add     esi, 4                  ; offset for power management
-
 
602
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], esi
-
 
603
        test    al, 11b
Line -... Line 604...
-
 
604
        jz      .device_awake
-
 
605
        and     al, not 11b             ; set state to D0
-
 
606
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], esi, eax
-
 
607
 
589
 
608
  .device_awake:
Line 590... Line 609...
590
; wake up the card
609
        DEBUGF 1,"Device is awake\n"
Line 591... Line 610...
591
        call    wake_up
610
 
592
 
611
; Check device/vendor ID
Line 611... Line 630...
611
        or      eax, -1
630
        or      eax, -1
612
        ret
631
        ret
613
  .found:
632
  .found:
614
        mov     esi, [hw_str+ecx*4]
633
        mov     esi, [hw_str+ecx*4]
615
        DEBUGF  1,"Hardware type: %s\n", esi
634
        DEBUGF  1,"Hardware type: %s\n", esi
616
        mov     [device.name], esi
635
        mov     [ebx + device.name], esi
Line 617... Line 636...
617
 
636
 
618
        mov     [device.ver_id], cl
637
        mov     [ebx + device.ver_id], cl
619
        test    word [hw_versions+2+ecx*4], HAS_HWCKSM
638
        test    word [hw_versions+2+ecx*4], HAS_HWCKSM
620
        setnz   [device.has_hwcksm]
639
        setnz   [ebx + device.has_hwcksm]
621
; set pci latency for vortex cards
640
; set pci latency for vortex cards
622
        test    word [hw_versions+2+ecx*4], IS_VORTEX
641
        test    word [hw_versions+2+ecx*4], IS_VORTEX
Line 623... Line 642...
623
        jz      .not_vortex
642
        jz      .not_vortex
624
 
643
 
Line 625... Line 644...
625
        mov     eax, 11111000b ; 248 = max latency
644
        mov     al, 11111000b ; 248 = max latency
626
        stdcall PciWrite32, [device.pci_bus], [device.pci_dev], PCI_REG_LATENCY, eax
645
        invoke  PciWrite8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.max_latency, eax
627
 
646
 
628
  .not_vortex:
647
  .not_vortex:
629
; set RX/TX functions
648
; set RX/TX functions
630
        mov     ax, EEPROM_REG_CAPABILITIES
649
        mov     ax, EEPROM_REG_CAPABILITIES
631
        call    read_eeprom
650
        call    read_eeprom
632
        test    al, 100000b ; full bus master?
651
        test    al, 100000b ; full bus master?
633
        setnz   [device.full_bus_master]
652
        setnz   [ebx + device.full_bus_master]
634
        jnz     .boomerang_func
653
        jnz     .boomerang_func
635
        mov     [device.transmit], vortex_transmit
654
        mov     [ebx + device.transmit], vortex_transmit
636
        DEBUGF  2,"Device is a vortex type\n"
655
        DEBUGF  2,"Device is a vortex type\n"
637
        DEBUGF  2,"I'm sorry but vortex code hasnt been tested yet\n"
656
        DEBUGF  2,"I'm sorry but vortex code hasnt been tested yet\n"
638
        DEBUGF  2,"Please contact me on hidnplayr@kolibrios.org\n"
657
        DEBUGF  2,"Please contact me on hidnplayr@kolibrios.org\n"
639
        DEBUGF  2,"If you can help me finish it!\n"
658
        DEBUGF  2,"If you can help me finish it!\n"
640
        or      eax, -1
659
        or      eax, -1
641
        ret
660
        ret
642
        jmp     @f
661
        jmp     @f
643
  .boomerang_func: ; full bus master, so use boomerang functions
662
  .boomerang_func: ; full bus master, so use boomerang functions
644
        mov     [device.transmit], boomerang_transmit
663
        mov     [ebx + device.transmit], boomerang_transmit
Line 645... Line 664...
645
        DEBUGF  1,"Device is a boomerang type\n"
664
        DEBUGF  1,"Device is a boomerang type\n"
646
       @@:
665
       @@:
647
        call    read_mac_eeprom
666
        call    read_mac_eeprom
648
 
667
 
649
        test    byte [device.full_bus_master], 0xff
668
        test    byte [ebx + device.full_bus_master], 0xff
650
        jz      .set_preamble
669
        jz      .set_preamble
651
; switch to register window 2
670
; switch to register window 2
652
        set_io  0
671
        set_io  [ebx + device.io_addr], 0
653
        set_io  REG_COMMAND
672
        set_io  [ebx + device.io_addr], REG_COMMAND
654
        mov     ax, SELECT_REGISTER_WINDOW+2
673
        mov     ax, SELECT_REGISTER_WINDOW+2
655
        out     dx, ax
674
        out     dx, ax
656
; activate xcvr by setting some magic bits
675
; activate xcvr by setting some magic bits
657
        set_io  REG_RESET_OPTIONS
676
        set_io  [ebx + device.io_addr], REG_RESET_OPTIONS
658
        in      ax, dx
677
        in      ax, dx
659
        and     ax, not 0x4010
678
        and     ax, not 0x4010
660
        movzx   ecx, [device.ver_id]
679
        movzx   ecx, [ebx + device.ver_id]
661
        test    word [ecx*4+hw_versions+2], INVERT_LED_PWR
680
        test    word [ecx*4+hw_versions+2], INVERT_LED_PWR
Line 667... Line 686...
667
        or      ah, 0x40
686
        or      ah, 0x40
668
       @@:
687
       @@:
669
        out     dx, ax
688
        out     dx, ax
670
  .set_preamble:
689
  .set_preamble:
671
; use preamble as default
690
; use preamble as default
672
        mov     byte [device.preamble], 1 ; enable preamble
691
        mov     byte [ebx + device.preamble], 1 ; enable preamble
-
 
692
 
-
 
693
        DEBUGF 1,"Global reset..\n"
-
 
694
 
-
 
695
; GlobalReset
-
 
696
        set_io  [ebx + device.io_addr], 0
-
 
697
        set_io  [ebx + device.io_addr], REG_COMMAND
-
 
698
        xor     eax, eax
-
 
699
;       or      al, 0x14
-
 
700
        out     dx, ax
-
 
701
; wait for GlobalReset to complete
-
 
702
        mov     ecx, 64000
-
 
703
  .rsloop:
-
 
704
        in      ax , dx
-
 
705
        test    ah , 10000b             ; CmdInProgress
-
 
706
        loopz   .rsloop
-
 
707
 
-
 
708
        DEBUGF 1,"Waiting for nic to boot..\n"
-
 
709
; wait for 2 seconds for NIC to boot
-
 
710
        mov     esi, 2000               ; WTF? FIXME
-
 
711
        invoke  Sleep ; 2 seconds
-
 
712
 
-
 
713
        DEBUGF 1,"Ok!\n"
Line 673... Line -...
673
 
-
 
Line 674... Line 714...
674
        call    global_reset
714
 
-
 
715
 
675
 
716
;--------------------------
-
 
717
;
-
 
718
; RESET
Line 676... Line -...
676
;--------------------------
-
 
677
; RESET
719
;
Line 678... Line 720...
678
 
720
;--------------------------
679
align 4
721
 
Line 680... Line 722...
680
reset:
722
reset:
681
 
723
 
682
        movzx   eax, [device.irq_line]
724
        movzx   eax, [ebx + device.irq_line]
683
        DEBUGF  1,"Attaching int handler to irq %x\n",eax:1
-
 
684
 
725
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
685
        movzx   ecx, [device.ver_id]
726
 
686
        test    word [hw_versions+2+ecx*4], IS_VORTEX
-
 
687
        jz      .not_vortex
727
        movzx   ecx, [ebx + device.ver_id]
688
 
728
        test    word [hw_versions+2+ecx*4], IS_VORTEX
689
        mov     esi, int_vortex
-
 
690
        jmp     .reg_int
729
        jz      .not_vortex
691
 
730
        mov     esi, int_vortex
692
.not_vortex:
731
        jmp     .reg_int
693
        mov     esi, int_boomerang
732
  .not_vortex:
694
 
733
        mov     esi, int_boomerang
695
.reg_int:
734
  .reg_int:
696
        stdcall AttachIntHandler, eax, esi, dword 0
735
        invoke  AttachIntHandler, eax, esi, ebx
697
        test    eax, eax
736
        test    eax, eax
Line 698... Line 737...
698
        jnz     @f
737
        jnz     @f
699
        DEBUGF  2,"Could not attach int handler!\n"
738
        DEBUGF  2,"Could not attach int handler!\n"
700
;        or      eax, -1
739
        or      eax, -1
701
;        ret
740
        ret
Line 702... Line 741...
702
  @@:
741
  @@:
703
 
742
 
Line 704... Line 743...
704
        set_io  0
743
        set_io  [ebx + device.io_addr], 0
705
        set_io  REG_COMMAND
744
        set_io  [ebx + device.io_addr], REG_COMMAND
Line 706... Line 745...
706
        mov     ax, SELECT_REGISTER_WINDOW + 0
745
        mov     ax, SELECT_REGISTER_WINDOW + 0
707
        out     dx, ax
746
        out     dx, ax
Line 708... Line 747...
708
 
747
 
709
        mov     ax, StopCoax
748
        mov     ax, StopCoax
710
        out     dx, ax                        ; stop transceiver
749
        out     dx, ax                        ; stop transceiver
Line 711... Line 750...
711
 
750
 
712
        mov     ax, SELECT_REGISTER_WINDOW + 4
751
        mov     ax, SELECT_REGISTER_WINDOW + 4
713
        out     dx, ax                        ; disable UTP
752
        out     dx, ax                        ; disable UTP
Line 714... Line 753...
714
 
753
 
715
        set_io  REG_MEDIA_STATUS
754
        set_io  [ebx + device.io_addr], REG_MEDIA_STATUS
Line 716... Line 755...
716
        mov     ax, 0x0
755
        mov     ax, 0x0
Line 717... Line -...
717
 
-
 
718
        set_io  REG_COMMAND
756
 
719
        mov     ax, SELECT_REGISTER_WINDOW + 0
-
 
720
        out     dx, ax
757
        set_io  [ebx + device.io_addr], REG_COMMAND
721
 
758
        mov     ax, SELECT_REGISTER_WINDOW + 0
722
        set_io  REG_FIFO_DIAGNOSTIC
759
        out     dx, ax
Line 723... Line 760...
723
        mov     ax, 0
760
 
724
        out     dx, ax                        ; disable card
761
        set_io  [ebx + device.io_addr], REG_FIFO_DIAGNOSTIC
725
 
762
        mov     ax, 0
726
        mov     ax, 1
763
        out     dx, ax                        ; disable card
727
        out     dx, ax                        ; enable card
764
 
Line 728... Line 765...
728
 
765
        mov     ax, 1
729
        call    write_mac
766
        out     dx, ax                        ; enable card
730
 
767
 
731
 
768
        call    write_mac
Line 732... Line 769...
732
;<<<<<<<<<<<<<<
769
 
733
 
770
        set_io  [ebx + device.io_addr], 0
Line 734... Line 771...
734
        set_io  REG_COMMAND
771
        set_io  [ebx + device.io_addr], REG_COMMAND
735
        mov     ax, SELECT_REGISTER_WINDOW + 1
772
        mov     ax, SELECT_REGISTER_WINDOW + 1
Line 736... Line 773...
736
        out     dx, ax
773
        out     dx, ax
-
 
774
 
-
 
775
        mov     ecx, 32
-
 
776
        set_io  [ebx + device.io_addr], 0x0b
-
 
777
  .loop:
-
 
778
        in      al, dx
-
 
779
        loop    .loop
-
 
780
 
-
 
781
; Get rid of stray ints
-
 
782
        set_io  [ebx + device.io_addr], REG_COMMAND
-
 
783
        mov     ax, AckIntr + 0xff
-
 
784
        out     dx, ax
737
 
785
 
Line 738... Line 786...
738
        mov     ecx, 32
786
        mov     ax, SetStatusEnb + S_5_INTS
Line 739... Line 787...
739
        set_io  0x0b
787
        out     dx, ax
740
  .loop:
788
 
741
        in      al, dx
789
        mov     ax, SetIntrEnb + S_5_INTS
Line 742... Line -...
742
        loop    .loop
-
 
743
 
-
 
744
; Get rid of stray ints
790
        out     dx, ax
745
        set_io  REG_COMMAND
791
 
Line 746... Line 792...
746
        mov     ax, AckIntr + 0xff
792
        DEBUGF  1,"Setting RX mode\n"
747
        out     dx, ax
793
 
748
 
794
        set_io  [ebx + device.io_addr], 0
Line 749... Line -...
749
        mov     ax, SetStatusEnb + S_5_INTS
-
 
750
        out     dx, ax
-
 
Line 751... Line 795...
751
 
795
        set_io  [ebx + device.io_addr], REG_COMMAND
Line 781... Line 825...
781
 
825
 
782
align 4
826
align 4
783
start_device:
827
start_device:
Line 784... Line 828...
784
        DEBUGF  1,"Starting the device\n"
828
        DEBUGF  1,"Starting the device\n"
785
 
829
 
786
        set_io  0
830
        set_io  [ebx + device.io_addr], 0
787
        set_io  REG_COMMAND
831
        set_io  [ebx + device.io_addr], REG_COMMAND
Line 788... Line 832...
788
        mov     ax, SetTxThreshold + 60 ;2047 ; recommended by the manual :)
832
        mov     ax, SetTxThreshold + 60 ;2047 ; recommended by the manual :)
Line 789... Line 833...
789
        out     dx, ax
833
        out     dx, ax
790
 
834
 
791
        call    check_tx_status
835
        call    check_tx_status
792
 
836
 
793
        set_io  0
837
        set_io  [ebx + device.io_addr], 0
Line 794... Line 838...
794
        set_io  REG_COMMAND
838
        set_io  [ebx + device.io_addr], REG_COMMAND
795
; switch to register window 4
839
; switch to register window 4
796
        mov     ax, SELECT_REGISTER_WINDOW+4
840
        mov     ax, SELECT_REGISTER_WINDOW+4
797
        out     dx, ax
841
        out     dx, ax
798
 
842
 
799
; wait for linkDetect
843
; wait for linkDetect
800
        set_io  REG_MEDIA_STATUS
844
        set_io  [ebx + device.io_addr], REG_MEDIA_STATUS
801
        mov     ecx, 20 ; wait for max 2s
845
        mov     ecx, 20         ; wait for max 2s
802
  .link_detect_loop:
846
  .link_detect_loop:
803
        mov     esi, 100
847
        mov     esi, 100
804
        call    Sleep ; 100 ms
848
        invoke  Sleep           ; 100 ms
805
        in      ax, dx
849
        in      ax, dx
Line 806... Line 850...
806
        test    ah, 1000b ; linkDetect
850
        test    ah, 1000b       ; linkDetect
807
        jnz     @f
851
        jnz     @f
808
        loop    .link_detect_loop
852
        loop    .link_detect_loop
809
        DEBUGF  2,"Link detect timed-out!\n"
853
        DEBUGF  2,"Link detect timed-out!\n"
810
       @@:
854
       @@:
811
 
855
 
Line 812... Line 856...
812
; print link type
856
; print link type
813
        xor     eax, eax
857
        xor     eax, eax
Line 814... Line 858...
814
        bsr     ax, word [device.state]
858
        bsr     ax, word[ebx + device.internal_link]
815
        jz      @f
-
 
816
        sub     ax, 4
859
        jz      @f
817
       @@:
860
        sub     ax, 5
818
 
861
       @@:
Line 819... Line 862...
819
        mov     esi, [link_str+eax*4]
862
 
820
        DEBUGF  1,"Established Link type: %s\n", esi
863
        mov     esi, [link_str+eax*4]
Line 834... Line 877...
834
        mov     ax, SetIntrEnb + S_5_INTS
877
        mov     ax, SetIntrEnb + S_5_INTS
835
        out     dx, ax
878
        out     dx, ax
Line 836... Line 879...
836
 
879
 
Line 837... Line 880...
837
; Start RX/TX
880
; Start RX/TX
838
 
881
 
839
        set_io  0
882
        set_io  [ebx + device.io_addr], 0
840
        set_io  REG_COMMAND
883
        set_io  [ebx + device.io_addr], REG_COMMAND
Line 841... Line 884...
841
        mov     ax, RxEnable
884
        mov     ax, RxEnable
842
        out     dx, ax
885
        out     dx, ax
Line 843... Line 886...
843
 
886
 
844
        mov     ax, TxEnable
887
        mov     ax, TxEnable
845
        out     dx, ax
888
        out     dx, ax
Line 846... Line 889...
846
 
889
 
847
        set_io  REG_COMMAND
890
        set_io  [ebx + device.io_addr], REG_COMMAND
Line 848... Line 891...
848
        mov     ax, SetRxThreshold + 208
891
        mov     ax, SetRxThreshold + 208
849
        out     dx, ax
892
        out     dx, ax
Line 850... Line -...
850
 
-
 
851
        mov     ax, SetTxThreshold + 60 ;16 ; recommended by the manual :)
-
 
852
        out     dx, ax
-
 
853
 
-
 
854
        mov     ax, SELECT_REGISTER_WINDOW + 1
-
 
855
        out     dx, ax
-
 
856
 
-
 
857
        ret
-
 
858
 
-
 
859
 
-
 
860
 
-
 
861
 
-
 
862
 
-
 
863
 
-
 
864
 
-
 
865
align 4
-
 
866
set_rx_mode:
-
 
867
 
-
 
868
        DEBUGF  1,"Setting RX mode\n"
-
 
869
 
-
 
870
        set_io  0
-
 
871
        set_io  REG_COMMAND
-
 
872
 
-
 
873
if      defined PROMISCIOUS
-
 
874
        mov     ax, SetRxFilter + RxStation + RxMulticast + RxBroadcast + RxProm
-
 
875
else if  defined ALLMULTI
-
 
876
        mov     ax, SetRxFilter + RxStation + RxMulticast + RxBroadcast
-
 
877
else
-
 
878
        mov     ax, SetRxFilter + RxStation + RxBroadcast
-
 
879
end if
-
 
880
        out     dx, ax
-
 
881
 
-
 
882
        ret
-
 
883
 
-
 
884
 
-
 
885
 
-
 
886
 
-
 
887
 
-
 
888
;***************************************************************************
-
 
889
;   Function
-
 
890
;      global_reset
-
 
891
;   Description
-
 
892
;      resets the device
-
 
893
;   Parameters:
-
 
894
;
-
 
895
;   Return value:
-
 
896
;   Destroyed registers
-
 
897
;      ax, ecx, edx, esi
-
 
898
;
-
 
899
;***************************************************************************1
-
 
900
 
-
 
901
align 4
-
 
902
global_reset:
-
 
903
 
-
 
904
        DEBUGF 1,"Global reset..\n"
-
 
905
 
-
 
906
; GlobalReset
-
 
907
        set_io  0
-
 
908
        set_io  REG_COMMAND
-
 
909
        xor     eax, eax
-
 
910
;       or      al, 0x14
-
 
911
        out     dx, ax
-
 
912
; wait for GlobalReset to complete
-
 
913
        mov     ecx, 64000
893
 
914
  .loop:
894
        mov     ax, SetTxThreshold + 60 ;16 ; recommended by the manual :)
915
        in      ax , dx
-
 
Line 916... Line 895...
916
        test    ah , 10000b ; check CmdInProgress
895
        out     dx, ax
-
 
896
 
Line 917... Line 897...
917
        loopz   .loop
897
        mov     ax, SELECT_REGISTER_WINDOW + 1
Line 938... Line 918...
938
align 4
918
align 4
939
tx_reset:
919
tx_reset:
940
        DEBUGF 1,"tx reset\n"
920
        DEBUGF 1,"tx reset\n"
Line 941... Line 921...
941
 
921
 
942
; TxReset
922
; TxReset
943
        set_io  0
923
        set_io  [ebx + device.io_addr], 0
944
        set_io  REG_COMMAND
924
        set_io  [ebx + device.io_addr], REG_COMMAND
945
        mov     ax, TxReset
925
        mov     ax, TxReset
946
        out     dx, ax
926
        out     dx, ax
947
; Wait for TxReset to complete
927
; Wait for TxReset to complete
948
        mov     ecx, 200000
928
        mov     ecx, 200000
Line 951... Line 931...
951
        test    ah, 10000b ; check CmdInProgress
931
        test    ah, 10000b ; check CmdInProgress
952
        jz      .tx_set_prev
932
        jz      .tx_set_prev
953
        dec     ecx
933
        dec     ecx
954
        jnz     .tx_reset_loop
934
        jnz     .tx_reset_loop
955
.tx_set_prev:
935
  .tx_set_prev:
956
; init last_dpd
936
; init last TX descriptor
957
        lea     eax, [device.dpd_buffer + (NUM_TX_DESC-1)*dpd.size]
937
        lea     eax, [ebx + device.tx_desc_buffer + (NUM_TX_DESC-1)*sizeof.tx_desc]
958
        mov     [device.prev_dpd], eax
938
        mov     [ebx + device.curr_tx], eax
Line 959... Line 939...
959
 
939
 
960
.tx_enable:
940
  .tx_enable:
Line 973... Line 953...
973
align 4
953
align 4
974
rx_reset:
954
rx_reset:
Line 975... Line 955...
975
 
955
 
Line 976... Line 956...
976
        DEBUGF 1,"rx reset\n"
956
        DEBUGF 1,"rx reset\n"
977
 
957
 
978
        set_io  0
958
        set_io  [ebx + device.io_addr], 0
979
        set_io  REG_COMMAND
959
        set_io  [ebx + device.io_addr], REG_COMMAND
Line 980... Line 960...
980
        mov     ax, RxReset or 0x4
960
        mov     ax, RxReset or 0x4
981
        out     dx, ax
961
        out     dx, ax
Line 988... Line 968...
988
        jz      .done
968
        jz      .done
989
        dec     ecx
969
        dec     ecx
990
        jnz     .loop
970
        jnz     .loop
991
  .done:
971
  .done:
Line 992... Line 972...
992
 
972
 
993
        lea     eax, [device.upd_buffer]
973
        lea     eax, [ebx + device.rx_desc_buffer]
994
        mov     [device.curr_upd], eax
974
        mov     [ebx + device.curr_rx], eax
995
        GetRealAddr
975
        invoke  GetPhysAddr
996
        set_io  0
976
        set_io  [ebx + device.io_addr], 0
997
        set_io  REG_UP_LIST_PTR
977
        set_io  [ebx + device.io_addr], REG_UP_LIST_PTR
Line 998... Line 978...
998
        out     dx, eax
978
        out     dx, eax
999
 
979
 
Line -... Line 980...
-
 
980
  .rx_enable:
1000
  .rx_enable:
981
        ret
1001
        ret
982
 
1002
 
983
 
1003
 
984
 
1004
align 4
985
align 4
1005
create_rx_ring:
986
create_rx_ring:
Line 1006... Line 987...
1006
; create upd ring
987
; create rx descriptor ring
1007
        lea     eax, [device.upd_buffer]
988
        lea     eax, [ebx + device.rx_desc_buffer]
Line 1008... Line 989...
1008
        GetRealAddr
989
        invoke  GetPhysAddr
1009
        mov     edi, eax                                                ; real addr of first descr
-
 
1010
 
990
        mov     edi, eax                                                ; real addr of first descr
1011
        lea     esi, [device.upd_buffer]                                ; ptr to first descr
991
 
Line 1012... Line 992...
1012
        lea     edx, [device.upd_buffer + (NUM_RX_DESC-1)*upd.size]     ; ptr to last descr
992
        lea     esi, [ebx + device.rx_desc_buffer]                          ; ptr to first descr
1013
 
993
        lea     edx, [ebx + device.rx_desc_buffer + (NUM_RX_DESC-1)*sizeof.rx_desc]     ; ptr to last descr
1014
        mov     ecx, NUM_RX_DESC
994
 
1015
 
995
        mov     ecx, NUM_RX_DESC
1016
  .upd_loop:
996
  .loop:
1017
        mov     [edx + upd.next_ptr], edi
997
        mov     [edx + rx_desc.next_ptr], edi
1018
 
998
 
1019
        push    ecx edx
999
        push    ecx edx
Line 1020... Line 1000...
1020
        stdcall KernelAlloc, MAX_ETH_FRAME_SIZE
1000
        invoke  KernelAlloc, MAX_ETH_FRAME_SIZE
1021
        pop     edx ecx
1001
        pop     edx ecx
Line 1022... Line 1002...
1022
        mov     [esi + upd.realaddr], eax
1002
        mov     [esi + rx_desc.realaddr], eax
1023
        call    GetPgAddr
1003
        invoke  GetPgAddr
1024
        mov     [esi + upd.frag_addr], eax
1004
        mov     [esi + rx_desc.frag_addr], eax
1025
        and     [esi + upd.pkt_status], 0
1005
        and     [esi + rx_desc.pkt_status], 0
1026
        mov     [esi + upd.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31)
1006
        mov     [esi + rx_desc.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31)
Line 1027... Line 1007...
1027
 
1007
 
Line 1054... Line 1034...
1054
;---------------------------------------------------------------------------
1034
;---------------------------------------------------------------------------
Line 1055... Line 1035...
1055
 
1035
 
1056
align 4
1036
align 4
Line 1057... Line 1037...
1057
try_link_detect:
1037
try_link_detect:
Line 1058... Line 1038...
1058
 
1038
 
1059
        DEBUGF  1,"trying to detect link\n"
1039
        DEBUGF  1,"Trying to detect link\n"
1060
 
1040
 
1061
; create self-directed packet
1041
; create self-directed packet
Line 1062... Line 1042...
1062
        stdcall KernelAlloc, 20 ; create a buffer for the self-directed packet
1042
        invoke  KernelAlloc, 20 ; create a buffer for the self-directed packet
1063
        test    eax, eax
1043
        test    eax, eax
Line 1064... Line 1044...
1064
        jz      .fail
1044
        jz      .fail
Line 1065... Line 1045...
1065
 
1045
 
1066
        pushd   20              ; Packet parameters for device.transmit
1046
        pushd   20              ; Packet parameters for device.transmit
1067
        push    eax             ;
1047
        push    eax             ;
1068
 
1048
 
1069
        mov     edi, eax
1049
        mov     edi, eax
1070
 
1050
 
1071
        lea     esi, [device.mac]
1051
        lea     esi, [ebx + device.mac]
1072
        movsw
1052
        movsw
Line 1073... Line 1053...
1073
        movsd
1053
        movsd
1074
        sub     esi, 6
1054
        sub     esi, 6
Line 1075... Line 1055...
1075
        movsw
1055
        movsw
1076
        movsd
1056
        movsd
1077
        mov     ax , 0x0608
1057
        mov     ax , 0x0608
1078
        stosw
1058
        stosw
1079
 
1059
 
Line 1080... Line 1060...
1080
; download self-directed packet
1060
; download self-directed packet
1081
        call    [device.transmit]
1061
        call    [ebx + device.transmit]
1082
 
1062
 
Line 1083... Line 1063...
1083
; switch to register window 4
1063
; switch to register window 4
1084
        set_io  0
1064
        set_io  [ebx + device.io_addr], 0
1085
        set_io  REG_COMMAND
1065
        set_io  [ebx + device.io_addr], REG_COMMAND
1086
        mov     ax, SELECT_REGISTER_WINDOW+4
1066
        mov     ax, SELECT_REGISTER_WINDOW+4
Line 1087... Line 1067...
1087
        out     dx, ax
1067
        out     dx, ax
1088
 
1068
 
1089
; See if we have received the packet by now..
1069
; See if we have received the packet by now..
1090
        cmp     [device.packets_rx], 0
1070
        cmp     [ebx + device.packets_rx], 0
1091
        jnz     .link_detected
1071
        jnz     .link_detected
1092
 
1072
 
1093
; switch to register window 4
1073
; switch to register window 4
Line 1094... Line 1074...
1094
        set_io  REG_COMMAND
1074
        set_io  [ebx + device.io_addr], REG_COMMAND
1095
        mov     ax, SELECT_REGISTER_WINDOW+4
1075
        mov     ax, SELECT_REGISTER_WINDOW+4
1096
        out     dx, ax
1076
        out     dx, ax
Line 1097... Line 1077...
1097
 
1077
 
1098
; read linkbeatdetect
1078
; read linkbeatdetect
1099
        set_io  REG_MEDIA_STATUS
1079
        set_io  [ebx + device.io_addr], REG_MEDIA_STATUS
1100
        in      ax, dx
1080
        in      ax, dx
1101
        test    ah, 1000b ; test linkBeatDetect
1081
        test    ah, 1000b ; test linkBeatDetect
1102
        jnz     .link_detected
1082
        jnz     .link_detected
Line 1103... Line 1083...
1103
        xor     al, al
1083
        xor     al, al
-
 
1084
        jmp     .finish
1104
        jmp     .finish
1085
 
Line 1105... Line 1086...
1105
 
1086
  .link_detected:
Line 1142... Line 1123...
1142
try_phy:
1123
try_phy:
Line 1143... Line 1124...
1143
 
1124
 
1144
        DEBUGF 1,"PHY=%u\n", ah
1125
        DEBUGF 1,"PHY=%u\n", ah
Line 1145... Line 1126...
1145
        DEBUGF 1,"Detecting if device is auto-negotiation capable\n"
1126
        DEBUGF 1,"Detecting if device is auto-negotiation capable\n"
1146
 
1127
 
1147
        mov     al, REG_MII_BMCR
1128
        mov     al, MII_BMCR
1148
        push    eax
1129
        push    eax
1149
        call    mdio_read       ; returns with window #4
1130
        call    mdio_read       ; returns with window #4
1150
        or      ah , 0x80       ; software reset
1131
        or      ah, 0x80        ; software reset
1151
        mov     esi, eax
1132
        mov     esi, eax
Line 1152... Line 1133...
1152
        mov     eax, dword [esp]
1133
        mov     eax, [esp]
1153
        call    mdio_write      ; returns with window #4
1134
        call    mdio_write      ; returns with window #4
1154
 
1135
 
1155
; wait for reset to complete
1136
; wait for reset to complete
1156
        mov     esi, 2000
1137
        mov     esi, 2000
1157
        stdcall Sleep      ; 2s
1138
        invoke  Sleep      ; 2s
1158
        mov     eax, [esp]
1139
        mov     eax, [esp]
1159
        call    mdio_read       ; returns with window #4
1140
        call    mdio_read       ; returns with window #4
Line 1160... Line 1141...
1160
        test    ah , 0x80
1141
        test    ah, 0x80
1161
        jnz     .fail1
1142
        jnz     .fail1
1162
        mov     eax, [esp]
1143
        mov     eax, [esp]
1163
 
1144
 
1164
; wait for a while after reset
1145
; wait for a while after reset
1165
        mov     esi, 20
1146
        mov     esi, 20
1166
        stdcall Sleep      ; 20ms
1147
        invoke  Sleep      ; 20ms
1167
        mov     eax, [esp]
1148
        mov     eax, [esp]
-
 
1149
        mov     al , MII_BMSR
Line 1168... Line 1150...
1168
        mov     al , REG_MII_BMSR
1150
        call    mdio_read        ; returns with window #4
1169
        call    mdio_read        ; returns with window #4
1151
        test    al, 1            ; extended capability supported?
1170
        test    al , 1           ; extended capability supported?
1152
        jz      .fail2
1171
        jz      .fail2
-
 
1172
 
1153
        DEBUGF  1,"Extended capability supported\n"
Line 1173... Line 1154...
1173
; auto-neg capable?
1154
 
1174
        test    al , 1000b
1155
; auto-neg capable?
1175
        jz      .fail2           ; not auto-negotiation capable
1156
        test    al , 1000b
1176
 
-
 
1177
        DEBUGF  1,"Device is auto-negotiation capable\n"
1157
        jz      .fail2           ; not auto-negotiation capable
Line 1178... Line 1158...
1178
 
1158
        DEBUGF  1,"Auto-negotiation capable\n"
1179
; auto-neg complete?
1159
 
1180
        test    al , 100000b
1160
; auto-neg complete?
1181
        jnz     .auto_neg_ok
1161
        test    al , 100000b
1182
 
1162
        jnz     .auto_neg_ok
1183
        DEBUGF  1,"Restarting auto-negotiation\n"
1163
        DEBUGF  1,"Restarting auto-negotiation\n"
1184
 
1164
 
1185
; restart auto-negotiation
1165
; restart auto-negotiation
Line 1196... Line 1176...
1196
        mov     esi, eax
1176
        mov     esi, eax
1197
        or      bh , 10010b     ; restart auto-negotiation
1177
        or      bh , 10010b     ; restart auto-negotiation
1198
        mov     eax, [esp]
1178
        mov     eax, [esp]
1199
        call    mdio_write      ; returns with window #4
1179
        call    mdio_write      ; returns with window #4
1200
        mov     esi, 4000
1180
        mov     esi, 4000
1201
        stdcall Sleep  ; 4 seconds
1181
        invoke  Sleep  ; 4 seconds
1202
        mov     eax, [esp]
1182
        mov     eax, [esp]
1203
        mov     al , REG_MII_BMSR
1183
        mov     al , MII_BMSR
1204
        call    mdio_read ; returns with window #4
1184
        call    mdio_read ; returns with window #4
1205
        test    al , 100000b ; auto-neg complete?
1185
        test    al , 100000b ; auto-neg complete?
1206
        jnz     .auto_neg_ok
1186
        jnz     .auto_neg_ok
1207
        jmp     .fail3
1187
        jmp     .fail3
1208
  .auto_neg_ok:
1188
  .auto_neg_ok:
1209
 
-
 
1210
        DEBUGF  1,"Auto-negotiation complete\n"
1189
        DEBUGF  1,"Auto-negotiation complete\n"
Line 1211... Line 1190...
1211
 
1190
 
1212
; compare advertisement and link partner ability registers
1191
; compare advertisement and link partner ability registers
1213
        mov     eax, [esp]
1192
        mov     eax, [esp]
1214
        mov     al , REG_MII_ANAR
1193
        mov     al, MII_ADVERTISE
1215
        call    mdio_read       ; returns with window #4
1194
        call    mdio_read               ; returns with window #4
1216
        xchg    eax, [esp]
1195
        xchg    eax, [esp]
1217
        mov     al , REG_MII_ANLPAR
1196
        mov     al, MII_LPA
1218
        call    mdio_read       ; returns with window #4
1197
        call    mdio_read               ; returns with window #4
1219
        pop     esi
1198
        pop     esi
1220
        and     eax, esi
1199
        and     eax, esi
1221
        and     eax, 1111100000b
1200
        and     eax, 11111100000b       ; Mask off
1222
        push    eax
-
 
1223
 
1201
        push    eax
Line 1224... Line 1202...
1224
        mov     word[device.state+2], ax
1202
        mov     word[ebx + device.internal_link+2], ax
1225
 
1203
 
1226
; switch to register window 3
1204
; switch to register window 3
1227
        set_io  0
1205
        set_io  [ebx + device.io_addr], 0
1228
        set_io  REG_COMMAND
1206
        set_io  [ebx + device.io_addr], REG_COMMAND
Line 1229... Line 1207...
1229
        mov     ax , SELECT_REGISTER_WINDOW+3
1207
        mov     ax, SELECT_REGISTER_WINDOW+3
1230
        out     dx , ax
1208
        out     dx, ax
1231
 
1209
 
1232
; set full-duplex mode
1210
; set full-duplex mode
1233
        set_io  REG_MAC_CONTROL
1211
        set_io  [ebx + device.io_addr], REG_MAC_CONTROL
1234
        in      ax , dx
1212
        in      ax, dx
1235
        and     ax , not 0x120  ; clear full duplex and flow control
1213
        and     ax, not 0x120           ; clear full duplex and flow control
Line 1241... Line 1219...
1241
        DEBUGF 1,"Using half-duplex\n"
1219
        DEBUGF 1,"Using half-duplex\n"
1242
        out     dx , ax
1220
        out     dx, ax
1243
        mov     al , 1
1221
        mov     al, 1
1244
        ret
1222
        ret
Line 1245... Line -...
1245
 
-
 
1246
 
1223
 
1247
  .fail1:
1224
  .fail1:
1248
        DEBUGF  2,"reset failed!\n"
1225
        DEBUGF  2,"reset failed!\n"
1249
        pop     eax
1226
        pop     eax
1250
        xor     al, al
1227
        xor     al, al
Line 1255... Line 1232...
1255
        pop     eax
1232
        pop     eax
1256
        xor     al, al
1233
        xor     al, al
1257
        ret
1234
        ret
Line 1258... Line 1235...
1258
 
1235
 
1259
  .fail3:
1236
  .fail3:
1260
        DEBUGF  2,"auto-negotiation reset failed!\n"
1237
        DEBUGF  2,"Auto-negotiation reset failed!\n"
1261
        pop     eax
1238
        pop     eax
1262
        xor     al, al
1239
        xor     al, al
Line 1283... Line 1260...
1283
;***************************************************************************
1260
;***************************************************************************
Line 1284... Line 1261...
1284
 
1261
 
1285
align 4
1262
align 4
Line 1286... Line 1263...
1286
try_mii:
1263
try_mii:
Line 1287... Line 1264...
1287
 
1264
 
1288
        DEBUGF  1,"trying to find MII PHY\n"
1265
        DEBUGF  1,"Trying to find MII PHY\n"
1289
 
1266
 
1290
; switch to register window 3
1267
; switch to register window 3
1291
        set_io  0
1268
        set_io  [ebx + device.io_addr], 0
1292
        set_io  REG_COMMAND
1269
        set_io  [ebx + device.io_addr], REG_COMMAND
1293
        mov     ax, SELECT_REGISTER_WINDOW+3
1270
        mov     ax, SELECT_REGISTER_WINDOW+3
1294
        out     dx, ax
1271
        out     dx, ax
1295
        set_io  REG_INTERNAL_CONFIG
1272
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1296
        in      eax, dx
1273
        in      eax, dx
Line 1297... Line 1274...
1297
        and     eax, (1111b shl 20)
1274
        and     eax, (1111b shl 20)
1298
        cmp     eax, (1000b shl 20) ; is auto-negotiation set?
1275
        cmp     eax, (1000b shl 20) ; is auto-negotiation set?
1299
        jne     .mii_device
1276
        jne     .mii_device
1300
 
1277
 
1301
        DEBUGF  1,"auto-negotiation is set\n"
1278
        DEBUGF  1,"Auto-negotiation is set\n"
Line 1302... Line 1279...
1302
; switch to register window 4
1279
; switch to register window 4
1303
        set_io  REG_COMMAND
1280
        set_io  [ebx + device.io_addr], REG_COMMAND
1304
        mov     ax , SELECT_REGISTER_WINDOW+4
1281
        mov     ax, SELECT_REGISTER_WINDOW+4
1305
        out     dx , ax
1282
        out     dx, ax
1306
 
1283
 
1307
; PHY==24 is the on-chip auto-negotiation logic
1284
; PHY==24 is the on-chip auto-negotiation logic
Line 1308... Line 1285...
1308
; it supports only 10base-T and 100base-TX
1285
; it supports only 10base-T and 100base-TX
1309
        mov     ah , 24
1286
        mov     ah, 24
Line 1310... Line 1287...
1310
        call    try_phy
1287
        call    try_phy
1311
        test    al , al
1288
        test    al, al
1312
        jz      .fail_finish
1289
        jz      .fail
Line 1313... Line 1290...
1313
 
1290
 
1314
        mov     cl , 24
1291
        mov     cl, 24
1315
        jmp     .check_preamble
1292
        jmp     .check_preamble
1316
 
1293
 
Line 1317... Line 1294...
1317
  .mii_device:
1294
  .mii_device:
1318
        cmp     eax, (0110b shl 20)
1295
        cmp     eax, (0110b shl 20)
1319
        jne     .fail_finish
1296
        jne     .fail
1320
 
1297
 
1321
        set_io  0
1298
        set_io  [ebx + device.io_addr], 0
Line 1334... Line 1311...
1334
 
1311
 
1335
  .search_for_phy:
1312
  .search_for_phy:
1336
; search for PHY
1313
; search for PHY
1337
        mov     cx , 31
1314
        mov     cx, 31
1338
  .search_phy_loop:
1315
  .search_phy_loop:
1339
        DEBUGF  1,"Searching the PHY\n"
1316
        DEBUGF  1,"Searching for the PHY\n"
1340
        cmp     cx , 24
1317
        cmp     cx, 24
1341
        je      .next_phy
1318
        je      .next_phy
1342
        mov     ah , cl ; ah = phy
1319
        mov     ah, cl                  ; ah = phy
1343
        mov     al , REG_MII_BMCR ; al = Basic Mode Status Register
1320
        mov     al, MII_BMSR            ; al = Basic Mode Status Register       ; BUGFIX HERE! :):)
1344
        push    cx
1321
        push    cx
1345
        call    mdio_read
1322
        call    mdio_read
1346
        pop     cx
1323
        pop     cx
1347
        test    ax , ax
1324
        test    ax, ax
Line 1355... Line 1332...
1355
        test    al , al
1332
        test    al, al
1356
        jnz     .check_preamble
1333
        jnz     .check_preamble
1357
  .next_phy:
1334
  .next_phy:
1358
        loopw   .search_phy_loop
1335
        loopw   .search_phy_loop
Line 1359... Line 1336...
1359
 
1336
 
-
 
1337
  .fail:
1360
  .fail_finish:
1338
        DEBUGF  1,"PHY not found\n"
1361
        xor     al, al
1339
        xor     al, al
Line 1362... Line 1340...
1362
        ret
1340
        ret
1363
 
1341
 
1364
; epilog
1342
; epilog
1365
  .check_preamble:
1343
  .check_preamble:
1366
        DEBUGF  1,"Using PHY: %u\nChecking PreAmble\n", cl
1344
        DEBUGF  1,"Using PHY: %u\nChecking PreAmble\n", cl
1367
        push    eax ; eax contains the return value of try_phy
1345
        push    eax ; eax contains the return value of try_phy
1368
; check hard coded preamble forcing
1346
; check hard coded preamble forcing
1369
        movzx   eax, [device.ver_id]
1347
        movzx   eax, [ebx + device.ver_id]
1370
        test    word [eax*4+hw_versions+2], EXTRA_PREAMBLE
1348
        test    word [eax*4+hw_versions+2], EXTRA_PREAMBLE
Line 1371... Line 1349...
1371
        setnz   [device.preamble] ; force preamble
1349
        setnz   [ebx + device.preamble] ; force preamble
1372
        jnz     .finish
1350
        jnz     .finish
1373
 
1351
 
1374
; check mii for preamble suppression
1352
; check mii for preamble suppression
1375
        mov     ah, cl
1353
        mov     ah, cl
1376
        mov     al, REG_MII_BMSR
1354
        mov     al, MII_BMSR
Line 1377... Line 1355...
1377
        call    mdio_read
1355
        call    mdio_read
1378
        test    al, 1000000b ; preamble suppression?
1356
        test    al, 1000000b ; preamble suppression?
1379
        setz    [device.preamble] ; no
1357
        setz    [ebx + device.preamble] ; no
Line 1395... Line 1373...
1395
;***************************************************************************
1373
;***************************************************************************
Line 1396... Line 1374...
1396
 
1374
 
1397
align 4
1375
align 4
Line 1398... Line 1376...
1398
test_packet:
1376
test_packet:
Line 1399... Line 1377...
1399
 
1377
 
1400
        DEBUGF 1,"sending test packet\n"
1378
        DEBUGF 1,"Sending test packet\n"
1401
 
1379
 
1402
; switch to register window 3
1380
; switch to register window 3
1403
        set_io  0
1381
        set_io  [ebx + device.io_addr], 0
Line 1404... Line 1382...
1404
        set_io  REG_COMMAND
1382
        set_io  [ebx + device.io_addr], REG_COMMAND
1405
        mov     ax, SELECT_REGISTER_WINDOW+3
1383
        mov     ax, SELECT_REGISTER_WINDOW+3
1406
        out     dx, ax
1384
        out     dx, ax
1407
 
1385
 
1408
; set fullDuplexEnable in MacControl register
1386
; set fullDuplexEnable in MacControl register
Line 1409... Line 1387...
1409
        set_io  REG_MAC_CONTROL
1387
        set_io  [ebx + device.io_addr], REG_MAC_CONTROL
1410
        in      ax, dx
1388
        in      ax, dx
1411
        or      ax, 0x120
1389
        or      ax, 0x120
1412
        out     dx, ax
1390
        out     dx, ax
Line 1413... Line 1391...
1413
 
1391
 
1414
; switch to register window 5
1392
; switch to register window 5
1415
        set_io  REG_COMMAND
1393
        set_io  [ebx + device.io_addr], REG_COMMAND
1416
        mov     ax, SELECT_REGISTER_WINDOW+5
1394
        mov     ax, SELECT_REGISTER_WINDOW+5
1417
        out     dx, ax
1395
        out     dx, ax
1418
 
1396
 
1419
; set RxFilter to enable individual address matches
1397
; set RxFilter to enable individual address matches
Line 1420... Line 1398...
1420
        mov     ax, (10000b shl 11)
1398
        mov     ax, (10000b shl 11)
1421
        set_io  REG_RX_FILTER
1399
        set_io  [ebx + device.io_addr], REG_RX_FILTER
1422
        in      al, dx
1400
        in      al, dx
Line 1423... Line 1401...
1423
        or      al, 1
1401
        or      al, 1
1424
        set_io  REG_COMMAND
1402
        set_io  [ebx + device.io_addr], REG_COMMAND
1425
        out     dx, ax
1403
        out     dx, ax
1426
 
1404
 
Line 1427... Line 1405...
1427
; issue RxEnable and TxEnable
1405
; issue RxEnable and TxEnable
1428
        call    rx_reset
1406
        call    rx_reset
Line 1429... Line 1407...
1429
        call    tx_reset
1407
        call    tx_reset
1430
 
1408
 
1431
; create self-directed packet
1409
; create self-directed packet
1432
        stdcall KernelAlloc, 20 ; create a buffer for the self-directed packet
1410
        invoke  KernelAlloc, 20 ; create a buffer for the self-directed packet
1433
        test    eax, eax
1411
        test    eax, eax
1434
        jz      .fail
1412
        jz      .fail
1435
 
1413
 
1436
        pushd   20              ; Packet parameters for device.transmit
1414
        pushd   20              ; Packet parameters for device.transmit
1437
        push    eax             ;
1415
        push    eax             ;
Line 1438... Line 1416...
1438
 
1416
 
1439
        mov     edi, eax
1417
        mov     edi, eax
Line 1440... Line 1418...
1440
        lea     esi, [device.mac]
1418
        lea     esi, [ebx + device.mac]
1441
        movsw
1419
        movsw
1442
        movsd
1420
        movsd
Line 1443... Line 1421...
1443
        sub     esi, 6
1421
        sub     esi, 6
1444
        movsw
1422
        movsw
1445
        movsd
1423
        movsd
1446
        mov     ax , 0x0608
1424
        mov     ax, 0x0608
Line 1447... Line 1425...
1447
        stosw
1425
        stosw
1448
 
1426
 
1449
; download self-directed packet
1427
; download self-directed packet
1450
        call    [device.transmit]
1428
        call    [ebx + device.transmit]
1451
 
1429
 
Line 1452... Line 1430...
1452
; wait for 2s
1430
; wait for 2s
1453
        mov     esi, 2000
1431
        mov     esi, 2000
1454
        call    Sleep
1432
        invoke  Sleep
1455
 
1433
 
1456
; check if self-directed packet is received
1434
; check if self-directed packet is received
1457
        mov     eax, [device.packets_rx]
1435
        mov     eax, [ebx + device.packets_rx]
1458
        test    eax, eax
1436
        test    eax, eax
Line 1499... Line 1477...
1499
 
1477
 
Line 1500... Line 1478...
1500
        DEBUGF 1,"trying loopback\n"
1478
        DEBUGF 1,"trying loopback\n"
1501
 
1479
 
1502
        push    eax
1480
        push    eax
1503
; switch to register window 3
1481
; switch to register window 3
1504
        set_io  0
1482
        set_io  [ebx + device.io_addr], 0
1505
        set_io  REG_COMMAND
1483
        set_io  [ebx + device.io_addr], REG_COMMAND
1506
        mov     ax, SELECT_REGISTER_WINDOW+3
1484
        mov     ax, SELECT_REGISTER_WINDOW+3
Line 1507... Line 1485...
1507
        out     dx, ax
1485
        out     dx, ax
1508
        mov     eax, [esp]
1486
        mov     eax, [esp]
1509
 
1487
 
1510
        mov     cl, al
1488
        mov     cl, al
Line 1511... Line 1489...
1511
        inc     cl
1489
        inc     cl
1512
        shl     cl, 3
1490
        shl     cl, 3
1513
        or      byte [device.state+1], cl
1491
        or      byte [ebx + device.internal_link+1], cl
1514
 
1492
 
Line 1531... Line 1509...
1531
        xchg    eax, [esp]
1509
        xchg    eax, [esp]
1532
        test    al, al
1510
        test    al, al
1533
        jz      .aui_finish
1511
        jz      .aui_finish
Line 1534... Line 1512...
1534
 
1512
 
1535
; issue DisableDcConverter command
1513
; issue DisableDcConverter command
1536
        set_io  0
1514
        set_io  [ebx + device.io_addr], 0
1537
        set_io  REG_COMMAND
1515
        set_io  [ebx + device.io_addr], REG_COMMAND
1538
        mov     ax, (10111b shl 11)
1516
        mov     ax, (10111b shl 11)
1539
        out     dx, ax
1517
        out     dx, ax
1540
  .aui_finish:
1518
  .aui_finish:
Line 1541... Line 1519...
1541
        pop     eax ; al contains the result of operation
1519
        pop     eax ; al contains the result of operation
1542
 
1520
 
1543
        test    al, al
1521
        test    al, al
1544
        jnz     @f
1522
        jnz     @f
Line 1545... Line 1523...
1545
        and     byte [device.state+1], not 11000b
1523
        and     byte [ebx + device.internal_link+1], not 11000b
Line 1563... Line 1541...
1563
set_active_port:
1541
set_active_port:
Line 1564... Line 1542...
1564
 
1542
 
Line 1565... Line 1543...
1565
        DEBUGF 1,"Trying to find the active port\n"
1543
        DEBUGF 1,"Trying to find the active port\n"
1566
 
1544
 
1567
; switch to register window 3
1545
; switch to register window 3
1568
        set_io  0
1546
        set_io  [ebx + device.io_addr], 0
1569
        set_io  REG_COMMAND
1547
        set_io  [ebx + device.io_addr], REG_COMMAND
Line 1570... Line 1548...
1570
        mov     ax, SELECT_REGISTER_WINDOW + 3
1548
        mov     ax, SELECT_REGISTER_WINDOW + 3
1571
        out     dx, ax
1549
        out     dx, ax
1572
 
1550
 
1573
        set_io  REG_INTERNAL_CONFIG
1551
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
Line 1574... Line 1552...
1574
        in      eax, dx
1552
        in      eax, dx
1575
        test    eax, (1 shl 24) ; check if autoselect enable
1553
        test    eax, (1 shl 24) ; check if autoselect enable
1576
        jz      .set_first_available_media
1554
        jz      .set_first_available_media
1577
 
1555
 
1578
; check 100BASE-TX and 10BASE-T
1556
; check 100BASE-TX and 10BASE-T
Line 1579... Line 1557...
1579
        set_io  REG_MEDIA_OPTIONS
1557
        set_io  [ebx + device.io_addr], REG_MEDIA_OPTIONS
1580
        in      ax, dx
1558
        in      ax, dx
1581
        test    al, 1010b       ; check whether 100BASE-TX or 10BASE-T available
1559
        test    al, 1010b       ; check whether 100BASE-TX or 10BASE-T available
1582
        jz      .mii_device     ; they are not available
1560
        jz      .mii_device     ; they are not available
1583
 
1561
 
1584
; set auto-negotiation
1562
; set auto-negotiation
1585
        set_io  REG_INTERNAL_CONFIG
1563
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
Line 1593... Line 1571...
1593
        DEBUGF 1,"Using auto negotiation\n"
1571
        DEBUGF 1,"Using auto negotiation\n"
1594
        ret
1572
        ret
Line 1595... Line 1573...
1595
 
1573
 
1596
  .mii_device:
1574
  .mii_device:
1597
; switch to register window 3
1575
; switch to register window 3
1598
        set_io  0
1576
        set_io  [ebx + device.io_addr], 0
1599
; check for off-chip mii device
1577
; check for off-chip mii device
1600
        set_io  REG_MEDIA_OPTIONS
1578
        set_io  [ebx + device.io_addr], REG_MEDIA_OPTIONS
1601
        in      ax, dx
1579
        in      ax, dx
1602
        test    al, 1000000b ; check miiDevice
1580
        test    al, 1000000b ; check miiDevice
1603
        jz      .base_fx
1581
        jz      .base_fx
1604
        set_io  REG_INTERNAL_CONFIG
1582
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1605
        in      eax, dx
1583
        in      eax, dx
1606
        and     eax, not (1111b shl 20)
1584
        and     eax, not (1111b shl 20)
1607
        or      eax, (0110b shl 20) ; set MIIDevice
1585
        or      eax, (0110b shl 20) ; set MIIDevice
1608
        out     dx, eax
1586
        out     dx, eax
Line 1612... Line 1590...
1612
        DEBUGF 1,"Using off-chip mii device\n"
1590
        DEBUGF 1,"Using off-chip mii device\n"
1613
        ret
1591
        ret
Line 1614... Line 1592...
1614
 
1592
 
1615
  .base_fx:
1593
  .base_fx:
1616
; switch to register window 3
1594
; switch to register window 3
1617
        set_io  0
1595
        set_io  [ebx + device.io_addr], 0
1618
; check for 100BASE-FX
1596
; check for 100BASE-FX
1619
        set_io  REG_MEDIA_OPTIONS
1597
        set_io  [ebx + device.io_addr], REG_MEDIA_OPTIONS
1620
        in      ax, dx ; read media option register
1598
        in      ax, dx ; read media option register
1621
        test    al, 100b ; check 100BASE-FX
1599
        test    al, 100b ; check 100BASE-FX
1622
        jz      .aui_enable
1600
        jz      .aui_enable
1623
        set_io  REG_INTERNAL_CONFIG
1601
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1624
        in      eax, dx
1602
        in      eax, dx
1625
        and     eax, not (1111b shl 20)
1603
        and     eax, not (1111b shl 20)
1626
        or      eax, (0101b shl 20) ; set 100base-FX
1604
        or      eax, (0101b shl 20) ; set 100base-FX
1627
        out     dx, eax
1605
        out     dx, eax
Line 1631... Line 1609...
1631
        DEBUGF 1,"Using 100Base-FX\n"
1609
        DEBUGF 1,"Using 100Base-FX\n"
1632
        ret
1610
        ret
Line 1633... Line 1611...
1633
 
1611
 
1634
  .aui_enable:
1612
  .aui_enable:
1635
; switch to register window 3
1613
; switch to register window 3
1636
        set_io  0
1614
        set_io  [ebx + device.io_addr], 0
1637
; check for 10Mbps AUI connector
1615
; check for 10Mbps AUI connector
1638
        set_io  REG_MEDIA_OPTIONS
1616
        set_io  [ebx + device.io_addr], REG_MEDIA_OPTIONS
1639
        in      ax, dx ; read media option register
1617
        in      ax, dx ; read media option register
1640
        test    al, 100000b ; check 10Mbps AUI connector
1618
        test    al, 100000b ; check 10Mbps AUI connector
1641
        jz      .coax_available
1619
        jz      .coax_available
1642
        set_io  REG_INTERNAL_CONFIG
1620
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1643
        in      eax, dx
1621
        in      eax, dx
1644
        and     eax, not (1111b shl 20)
1622
        and     eax, not (1111b shl 20)
1645
        or      eax, (0001b shl 20) ; set 10Mbps AUI connector
1623
        or      eax, (0001b shl 20) ; set 10Mbps AUI connector
1646
        out     dx, eax
1624
        out     dx, eax
Line 1651... Line 1629...
1651
        DEBUGF 1,"Using 10Mbps aui\n"
1629
        DEBUGF 1,"Using 10Mbps aui\n"
1652
        ret
1630
        ret
Line 1653... Line 1631...
1653
 
1631
 
1654
  .coax_available:
1632
  .coax_available:
1655
; switch to register window 3
1633
; switch to register window 3
1656
        set_io  0
1634
        set_io  [ebx + device.io_addr], 0
1657
; check for coaxial 10BASE-2 port
1635
; check for coaxial 10BASE-2 port
1658
        set_io  REG_MEDIA_OPTIONS
1636
        set_io  [ebx + device.io_addr], REG_MEDIA_OPTIONS
1659
        in      ax, dx ; read media option register
1637
        in      ax, dx ; read media option register
1660
        test    al, 10000b ; check 10BASE-2
1638
        test    al, 10000b ; check 10BASE-2
Line 1661... Line 1639...
1661
        jz      .set_first_available_media
1639
        jz      .set_first_available_media
1662
 
1640
 
1663
        set_io  REG_INTERNAL_CONFIG
1641
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1664
        in      eax, dx
1642
        in      eax, dx
1665
        and     eax, not (1111b shl 20)
1643
        and     eax, not (1111b shl 20)
1666
        or      eax, (0011b shl 20) ; set 10BASE-2
1644
        or      eax, (0011b shl 20) ; set 10BASE-2
Line 1693... Line 1671...
1693
align 4
1671
align 4
1694
set_available_media:
1672
set_available_media:
Line 1695... Line 1673...
1695
 
1673
 
1696
        DEBUGF  1,"Setting the available media\n"
1674
        DEBUGF  1,"Setting the available media\n"
1697
; switch to register window 3
1675
; switch to register window 3
1698
        set_io  0
1676
        set_io  [ebx + device.io_addr], 0
1699
        set_io  REG_COMMAND
1677
        set_io  [ebx + device.io_addr], REG_COMMAND
1700
        mov     ax, SELECT_REGISTER_WINDOW+3
1678
        mov     ax, SELECT_REGISTER_WINDOW+3
Line 1701... Line 1679...
1701
        out     dx, ax
1679
        out     dx, ax
1702
 
1680
 
1703
        set_io  REG_MEDIA_OPTIONS
1681
        set_io  [ebx + device.io_addr], REG_MEDIA_OPTIONS
1704
        in      ax, dx
1682
        in      ax, dx
Line 1705... Line 1683...
1705
        DEBUGF  1,"available media:%x\n", al
1683
        DEBUGF  1,"available media:%x\n", al
1706
        mov     cl, al
1684
        mov     cl, al
1707
 
1685
 
Line 1708... Line 1686...
1708
        set_io  REG_INTERNAL_CONFIG
1686
        set_io  [ebx + device.io_addr], REG_INTERNAL_CONFIG
1709
        in      eax, dx
1687
        in      eax, dx
Line 1710... Line 1688...
1710
        and     eax, not (1111b shl 20) ; these bits hold the 'transceiver select' value
1688
        and     eax, not (1111b shl 20) ; these bits hold the 'transceiver select' value
1711
 
1689
 
1712
        test    cl, 10b         ; baseTXAvailable
1690
        test    cl, 10b         ; baseTXAvailable
1713
        jz      @f
1691
        jz      @f
1714
 
1692
 
1715
        DEBUGF  1,"base TX is available\n"
1693
        DEBUGF  1,"base TX is available\n"
1716
        or      eax, (100b shl 20)
1694
        or      eax, (100b shl 20)
1717
if defined FORCE_FD
1695
if FORCE_FD
1718
        mov     word [device.state], (1 shl 8)
1696
        mov     word [ebx + device.internal_link], (1 shl 8)
Line 1719... Line 1697...
1719
else
1697
else
1720
        mov     word [device.mode], (1 shl 7)
1698
        mov     word [ebx + device.internal_link], (1 shl 7)
Line 1721... Line 1699...
1721
end if
1699
end if
1722
        jmp     .set_media
1700
        jmp     .set_media
1723
       @@:
1701
       @@:
1724
 
1702
 
1725
        test    cl, 100b        ; baseFXAvailable
1703
        test    cl, 100b        ; baseFXAvailable
Line 1726... Line 1704...
1726
        jz      @f
1704
        jz      @f
1727
 
1705
 
Line 1728... Line 1706...
1728
        DEBUGF  1,"base FX is available\n"
1706
        DEBUGF  1,"base FX is available\n"
1729
        or      eax, (101b shl 20)
1707
        or      eax, (101b shl 20)
1730
        mov     word [device.state], (1 shl 10)
1708
        mov     word [ebx + device.internal_link], (1 shl 10)
1731
        jmp     .set_media
1709
        jmp     .set_media
1732
       @@:
1710
       @@:
Line 1733... Line 1711...
1733
 
1711
 
1734
        test    cl, 1000000b    ; miiDevice
1712
        test    cl, 1000000b    ; miiDevice
Line 1735... Line 1713...
1735
        jz      @f
1713
        jz      @f
1736
 
1714
 
1737
        DEBUGF  1,"mii-device is available\n"
1715
        DEBUGF  1,"mii-device is available\n"
1738
        or      eax, (0110b shl 20)
1716
        or      eax, (0110b shl 20)
1739
        mov     word [device.state], (1 shl 13)
1717
        mov     word [ebx + device.internal_link], (1 shl 13)
1740
        jmp     .set_media
1718
        jmp     .set_media
1741
       @@:
1719
       @@:
1742
 
1720
 
1743
        test    cl, 1000b       ; 10bTAvailable
1721
        test    cl, 1000b       ; 10bTAvailable
Line 1744... Line 1722...
1744
        jz      @f
1722
        jz      @f
1745
 
1723
 
Line 1746... Line 1724...
1746
        DEBUGF  1,"10base-T is available\n"
1724
        DEBUGF  1,"10base-T is available\n"
1747
  .set_default:
1725
  .set_default:
1748
if FORCE_FD
1726
if FORCE_FD
1749
        mov     word [device.state], (1 shl 6)
1727
        mov     word [ebx + device.internal_link], (1 shl 6)
1750
else
1728
else
1751
        mov     word [device.state], (1 shl 5)
1729
        mov     word [ebx + device.internal_link], (1 shl 5)
Line 1752... Line 1730...
1752
end if
1730
end if
1753
        jmp     .set_media
1731
        jmp     .set_media
1754
       @@:
1732
       @@:
1755
 
1733
 
Line 1756... Line 1734...
1756
        test    cl, 10000b      ; coaxAvailable
1734
        test    cl, 10000b      ; coaxAvailable
1757
        jz      @f
1735
        jz      @f
Line 1758... Line 1736...
1758
 
1736
 
1759
        DEBUGF  1,"coax is available\n"
1737
        DEBUGF  1,"coax is available\n"
1760
        push    eax
1738
        push    eax
Line 1761... Line 1739...
1761
        set_io  REG_COMMAND
1739
        set_io  [ebx + device.io_addr], REG_COMMAND
1762
        mov     ax, (10b shl 11) ; EnableDcConverter
1740
        mov     ax, (10b shl 11) ; EnableDcConverter
1763
        out     dx, ax
1741
        out     dx, ax
1764
        pop     eax
1742
        pop     eax
Line 1765... Line 1743...
1765
 
1743
 
1766
        or      eax, (11b shl 20)
1744
        or      eax, (11b shl 20)
1767
        mov     word [device.state], (1 shl 12)
1745
        mov     word [ebx + device.internal_link], (1 shl 12)
1768
        jmp     .set_media
1746
        jmp     .set_media
1769
       @@:
1747
       @@:
1770
 
1748
 
1771
        test    cl, 10000b      ; auiAvailable
1749
        test    cl, 10000b      ; auiAvailable
Line 1772... Line 1750...
1772
        jz      .set_default
1750
        jz      .set_default
1773
 
1751
 
Line 1774... Line -...
1774
        DEBUGF  1,"AUI is available\n"
-
 
1775
        or      eax, (1 shl 20)
-
 
1776
        mov     word [device.state], (1 shl 11)
-
 
1777
 
-
 
1778
  .set_media:
-
 
1779
        set_io  0
-
 
1780
        set_io  REG_INTERNAL_CONFIG
-
 
1781
        out     dx, eax
-
 
1782
 
-
 
1783
if FORCE_FD
-
 
1784
        DEBUGF  1,"Forcing full duplex\n"
-
 
1785
        set_io  REG_MAC_CONTROL
-
 
1786
        in      ax, dx
-
 
1787
        or      ax, 0x120
-
 
1788
        out     dx, ax
-
 
1789
end if
-
 
1790
 
-
 
1791
        mov     al, 1
-
 
1792
        ret
-
 
1793
 
-
 
1794
 
-
 
1795
 
-
 
1796
;***************************************************************************
-
 
1797
;   Function
-
 
1798
;      wake_up
-
 
1799
;   Description
-
 
1800
;      set the power state to D0
-
 
1801
;
-
 
1802
;***************************************************************************
-
 
1803
 
-
 
1804
align 4
-
 
1805
wake_up:
-
 
1806
 
-
 
1807
        DEBUGF 1,"Waking up NIC: "
-
 
1808
 
-
 
1809
; wake up - we directly do it by programming PCI
-
 
1810
; check if the device is power management capable
-
 
1811
        stdcall PciRead32, [device.pci_bus], [device.pci_dev], PCI_REG_STATUS
-
 
1812
 
-
 
1813
        test    al, 10000b      ; is there "new capabilities" linked list?
-
 
1814
        jz      .device_awake
-
 
1815
 
-
 
1816
; search for power management register
-
 
1817
        stdcall PciRead16, [device.pci_bus], [device.pci_dev], PCI_REG_CAP_PTR
-
 
1818
        cmp     al, 0x3f
-
 
1819
        jbe     .device_awake
-
 
1820
 
-
 
1821
; traverse the list
-
 
1822
        movzx   esi, al
-
 
1823
  .pm_loop:
-
 
1824
        stdcall PciRead32, [device.pci_bus], [device.pci_dev], esi
-
 
1825
 
-
 
1826
        cmp     al , 1
-
 
1827
        je      .set_pm_state
-
 
1828
 
-
 
1829
        movzx   esi, ah
-
 
1830
 
-
 
1831
        test    ah , ah
-
 
1832
        jnz     .pm_loop
-
 
1833
        jmp     .device_awake
1752
        DEBUGF  1,"AUI is available\n"
1834
 
1753
        or      eax, (1 shl 20)
1835
; waku up the device if necessary
1754
        mov     word [ebx + device.internal_link], (1 shl 11)
1836
  .set_pm_state:
1755
 
1837
 
1756
  .set_media:
Line 1953... Line 1872...
1953
 
1872
 
Line 1954... Line 1873...
1954
        DEBUGF 1,"Reading from eeprom.. "
1873
        DEBUGF 1,"Reading from eeprom.. "
1955
 
1874
 
1956
        push    eax
1875
        push    eax
1957
; switch to register window 0
1876
; switch to register window 0
1958
        set_io  0
1877
        set_io  [ebx + device.io_addr], 0
1959
        set_io  REG_COMMAND
1878
        set_io  [ebx + device.io_addr], REG_COMMAND
1960
        mov     ax, SELECT_REGISTER_WINDOW+0
1879
        mov     ax, SELECT_REGISTER_WINDOW+0
1961
        out     dx, ax
1880
        out     dx, ax
1962
        pop     eax
1881
        pop     eax
Line 1963... Line 1882...
1963
        and     ax, 111111b ; take only the first 6 bits into account
1882
        and     ax, 111111b ; take only the first 6 bits into account
1964
        movzx   esi, [device.ver_id]
1883
        movzx   esi, [ebx + device.ver_id]
1965
 
1884
 
1966
        test    word [esi*4+hw_versions+2], EEPROM_8BIT
1885
        test    word [esi*4+hw_versions+2], EEPROM_8BIT
Line 1973... Line 1892...
1973
        test    word [esi*4+hw_versions+2], EEPROM_OFFSET
1892
        test    word [esi*4+hw_versions+2], EEPROM_OFFSET
1974
        jz      .read
1893
        jz      .read
1975
        add     ax, 0x30
1894
        add     ax, 0x30
1976
.read:
1895
.read:
Line 1977... Line 1896...
1977
 
1896
 
1978
        set_io  REG_EEPROM_COMMAND
1897
        set_io  [ebx + device.io_addr], REG_EEPROM_COMMAND
1979
        out     dx, ax
1898
        out     dx, ax
1980
        mov     ecx, 0xffff ; duration of about 162 us ;-)
1899
        mov     ecx, 0xffff ; duration of about 162 us ;-)
1981
.wait_for_reading:
1900
.wait_for_reading:
1982
        in      ax, dx
1901
        in      ax, dx
1983
        test    ah, 0x80 ; check bit eepromBusy
1902
        test    ah, 0x80 ; check bit eepromBusy
1984
        jz      .read_data
1903
        jz      .read_data
1985
        loop    .wait_for_reading
1904
        loop    .wait_for_reading
1986
.read_data:
1905
.read_data:
1987
        set_io  REG_EEPROM_DATA
1906
        set_io  [ebx + device.io_addr], REG_EEPROM_DATA
Line 1988... Line 1907...
1988
        in      ax, dx
1907
        in      ax, dx
Line 1989... Line 1908...
1989
 
1908
 
Line 2008... Line 1927...
2008
mdio_sync:
1927
mdio_sync:
Line 2009... Line 1928...
2009
 
1928
 
Line 2010... Line 1929...
2010
        DEBUGF 1,"syncing mdio\n"
1929
        DEBUGF 1,"syncing mdio\n"
2011
 
1930
 
2012
; switch to register window 4
1931
; switch to register window 4
2013
        set_io  0
1932
        set_io  [ebx + device.io_addr], 0
2014
        set_io  REG_COMMAND
1933
        set_io  [ebx + device.io_addr], REG_COMMAND
2015
        mov     ax, SELECT_REGISTER_WINDOW+4
1934
        mov     ax, SELECT_REGISTER_WINDOW+4
2016
        out     dx, ax
1935
        out     dx, ax
2017
        cmp     [device.preamble], 0
1936
        cmp     [ebx + device.preamble], 0
2018
        je      .no_preamble
1937
        je      .no_preamble
2019
; send 32 logic ones
1938
; send 32 logic ones
2020
        set_io  REG_PHYSICAL_MGMT
1939
        set_io  [ebx + device.io_addr], REG_PHYSICAL_MGMT
2021
        mov     ecx, 31
1940
        mov     ecx, 31
2022
  .loop:
1941
  .loop:
2023
        mov     ax, (1 shl BIT_MGMT_DATA) or (1 shl BIT_MGMT_DIR)
1942
        mov     ax, (1 shl BIT_MGMT_DATA) or (1 shl BIT_MGMT_DIR)
Line 2052... Line 1971...
2052
        DEBUGF 1,"Reading MII registers\n"
1971
        DEBUGF 1,"Reading MII registers\n"
Line 2053... Line 1972...
2053
 
1972
 
2054
        push    eax
1973
        push    eax
2055
        call    mdio_sync ; returns with window #4
1974
        call    mdio_sync ; returns with window #4
2056
        pop     eax
1975
        pop     eax
2057
        set_io  0
1976
        set_io  [ebx + device.io_addr], 0
2058
        set_io  REG_PHYSICAL_MGMT
1977
        set_io  [ebx + device.io_addr], REG_PHYSICAL_MGMT
2059
        shl     al, 3
1978
        shl     al, 3
2060
        shr     ax, 3
1979
        shr     ax, 3
2061
        and     ax, not MII_CMD_MASK
1980
        and     ax, not MII_CMD_MASK
Line 2123... Line 2042...
2123
        DEBUGF 1,"Writing MII registers\n"
2042
        DEBUGF 1,"Writing MII registers\n"
Line 2124... Line 2043...
2124
 
2043
 
2125
        push    eax
2044
        push    eax
2126
        call    mdio_sync
2045
        call    mdio_sync
2127
        pop     eax
2046
        pop     eax
2128
        set_io  0
2047
        set_io  [ebx + device.io_addr], 0
2129
        set_io  REG_PHYSICAL_MGMT
2048
        set_io  [ebx + device.io_addr], REG_PHYSICAL_MGMT
2130
        shl     al, 3
2049
        shl     al, 3
2131
        shr     ax, 3
2050
        shr     ax, 3
2132
        and     ax, not MII_CMD_MASK
2051
        and     ax, not MII_CMD_MASK
2133
        or      ax, MII_CMD_WRITE
2052
        or      ax, MII_CMD_WRITE
Line 2173... Line 2092...
2173
check_tx_status:
2092
check_tx_status:
Line 2174... Line 2093...
2174
 
2093
 
Line 2175... Line 2094...
2175
        DEBUGF 1,"Checking TX status\n"
2094
        DEBUGF 1,"Checking TX status\n"
2176
 
2095
 
2177
; clear TxStatus queue
2096
; clear TxStatus queue
2178
        set_io  0
2097
        set_io  [ebx + device.io_addr], 0
Line 2179... Line 2098...
2179
        set_io  REG_TX_STATUS
2098
        set_io  [ebx + device.io_addr], REG_TX_STATUS
2180
        mov     ecx, 31 ; max number of queue entries
2099
        mov     ecx, 31 ; max number of queue entries
2181
 
2100
 
Line 2190... Line 2109...
2190
        xor     al, al
2109
        xor     al, al
2191
        out     dx, al
2110
        out     dx, al
2192
        loop    .tx_status_loop
2111
        loop    .tx_status_loop
Line 2193... Line 2112...
2193
 
2112
 
2194
  .finish:
-
 
2195
 
2113
  .finish:
Line 2196... Line 2114...
2196
        ret
2114
        ret
2197
 
2115
 
2198
  .error:
2116
  .error:
Line 2209... Line 2127...
2209
;;     size of buffer in [esp+8]           ;;
2127
;;     size of buffer in [esp+8]           ;;
2210
;;     pointer to device structure in ebx  ;;
2128
;;     pointer to device structure in ebx  ;;
2211
;;                                         ;;
2129
;;                                         ;;
2212
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2130
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line -... Line 2131...
-
 
2131
 
-
 
2132
proc vortex_transmit stdcall bufferptr, buffersize
2213
 
2133
 
2214
align 4
2134
        pushf
Line -... Line 2135...
-
 
2135
        cli
2215
vortex_transmit:
2136
 
-
 
2137
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
-
 
2138
        mov     eax, [bufferptr]
-
 
2139
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
-
 
2140
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
Line 2216... Line 2141...
2216
 
2141
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
2217
        DEBUGF 1,"Sending packet (vortex)\n"
2142
        [eax+13]:2,[eax+12]:2
-
 
2143
 
-
 
2144
        cmp     [buffersize], 1514
Line 2218... Line 2145...
2218
 
2145
        ja      .fail
Line 2219... Line 2146...
2219
        cmp     dword [esp+8], MAX_ETH_FRAME_SIZE
2146
        cmp     [buffersize], 60
2220
        ja      .finish ; packet is too long
2147
        jb      .fail
2221
 
2148
 
2222
        call    check_tx_status
2149
        call    check_tx_status
2223
 
2150
 
2224
; switch to register window 7
2151
; switch to register window 7
2225
        set_io  0
2152
        set_io  [ebx + device.io_addr], 0
2226
        set_io  REG_COMMAND
2153
        set_io  [ebx + device.io_addr], REG_COMMAND
2227
        mov     ax, SELECT_REGISTER_WINDOW+7
2154
        mov     ax, SELECT_REGISTER_WINDOW+7
2228
        out     dx, ax
2155
        out     dx, ax
2229
; check for master operation in progress
2156
; check for master operation in progress
2230
        set_io  REG_MASTER_STATUS
2157
        set_io  [ebx + device.io_addr], REG_MASTER_STATUS
2231
        in      ax, dx
2158
        in      ax, dx
2232
        test    ah, 0x80
2159
        test    ah, 0x80
2233
        jnz     .fail ; no DMA for sending
2160
        jnz     .fail ; no DMA for sending
2234
; program frame address to be sent
2161
; program frame address to be sent
2235
        set_io  REG_MASTER_ADDRESS
2162
        set_io  [ebx + device.io_addr], REG_MASTER_ADDRESS
2236
        mov     eax, [esp+4]
2163
        mov     eax, [bufferptr]
2237
        call    GetPgAddr
-
 
2238
        out     dx, eax
2164
        invoke  GetPhysAddr
2239
; program frame length
2165
        out     dx, eax
2240
        set_io  REG_MASTER_LEN
2166
; program frame length
2241
        mov     eax, [esp+8]
2167
        set_io  [ebx + device.io_addr], REG_MASTER_LEN
2242
;;;        and     eax, not 3
2168
        mov     eax, [buffersize]
2243
        out     dx, ax
2169
        out     dx, ax
-
 
2170
; start DMA Down
2244
; start DMA Down
2171
        set_io  [ebx + device.io_addr], REG_COMMAND
2245
        set_io  REG_COMMAND
2172
        mov     ax, (10100b shl 11) + 1 ; StartDMADown
Line 2246... Line 2173...
2246
        mov     ax, (10100b shl 11) + 1 ; StartDMADown
2173
        out     dx, ax
-
 
2174
  .finish:
2247
        out     dx, ax
2175
        popf
-
 
2176
        xor     eax, eax
2248
  .finish:
2177
        ret
2249
        xor     eax, eax
2178
 
-
 
2179
  .fail:
-
 
2180
        DEBUGF  2,"Send failed\n"
Line 2250... Line 2181...
2250
        ret     8
2181
        invoke  KernelFree, [bufferptr]
2251
 
2182
        popf
2252
  .fail:
2183
        or      eax, -1
2253
        stdcall KernelFree, [esp+4]
2184
        ret
Line 2262... Line 2193...
2262
;;     size of buffer in [esp+8]           ;;
2193
;;     size of buffer in [esp+8]           ;;
2263
;;     pointer to device structure in ebx  ;;
2194
;;     pointer to device structure in ebx  ;;
2264
;;                                         ;;
2195
;;                                         ;;
2265
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2196
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line -... Line 2197...
-
 
2197
 
-
 
2198
proc boomerang_transmit stdcall bufferptr, buffersize
2266
 
2199
 
2267
align 4
2200
        pushf
Line 2268... Line 2201...
2268
boomerang_transmit:
2201
        cli
2269
 
2202
 
2270
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8]
2203
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
2271
        mov     eax, [esp+4]
2204
        mov     eax, [bufferptr]
2272
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
2205
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
2273
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
2206
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
Line 2274... Line 2207...
2274
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
2207
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
2275
        [eax+13]:2,[eax+12]:2
2208
        [eax+13]:2,[eax+12]:2
-
 
2209
 
-
 
2210
        cmp     [buffersize], 1514
Line 2276... Line 2211...
2276
 
2211
        ja      .fail
Line 2277... Line 2212...
2277
        cmp     dword [esp+8], MAX_ETH_FRAME_SIZE
2212
        cmp     [buffersize], 60
2278
        ja      .fail
2213
        jb      .fail
2279
 
2214
 
2280
        call    check_tx_status
2215
        call    check_tx_status                         ; Reset TX engine if needed
2281
 
2216
 
2282
; calculate descriptor address
2217
; calculate descriptor address
2283
        mov     esi, [device.prev_dpd]
2218
        mov     esi, [ebx + device.curr_tx]
2284
        DEBUGF  1,"Previous DPD: %x\n", esi
2219
        DEBUGF  1,"Previous TX desc: %x\n", esi
2285
        add     esi, dpd.size
2220
        add     esi, sizeof.tx_desc
2286
        lea     ecx, [device.dpd_buffer + (NUM_TX_DESC)*dpd.size]
2221
        lea     ecx, [ebx + device.tx_desc_buffer + (NUM_TX_DESC)*sizeof.tx_desc]
Line 2287... Line 2222...
2287
        cmp     esi, ecx
2222
        cmp     esi, ecx
2288
        jb      @f
2223
        jb      @f
2289
        lea     esi, [device.dpd_buffer]        ; Wrap if needed
2224
        lea     esi, [ebx + device.tx_desc_buffer]      ; Wrap if needed
2290
       @@:
2225
       @@:
2291
        DEBUGF  1,"Found a free DPD: %x\n", esi
2226
        DEBUGF  1,"Using TX desc: %x\n", esi
2292
 
2227
 
2293
; check DnListPtr
2228
; check DnListPtr
Line 2294... Line 2229...
2294
        set_io  0
2229
        set_io  [ebx + device.io_addr], 0
2295
        set_io  REG_DN_LIST_PTR
2230
        set_io  [ebx + device.io_addr], REG_DN_LIST_PTR
2296
        in      eax, dx
2231
        in      eax, dx
Line 2297... Line 2232...
2297
; mark if Dn_List_Ptr is cleared
2232
; mark if Dn_List_Ptr is cleared
2298
        test    eax, eax
2233
        test    eax, eax
2299
        setz    [device.dn_list_ptr_cleared]
2234
        setz    [ebx + device.dn_list_ptr_cleared]
2300
 
2235
 
2301
; finish if no more free descriptor is available - FIXME!
2236
; finish if no more free descriptor is available - FIXME!
Line 2302... Line 2237...
2302
;        cmp     eax, esi
2237
;        cmp     eax, esi
2303
;        jz      .finish
2238
;        jz      .finish
2304
 
2239
 
2305
; update statistics
2240
; update statistics
2306
        inc     [device.packets_tx]
2241
        inc     [ebx + device.packets_tx]
2307
        mov     ecx, [esp+8]            ; buffer size
2242
        mov     ecx, [buffersize]
2308
        add     dword [device.bytes_tx], ecx
2243
        add     dword [ebx + device.bytes_tx], ecx
2309
        adc     dword [device.bytes_tx + 4], 0
2244
        adc     dword [ebx + device.bytes_tx + 4], 0
2310
 
2245
 
2311
; program DPD
2246
; program DPD
2312
        and     [esi+dpd.next_ptr], 0
2247
        and     [esi + tx_desc.next_ptr], 0
2313
        mov     eax, [esp+4]            ; Tx buffer address
2248
        mov     eax, [bufferptr]
2314
        mov     [esi+dpd.realaddr], eax
-
 
2315
        call    GetPgAddr
-
 
2316
        mov     [esi+dpd.frag_addr], eax
-
 
2317
        mov     ecx, [esp+8]            ; packet size
2249
        mov     [esi + tx_desc.realaddr], eax
2318
        or      ecx, 0x80000000         ; last fragment
2250
        invoke  GetPhysAddr
2319
        mov     [esi+dpd.frag_len], ecx
2251
        mov     [esi + tx_desc.frag_addr], eax
2320
 
2252
        mov     ecx, [buffersize]
2321
        mov     ecx, [esp+8]            ; packet size
2253
        or      ecx, 0x80000000         ; last fragment flag
2322
;        or      ecx, 0x8000             ; transmission complete notification
-
 
2323
 
2254
        mov     [esi + tx_desc.frag_len], ecx
Line 2324... Line 2255...
2324
        or      ecx, 1 shl 31
2255
 
2325
 
2256
        mov     ecx, [buffersize]       ; packet size
2326
;        test    byte [device.has_hwcksm], 0xff
2257
        or      ecx, 0x80008000         ; set OWN bit + transmission complete notification flag
2327
;        jz      @f
2258
;        test    byte [ebx + device.has_hwcksm], 0xff
2328
;        or      ecx, (1 shl 26)         ; set AddTcpChecksum
2259
;        jz      @f
Line 2329... Line 2260...
2329
;@@:
2260
;        or      ecx, (1 shl 26)         ; set AddTcpChecksum
2330
        mov     [esi+dpd.frame_start_hdr], ecx
2261
;@@:
2331
 
2262
        mov     [esi + tx_desc.frame_start_hdr], ecx
2332
        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
2263
        DEBUGF  1,"TX desc: lin=%x phys=%x len=%x start hdr=%x\n", [esi+tx_desc.realaddr]:8, [esi+tx_desc.frag_addr]:8, [esi+tx_desc.frag_len]:8, [esi+tx_desc.frame_start_hdr]:8
2333
 
2264
 
2334
; calculate physical address of dpd
2265
; calculate physical address of tx descriptor
Line 2335... Line 2266...
2335
        mov     eax, esi
2266
        mov     eax, esi
2336
        GetRealAddr
2267
        invoke  GetPhysAddr
2337
        cmp     [device.dn_list_ptr_cleared], 0
2268
        cmp     [ebx + device.dn_list_ptr_cleared], 0
2338
        jz      .add_to_list
2269
        je      .add_to_list
2339
 
2270
 
2340
; write Dn_List_Ptr
2271
; write Dn_List_Ptr
2341
        DEBUGF  1,"DPD phys addr=%x\n", eax
2272
        DEBUGF  1,"TX desc phys addr=%x\n", eax
2342
        set_io  0
2273
        set_io  [ebx + device.io_addr], 0
Line 2343... Line 2274...
2343
        set_io  REG_DN_LIST_PTR
2274
        set_io  [ebx + device.io_addr], REG_DN_LIST_PTR
2344
        out     dx, eax
2275
        out     dx, eax
Line 2363... Line 2294...
2363
        dec     ecx
2294
        dec     ecx
2364
        jnz     .wait_for_stall
2295
        jnz     .wait_for_stall
Line 2365... Line 2296...
2365
 
2296
 
2366
  .dnstall_ok:
2297
  .dnstall_ok:
2367
        DEBUGF  1,"DnStall ok!\n"
2298
        DEBUGF  1,"DnStall ok!\n"
2368
        mov     ecx, [device.prev_dpd]
2299
        mov     ecx, [ebx + device.curr_tx]
Line 2369... Line 2300...
2369
        mov     [ecx+dpd.next_ptr], eax
2300
        mov     [ecx + tx_desc.next_ptr], eax
2370
 
2301
 
2371
        set_io  0
2302
        set_io  [ebx + device.io_addr], 0
2372
        set_io  REG_DN_LIST_PTR
2303
        set_io  [ebx + device.io_addr], REG_DN_LIST_PTR
2373
        in      eax, dx
2304
        in      eax, dx
2374
        test    eax, eax
2305
        test    eax, eax
Line 2379... Line 2310...
2379
        DEBUGF  1,"DnList Ptr has been cleared\n"
2310
        DEBUGF  1,"DnList Ptr has been cleared\n"
2380
        out     dx, eax
2311
        out     dx, eax
Line 2381... Line 2312...
2381
 
2312
 
2382
  .dnunstall:
2313
  .dnunstall:
2383
; DnUnStall
2314
; DnUnStall
2384
        set_io  0
2315
        set_io  [ebx + device.io_addr], 0
2385
        set_io  REG_COMMAND
2316
        set_io  [ebx + device.io_addr], REG_COMMAND
2386
        mov     ax, ((110b shl 11)+3)
2317
        mov     ax, ((110b shl 11)+3)
Line 2387... Line 2318...
2387
        out     dx, ax
2318
        out     dx, ax
2388
 
2319
 
-
 
2320
  .finish:
2389
  .finish:
2321
        mov     [ebx + device.curr_tx], esi
2390
        mov     [device.prev_dpd], esi
2322
        popf
Line 2391... Line 2323...
2391
        xor     eax, eax
2323
        xor     eax, eax
-
 
2324
        ret
2392
        ret     8
2325
 
-
 
2326
  .fail:
2393
 
2327
        DEBUGF  2,"Send failed\n"
2394
  .fail:
2328
        invoke  KernelFree, [bufferptr]
-
 
2329
        popf
-
 
2330
        or      eax, -1
-
 
2331
        ret
Line 2395... Line 2332...
2395
        stdcall KernelFree, [esp+4]
2332
 
2396
        or      eax, -1
2333
endp
Line 2397... Line 2334...
2397
        ret     8
2334
 
2398
 
2335
 
Line 2399... Line 2336...
2399
 
2336
 
Line 2400... Line 2337...
2400
;---------------------------------
2337
;---------------------------------
2401
; Write MAC
2338
; Write MAC
Line 2402... Line 2339...
2402
 
2339
 
2403
align 4
2340
align 4
2404
write_mac:
2341
write_mac:
Line 2405... Line 2342...
2405
 
2342
 
2406
        DEBUGF 1,"Writing mac\n"
2343
        DEBUGF 1,"Writing mac\n"
2407
 
2344
 
2408
        set_io  0
2345
        set_io  [ebx + device.io_addr], 0
2409
        set_io  REG_COMMAND
2346
        set_io  [ebx + device.io_addr], REG_COMMAND
2410
 
2347
 
2411
; switch to register window 2
2348
; switch to register window 2
2412
        mov     ax, SELECT_REGISTER_WINDOW+2
2349
        mov     ax, SELECT_REGISTER_WINDOW+2
Line 2428... Line 2365...
2428
; Read MAC
2365
; Read MAC
Line 2429... Line 2366...
2429
 
2366
 
2430
align 4
2367
align 4
Line -... Line 2368...
-
 
2368
read_mac:
-
 
2369
 
2431
read_mac:
2370
        DEBUGF 1,"Reading MAC\n"
2432
 
2371
 
Line 2433... Line 2372...
2433
        set_io  0
2372
        set_io  [ebx + device.io_addr], 0
2434
        set_io  REG_COMMAND
2373
        set_io  [ebx + device.io_addr], REG_COMMAND
2435
 
2374
 
Line 2436... Line 2375...
2436
; switch to register window 2
2375
; switch to register window 2
2437
        mov     ax, SELECT_REGISTER_WINDOW+2
2376
        mov     ax, SELECT_REGISTER_WINDOW+2
2438
        out     dx, ax
2377
        out     dx, ax
2439
 
2378
 
2440
; write MAC addres back into the station address registers
2379
; Read the MAC and write it to device.mac
2441
        set_io  REG_STATION_ADDRESS_LO
2380
        set_io  [ebx + device.io_addr], REG_STATION_ADDRESS_LO
2442
        lea     edi, [device.mac]
2381
        lea     edi, [ebx + device.mac]
2443
        insw
2382
        insw
2444
        inc     dx
2383
        inc     dx
2445
        inc     dx
2384
        inc     dx
Line -... Line 2385...
-
 
2385
        insw
-
 
2386
        inc     dx
2446
        insw
2387
        inc     dx
Line 2447... Line 2388...
2447
        inc     dx
2388
        insw
Line 2448... Line 2389...
2448
        inc     dx
2389
 
2449
        insw
2390
        DEBUGF 1,"%x-%x-%x-%x-%x-%x\n", \
Line 2450... Line 2391...
2450
 
2391
        [ebx + device.mac+0]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,\
2451
        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
2392
        [ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
Line 2452... Line 2393...
2452
 
2393
 
Line 2453... Line 2394...
2453
        ret
2394
        ret
2454
 
2395
 
2455
 
2396
 
2456
;------------------------------------
2397
;------------------------------------
2457
; Read MAC from eeprom
2398
; Read MAC from eeprom
2458
 
2399
 
2459
align 4
2400
align 4
2460
read_mac_eeprom:        ; Tested - ok
2401
read_mac_eeprom:
2461
 
2402
 
2462
        DEBUGF 1,"Reading mac from eeprom\n"
2403
        DEBUGF 1,"Reading MAC from eeprom\n"
Line -... Line 2404...
-
 
2404
 
-
 
2405
; read MAC from eeprom and write it to device.mac
2463
 
2406
        mov     ecx, 3
Line 2464... Line 2407...
2464
; read MAC from eeprom
2407
  .mac_loop:
Line 2493... Line 2436...
2493
 
2436
 
Line 2494... Line 2437...
2494
        DEBUGF  1,"INT\n"
2437
        DEBUGF  1,"INT\n"
Line 2495... Line -...
2495
 
-
 
2496
; find pointer of device wich made IRQ occur
2438
 
2497
 
2439
; find pointer of device wich made IRQ occur
2498
        mov     esi, VORTEX_LIST
2440
 
-
 
2441
        mov     ecx, [vortex_devices]
2499
        mov     ecx, [VORTEX_DEVICES]
2442
        test    ecx, ecx
2500
        test    ecx, ecx
2443
        jz      .nothing
Line 2501... Line 2444...
2501
        jz      .nothing
2444
        mov     esi, vortex_list
2502
  .nextdevice:
2445
  .nextdevice:
2503
        mov     ebx, dword [esi]
2446
        mov     ebx, [esi]
2504
 
2447
 
2505
 
2448
 
Line 2506... Line 2449...
2506
        set_io  0
2449
        set_io  [ebx + device.io_addr], 0
Line 2521... Line 2464...
2521
 
2464
 
Line 2522... Line 2465...
2522
        ret
2465
        ret
Line 2523... Line 2466...
2523
 
2466
 
Line 2524... Line 2467...
2524
.got_it:
2467
.got_it:
2525
 
2468
 
Line 2526... Line 2469...
2526
        DEBUGF  1,"Device: %x Status: %x ",ebx,eax:4
2469
        DEBUGF  1,"Device: %x Status: %x\n", ebx, eax:4
2527
 
2470
 
2528
        test    ax, RxComplete
2471
        test    ax, RxComplete
2529
        jz      .noRX
2472
        jz      .noRX
2530
 
2473
 
2531
        set_io  0
2474
        set_io  [ebx + device.io_addr], 0
2532
  .rx_status_loop:
2475
  .rx_status_loop:
Line 2533... Line 2476...
2533
; examine RxStatus
2476
; examine RxStatus
Line 2541... Line 2484...
2541
 
2484
 
2542
        test    ah, 0x40
2485
        test    ah, 0x40
Line 2543... Line 2486...
2543
        jz      .check_length
2486
        jz      .check_length
2544
 
2487
 
2545
; discard the top frame received advancing the next one
2488
; discard the top frame received advancing the next one
2546
        set_io  REG_COMMAND
2489
        set_io  [ebx + device.io_addr], REG_COMMAND
2547
        mov     ax, (01000b shl 11)
2490
        mov     ax, (01000b shl 11)
Line 2548... Line 2491...
2548
        out     dx, ax
2491
        out     dx, ax
Line 2554... Line 2497...
2554
        ja      .discard_frame ; frame is too long discard it
2497
        ja      .discard_frame ; frame is too long discard it
Line 2555... Line 2498...
2555
 
2498
 
2556
  .check_dma:
2499
  .check_dma:
2557
        mov     ecx, eax
2500
        mov     ecx, eax
2558
; switch to register window 7
2501
; switch to register window 7
2559
        set_io  0
2502
        set_io  [ebx + device.io_addr], 0
2560
        set_io  REG_COMMAND
2503
        set_io  [ebx + device.io_addr], REG_COMMAND
2561
        mov     ax, SELECT_REGISTER_WINDOW+7
2504
        mov     ax, SELECT_REGISTER_WINDOW+7
2562
        out     dx, ax
2505
        out     dx, ax
2563
; check for master operation in progress
2506
; check for master operation in progress
2564
        set_io  REG_MASTER_STATUS
2507
        set_io  [ebx + device.io_addr], REG_MASTER_STATUS
Line 2565... Line 2508...
2565
        in      ax, dx
2508
        in      ax, dx
2566
 
2509
 
Line 2567... Line 2510...
2567
        test    ah, 0x80
2510
        test    ah, 0x80
2568
        jnz     .finish
2511
        jnz     .finish
2569
 
2512
 
2570
  .read_frame:
2513
  .read_frame:
2571
; program buffer address to read in
2514
; program buffer address to read in
2572
        push    ecx
2515
        push    ecx
2573
        stdcall KernelAlloc, MAX_ETH_FRAME_SIZE
2516
        invoke  KernelAlloc, MAX_ETH_FRAME_SIZE
Line 2574... Line 2517...
2574
        pop     ecx
2517
        pop     ecx
2575
        test    eax, eax
2518
        test    eax, eax
2576
        jz      .finish
2519
        jz      .finish
2577
 
2520
 
2578
        push    .discard_frame
2521
        push    .discard_frame
2579
        push    ecx
2522
        push    ecx
Line 2580... Line 2523...
2580
        push    eax
2523
        push    eax
2581
;        zero_to_dma eax
2524
;        zero_to_dma eax
2582
        set_io  REG_MASTER_ADDRESS
2525
        set_io  [ebx + device.io_addr], REG_MASTER_ADDRESS
2583
        out     dx, eax
2526
        out     dx, eax
Line 2584... Line 2527...
2584
 
2527
 
2585
; program frame length
2528
; program frame length
2586
        set_io  REG_MASTER_LEN
2529
        set_io  [ebx + device.io_addr], REG_MASTER_LEN
2587
        mov     ax, 1560
2530
        mov     ax, 1560
Line 2588... Line 2531...
2588
        out     dx, ax
2531
        out     dx, ax
2589
 
2532
 
2590
; start DMA Up
2533
; start DMA Up
2591
        set_io  REG_COMMAND
2534
        set_io  [ebx + device.io_addr], REG_COMMAND
2592
        mov     ax, (10100b shl 11) ; StartDMAUp
2535
        mov     ax, (10100b shl 11) ; StartDMAUp
2593
        out     dx, ax
2536
        out     dx, ax
Line 2594... Line 2537...
2594
 
2537
 
2595
; check for master operation in progress
2538
; check for master operation in progress
Line 2596... Line 2539...
2596
        set_io  REG_MASTER_STATUS   ; TODO: use timeout and reset after timeout expired
2539
        set_io  [ebx + device.io_addr], REG_MASTER_STATUS   ; TODO: use timeout and reset after timeout expired
2597
  .dma_loop:
2540
  .dma_loop:
2598
        in      ax, dx
2541
        in      ax, dx
2599
        test    ah, 0x80
2542
        test    ah, 0x80
2600
        jnz     .dma_loop
2543
        jnz     .dma_loop
2601
 
2544
 
Line 2602... Line 2545...
2602
; registrate the received packet to kernel
2545
; registrate the received packet to kernel
Line 2617... Line 2560...
2617
        test    ax, DMADone
2560
        test    ax, DMADone
2618
        jz      .noDMA
2561
        jz      .noDMA
Line 2619... Line 2562...
2619
 
2562
 
Line 2620... Line 2563...
2620
        push    ax
2563
        push    ax
2621
 
2564
 
2622
        set_io  0
2565
        set_io  [ebx + device.io_addr], 0
2623
        set_io  12
2566
        set_io  [ebx + device.io_addr], 12
2624
        in      ax, dx
2567
        in      ax, dx
Line 2625... Line 2568...
2625
        test    ax, 0x1000
2568
        test    ax, 0x1000
Line 2639... Line 2582...
2639
.noDMA:
2582
.noDMA:
Line 2640... Line 2583...
2640
 
2583
 
2641
 
2584
 
2642
 
2585
 
2643
.ACK:
2586
.ACK:
2644
        set_io  0
2587
        set_io  [ebx + device.io_addr], 0
Line 2645... Line 2588...
2645
        set_io  REG_COMMAND
2588
        set_io  [ebx + device.io_addr], REG_COMMAND
Line 2666... Line 2609...
2666
 
2609
 
Line 2667... Line 2610...
2667
        DEBUGF  1,"INT\n"
2610
        DEBUGF  1,"INT\n"
Line 2668... Line 2611...
2668
 
2611
 
2669
; find pointer of device wich made IRQ occur
2612
; find pointer of device wich made IRQ occur
2670
 
2613
 
2671
        mov     ecx, [BOOMERANG_DEVICES]
2614
        mov     ecx, [boomerang_devices]
2672
        test    ecx, ecx
2615
        test    ecx, ecx
2673
        jz      .nothing
2616
        jz      .nothing
Line 2674... Line 2617...
2674
        mov     esi, BOOMERANG_LIST
2617
        mov     esi, boomerang_list
2675
  .nextdevice:
2618
  .nextdevice:
2676
        mov     ebx, [esi]
2619
        mov     ebx, [esi]
2677
 
2620
 
2678
        set_io  0
2621
        set_io  [ebx + device.io_addr], 0
2679
        set_io  REG_INT_STATUS
2622
        set_io  [ebx + device.io_addr], REG_INT_STATUS
2680
        in      ax, dx
2623
        in      ax, dx
2681
        test    ax, ax
2624
        test    ax, S_5_INTS
2682
        jnz     .got_it
2625
        jnz     .got_it
Line 2690... Line 2633...
2690
 
2633
 
Line 2691... Line 2634...
2691
        ret
2634
        ret
Line 2692... Line 2635...
2692
 
2635
 
2693
  .got_it:
2636
  .got_it:
Line 2694... Line 2637...
2694
 
2637
 
Line 2695... Line 2638...
2695
        DEBUGF  1,"Device: %x Status: %x ", ebx, ax
2638
        DEBUGF  1,"Device: %x Status: %x\n", ebx, ax
2696
        push    ax
2639
        push    ax
2697
 
2640
 
Line 2698... Line 2641...
2698
; disable all INTS
2641
; disable all INTS
2699
 
2642
 
Line 2709... Line 2652...
2709
 
2652
 
2710
  .receive:
2653
  .receive:
Line 2711... Line 2654...
2711
        DEBUGF  1,"UpComplete\n"
2654
        DEBUGF  1,"UpComplete\n"
2712
 
2655
 
2713
; check if packet is uploaded
2656
; check if packet is uploaded
2714
        mov     esi, [device.curr_upd]
2657
        mov     esi, [ebx + device.curr_rx]
2715
        test    byte [esi+upd.pkt_status+1], 0x80 ; upPktComplete
2658
        test    byte [esi+rx_desc.pkt_status+1], 0x80 ; upPktComplete
2716
        jz      .finish
2659
        jz      .finish
2717
        DEBUGF  1, "Current upd: %x\n", esi
2660
        DEBUGF  1, "Current RX desc: %x\n", esi
2718
; packet is uploaded check for any error
2661
; packet is uploaded check for any error
2719
  .check_error:
2662
  .check_error:
2720
        test    byte [esi+upd.pkt_status+1], 0x40 ; upError
2663
        test    byte [esi + rx_desc.pkt_status+1], 0x40 ; upError
2721
        jz      .copy_packet_length
2664
        jz      .copy_packet_length
2722
        DEBUGF  1,"Error in packet\n"
2665
        DEBUGF  1,"Error in packet\n"
2723
        and     [esi+upd.pkt_status], 0           ; mark packet as read
2666
        and     [esi + rx_desc.pkt_status], 0           ; mark packet as read
2724
        jmp     .finish
2667
        jmp     .finish
2725
  .copy_packet_length:
2668
  .copy_packet_length:
Line 2726... Line 2669...
2726
        mov     ecx, [esi+upd.pkt_status]
2669
        mov     ecx, [esi + rx_desc.pkt_status]
2727
        and     ecx, 0x1fff
2670
        and     ecx, 0x1fff
2728
 
2671
 
2729
;        cmp     ecx, MAX_ETH_PKT_SIZE
2672
;        cmp     ecx, MAX_ETH_PKT_SIZE
2730
;        jbe     .copy_packet
2673
;        jbe     .copy_packet
Line 2731... Line 2674...
2731
;        and     [esi+upd.pkt_status], 0
2674
;        and     [esi+rx_desc.pkt_status], 0
Line 2732... Line 2675...
2732
;        jmp     .finish
2675
;        jmp     .finish
2733
;  .copy_packet:
2676
;  .copy_packet:
2734
 
2677
 
Line 2735... Line 2678...
2735
        DEBUGF  1, "Received %u bytes in buffer %x\n", ecx, [esi+upd.realaddr]:8
2678
        DEBUGF  1, "Received %u bytes in buffer %x\n", ecx, [esi + rx_desc.realaddr]:8
2736
 
2679
 
2737
        push    dword .loop ;.finish
2680
        push    dword .loop ;.finish
2738
        push    ecx
2681
        push    ecx
2739
        push    [esi+upd.realaddr]
2682
        push    [esi + rx_desc.realaddr]
2740
 
2683
 
2741
; update statistics
2684
; update statistics
2742
        inc     [device.packets_rx]
2685
        inc     [ebx + device.packets_rx]
2743
        add     dword [device.bytes_rx], ecx
2686
        add     dword [ebx + device.bytes_rx], ecx
2744
        adc     dword [device.bytes_rx + 4], 0
2687
        adc     dword [ebx + device.bytes_rx + 4], 0
2745
 
2688
 
2746
; update UPD (Alloc new buffer for next packet)
2689
; update rx descriptor (Alloc new buffer for next packet)
2747
        stdcall KernelAlloc, MAX_ETH_FRAME_SIZE
2690
        invoke  KernelAlloc, MAX_ETH_FRAME_SIZE
2748
        mov     [esi + upd.realaddr], eax
2691
        mov     [esi + rx_desc.realaddr], eax
2749
        GetRealAddr
2692
        invoke  GetPhysAddr
2750
        mov     [esi + upd.frag_addr], eax
2693
        mov     [esi + rx_desc.frag_addr], eax
2751
        and     [esi + upd.pkt_status], 0
2694
        and     [esi + rx_desc.pkt_status], 0
2752
        mov     [esi + upd.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31)
2695
        mov     [esi + rx_desc.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31)
2753
 
2696
 
2754
; Update UPD pointer
2697
; Update rx descriptor pointer
2755
        add     esi, upd.size
2698
        add     esi, sizeof.rx_desc
2756
        lea     ecx, [device.upd_buffer+(NUM_RX_DESC)*upd.size]
2699
        lea     ecx, [ebx + device.rx_desc_buffer+(NUM_RX_DESC)*sizeof.rx_desc]
Line 2757... Line 2700...
2757
        cmp     esi, ecx
2700
        cmp     esi, ecx
2758
        jb      @f
2701
        jb      @f
Line 2759... Line 2702...
2759
        lea     esi, [device.upd_buffer]
2702
        lea     esi, [ebx + device.rx_desc_buffer]
2760
       @@:
2703
       @@:
Line 2761... Line 2704...
2761
        mov     [device.curr_upd], esi
2704
        mov     [ebx + device.curr_rx], esi
2762
        DEBUGF  1, "Next upd: %x\n", esi
2705
        DEBUGF  1, "Next RX desc: %x\n", esi
Line 2763... Line 2706...
2763
 
2706
 
2764
        jmp     Eth_input
2707
        jmp     [Eth_input]
2765
  .loop:
2708
  .loop:
2766
 
2709
 
2767
        mov     ebx, [esp]
2710
        mov     ebx, [esp]
2768
        jmp     .receive
2711
        jmp     .receive
Line 2769... Line 2712...
2769
 
2712
 
2770
  .finish:
2713
  .finish:
2771
        pop     ebx
2714
        pop     ebx
2772
 
2715
 
2773
; check if the NIC is in the upStall state
2716
; check if the NIC is in the upStall state
Line 2774... Line 2717...
2774
        set_io  0
2717
        set_io  [ebx + device.io_addr], 0
Line 2790... Line 2733...
2790
        test    word[esp], DownComplete
2733
        test    word[esp], DownComplete
2791
        jz      .noTX
2734
        jz      .noTX
2792
        DEBUGF  1, "Downcomplete!\n"
2735
        DEBUGF  1, "Downcomplete!\n"
Line 2793... Line 2736...
2793
 
2736
 
2794
        mov     ecx, NUM_TX_DESC
2737
        mov     ecx, NUM_TX_DESC
2795
        lea     esi, [device.dpd_buffer]
2738
        lea     esi, [ebx + device.tx_desc_buffer]
2796
  .txloop:
2739
  .txloop:
2797
        test    [esi+dpd.frame_start_hdr], 1 shl 31
2740
        test    [esi+tx_desc.frame_start_hdr], 1 shl 31
Line 2798... Line 2741...
2798
        jz      .maybenext
2741
        jz      .maybenext
2799
 
2742
 
2800
        and     [esi+dpd.frame_start_hdr], 0
2743
        and     [esi+tx_desc.frame_start_hdr], 0
2801
        push    ecx
2744
        push    ecx
Line 2802... Line 2745...
2802
        stdcall KernelFree, [esi+dpd.realaddr]
2745
        invoke  KernelFree, [esi+tx_desc.realaddr]
2803
        pop     ecx
2746
        pop     ecx
2804
 
2747
 
2805
  .maybenext:
2748
  .maybenext:
Line 2806... Line 2749...
2806
        add     esi, dpd.size
2749
        add     esi, sizeof.tx_desc
2807
        dec     ecx
2750
        dec     ecx
Line 2808... Line 2751...
2808
        jnz     .txloop
2751
        jnz     .txloop
2809
 
2752
 
2810
.noTX:
2753
.noTX:
2811
        pop     ax
2754
        pop     ax
Line 2812... Line 2755...
2812
 
2755
 
2813
        set_io  0
2756
        set_io  [ebx + device.io_addr], 0
2814
        set_io  REG_COMMAND
2757
        set_io  [ebx + device.io_addr], REG_COMMAND
2815
        or      ax, AckIntr
2758
        or      ax, AckIntr
Line 2816... Line 2759...
2816
        out     dx, ax
2759
        out     dx, ax
2817
 
2760
 
2818
        set_io  REG_INT_STATUS
2761
        set_io  [ebx + device.io_addr], REG_INT_STATUS
2819
        in      ax, dx
2762
        in      ax, dx
Line 2820... Line 2763...
2820
        test    ax, S_5_INTS
2763
        test    ax, S_5_INTS
Line 2831... Line 2774...
2831
 
2774
 
-
 
2775
 
-
 
2776
 
-
 
2777
 
-
 
2778
; End of code
-
 
2779
 
-
 
2780
data fixups
2832
 
2781
end data
Line 2833... Line 2782...
2833
 
2782
 
2834
 
2783
include '../peimport.inc'
2835
; End of code
2784
 
2836
align 4                                         ; Place all initialised data here
2785
my_service           db '3C59X',0                    ; max 16 chars include zero
Line 2844... Line 2793...
2844
        dd label
2793
        dd label
2845
forward
2794
forward
2846
        label db string, 0
2795
        label db string, 0
2847
}
2796
}
Line 2848... Line -...
2848
 
-
 
2849
VORTEX_DEVICES       dd 0
-
 
2850
BOOMERANG_DEVICES    dd 0
-
 
2851
version              dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
-
 
2852
my_service           db '3C59X',0                    ; max 16 chars include zero
-
 
2853
 
-
 
2854
 
2797
 
2855
strtbl link_str, \
2798
strtbl link_str, \
2856
        "No valid link type detected", \
2799
        "No valid link type detected", \
2857
        "10BASE-T half duplex", \
2800
        "10BASE-T half duplex", \
2858
        "10BASE-T full-duplex", \
2801
        "10BASE-T full-duplex", \
Line 2946... Line 2889...
2946
dw 0x9210, IS_TORNADO or HAS_NWAY or HAS_HWCKSM                                                                                 ; 3c920B-EMB-WNM Tornado
2889
dw 0x9210, IS_TORNADO or HAS_NWAY or HAS_HWCKSM                                                                                 ; 3c920B-EMB-WNM Tornado
2947
HW_VERSIONS_SIZE = $ - hw_versions
2890
HW_VERSIONS_SIZE = $ - hw_versions
Line 2948... Line 2891...
2948
 
2891
 
Line -... Line 2892...
-
 
2892
include_debug_strings                           ; All data wich FDO uses will be included here
-
 
2893
 
2949
include_debug_strings                           ; All data wich FDO uses will be included here
2894
align 4
2950
 
-
 
2951
section '.data' data readable writable align 16 ; place all uninitialized data place here
2895
vortex_devices          dd 0
2952
 
2896
boomerang_devices       dd 0