Fixed 3c59x driver to work with 3c900b-tpo cards

git-svn-id: svn://kolibrios.org@1521 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2010-07-16 15:37:50 +00:00
parent 28fb09b79d
commit 55e0141343
2 changed files with 250 additions and 208 deletions

View File

@ -357,7 +357,6 @@ virtual at ebx
.has_hwcksm db ? .has_hwcksm db ?
.preamble db ? .preamble db ?
.dn_list_ptr_cleared db ? .dn_list_ptr_cleared db ?
.self_directed_packet rb 20
.size = $ - device .size = $ - device
@ -473,12 +472,7 @@ proc service_proc stdcall, ioctl:dword
cmp ecx, MAX_DEVICES ; First check if the driver can handle one more card cmp ecx, MAX_DEVICES ; First check if the driver can handle one more card
jge .fail jge .fail
push edx allocate_and_clear ebx, device.size, .fail ; Allocate the buffer for device structure
stdcall KernelAlloc, dword device.size ; Allocate the buffer for eth_device structure
pop edx
test eax, eax
jz .fail
mov ebx, eax ; ebx is always used as a pointer to the structure (in driver, but also in kernel code)
; Fill in the direct call addresses into the struct ; Fill in the direct call addresses into the struct
@ -516,30 +510,26 @@ proc service_proc stdcall, ioctl:dword
test word [hw_versions+2+ecx*4], IS_VORTEX test word [hw_versions+2+ecx*4], IS_VORTEX
jz .not_vortex jz .not_vortex
mov eax, [VORTEX_DEVICES] ; Add the device structure to our device list mov eax, [VORTEX_DEVICES] ; Add the device structure to our device list
mov [VORTEX_LIST+4*eax], ebx ; (IRQ handler uses this list to find device) mov [VORTEX_LIST+4*eax], ebx ; (IRQ handler uses this list to find device)
inc [VORTEX_DEVICES] ; inc [VORTEX_DEVICES] ;
.register: .register:
mov [device.type], NET_TYPE_ETH mov [device.type], NET_TYPE_ETH
call NetRegDev call NetRegDev
cmp eax, -1 cmp eax, -1
je .destroy je .destroy
call start call start_device
ret ret
.not_vortex: .not_vortex:
mov eax, [BOOMERANG_DEVICES] ; Add the device structure to our device list mov eax, [BOOMERANG_DEVICES] ; Add the device structure to our device list
mov [BOOMERANG_LIST+4*eax], ebx ; (IRQ handler uses this list to find device) mov [BOOMERANG_LIST+4*eax], ebx ; (IRQ handler uses this list to find device)
inc [BOOMERANG_DEVICES] inc [BOOMERANG_DEVICES]
call .register jmp .register
; If the device was already loaded, find the device number and return it in eax ; If the device was already loaded, find the device number and return it in eax
@ -741,8 +731,8 @@ reset:
call write_mac call write_mac
call rx_reset
call tx_reset ;<<<<<<<<<<<<<<
set_io REG_COMMAND set_io REG_COMMAND
mov ax, SELECT_REGISTER_WINDOW + 1 mov ax, SELECT_REGISTER_WINDOW + 1
@ -768,6 +758,14 @@ reset:
call set_rx_mode call set_rx_mode
call set_active_port call set_active_port
;>>>>>>>>>>
call create_rx_ring
call rx_reset
call tx_reset
;>>>>>>>>>>>>>>>>>>
set_io 0 set_io 0
set_io REG_COMMAND set_io REG_COMMAND
mov ax, RxEnable mov ax, RxEnable
@ -803,7 +801,8 @@ reset:
align 4 align 4
start: start_device:
DEBUGF 1,"Starting the device\n"
set_io 0 set_io 0
set_io REG_COMMAND set_io REG_COMMAND
@ -822,12 +821,13 @@ start:
set_io REG_MEDIA_STATUS set_io REG_MEDIA_STATUS
mov ecx, 20 ; wait for max 2s mov ecx, 20 ; wait for max 2s
.link_detect_loop: .link_detect_loop:
mov esi, 10 mov esi, 100
stdcall Sleep ; 100 ms call Sleep ; 100 ms
in ax, dx in ax, dx
test ah, 1000b ; linkDetect test ah, 1000b ; linkDetect
jnz @f jnz @f
loop .link_detect_loop loop .link_detect_loop
DEBUGF 1,"Link detect timed-out!\n"
@@: @@:
; print link type ; print link type
@ -836,11 +836,12 @@ start:
jz @f jz @f
sub ax, 4 sub ax, 4
@@: @@:
mov esi, [link_str+eax*4] mov esi, [link_str+eax*4]
DEBUGF 1,"Established Link type: %s\n", esi DEBUGF 1,"Established Link type: %s\n", esi
; enable interrupts
set_io 0
set_io REG_COMMAND set_io REG_COMMAND
mov ax, SELECT_REGISTER_WINDOW + 1 mov ax, SELECT_REGISTER_WINDOW + 1
out dx, ax out dx, ax
@ -854,11 +855,6 @@ start:
mov ax, SetIntrEnb + S_5_INTS mov ax, SetIntrEnb + S_5_INTS
out dx, ax out dx, ax
set_io 0
set_io REG_COMMAND
mov ax, SELECT_REGISTER_WINDOW + 1
ret ret
@ -870,6 +866,8 @@ start:
align 4 align 4
set_rx_mode: set_rx_mode:
DEBUGF 1,"Setting RX mode\n"
set_io 0 set_io 0
set_io REG_COMMAND set_io REG_COMMAND
@ -880,7 +878,6 @@ set_rx_mode:
else else
mov ax, SetRxFilter + RxStation + RxBroadcast mov ax, SetRxFilter + RxStation + RxBroadcast
end if end if
out dx, ax out dx, ax
ret ret
@ -905,7 +902,7 @@ set_rx_mode:
align 4 align 4
global_reset: global_reset:
DEBUGF 1,"Global reset: " DEBUGF 1,"Global reset..\n"
; GlobalReset ; GlobalReset
set_io 0 set_io 0
@ -918,13 +915,12 @@ global_reset:
.loop: .loop:
in ax , dx in ax , dx
test ah , 10000b ; check CmdInProgress test ah , 10000b ; check CmdInProgress
; jz .finish
loopz .loop loopz .loop
;.finish:
; DEBUGF 1,"Waiting for nic to boot..\n" DEBUGF 1,"Waiting for nic to boot..\n"
; wait for 2 seconds for NIC to boot ; wait for 2 seconds for NIC to boot
mov esi, 200 mov esi, 2000
stdcall Sleep ; 2 seconds call Sleep ; 2 seconds
DEBUGF 1,"Ok!\n" DEBUGF 1,"Ok!\n"
@ -990,9 +986,24 @@ rx_reset:
.loop: .loop:
in ax, dx in ax, dx
test ah, 10000b ; check CmdInProgress test ah, 10000b ; check CmdInProgress
jz .done
dec ecx dec ecx
jnz .loop jnz .loop
.done:
lea eax, [device.upd_buffer]
mov [device.curr_upd], eax
GetRealAddr
set_io 0
set_io REG_UP_LIST_PTR
out dx, eax
.rx_enable:
ret
align 4
create_rx_ring:
; create upd ring ; create upd ring
lea eax, [device.upd_buffer] lea eax, [device.upd_buffer]
GetRealAddr GetRealAddr
@ -1024,19 +1035,10 @@ rx_reset:
dec ecx dec ecx
jnz .upd_loop jnz .upd_loop
lea eax, [device.upd_buffer]
mov [device.curr_upd], eax
GetRealAddr
set_io 0
set_io REG_UP_LIST_PTR
out dx, eax
.rx_enable:
ret ret
;--------------------------------------------------------------------------- ;---------------------------------------------------------------------------
; Function ; Function
; try_link_detect ; try_link_detect
@ -1058,8 +1060,16 @@ try_link_detect:
DEBUGF 1,"trying to detect link\n" DEBUGF 1,"trying to detect link\n"
; create self-directed packet ; create self-directed packet
stdcall KernelAlloc, 20 ; create a buffer for the self-directed packet
test eax, eax
jz .fail
pushd 20 ; Packet parameters for device.transmit
push eax ;
mov edi, eax
lea esi, [device.mac] lea esi, [device.mac]
lea edi, [device.self_directed_packet]
movsw movsw
movsd movsd
sub esi, 6 sub esi, 6
@ -1069,9 +1079,6 @@ try_link_detect:
stosw stosw
; download self-directed packet ; download self-directed packet
push 20
lea eax, [device.self_directed_packet]
push eax
call [device.transmit] call [device.transmit]
; switch to register window 4 ; switch to register window 4
@ -1098,6 +1105,7 @@ try_link_detect:
jmp .finish jmp .finish
.link_detected: .link_detected:
DEBUGF 1,"link detected!\n"
setb al setb al
.finish: .finish:
@ -1107,6 +1115,9 @@ try_link_detect:
@@: @@:
ret ret
.fail:
ret
;*************************************************************************** ;***************************************************************************
@ -1116,7 +1127,7 @@ try_link_detect:
; try_phy checks the auto-negotiation function ; try_phy checks the auto-negotiation function
; in the PHY at PHY index. It can also be extended to ; in the PHY at PHY index. It can also be extended to
; include link detection for non-IEEE 802.3u ; include link detection for non-IEEE 802.3u
; auto-negotiation devices, for instance the BCM5000. ; auto-negotiation devices, for instance the BCM5000. ; TODO: BCM5000
; Parameters ; Parameters
; ah - PHY index ; ah - PHY index
; ebx - device stucture ; ebx - device stucture
@ -1131,7 +1142,8 @@ try_link_detect:
align 4 align 4
try_phy: try_phy:
DEBUGF 1,"trying phy\n" DEBUGF 1,"PHY=%u\n", ah
DEBUGF 1,"Detecting if device is auto-negotiation capable\n"
mov al, REG_MII_BMCR mov al, REG_MII_BMCR
push eax push eax
@ -1142,31 +1154,35 @@ try_phy:
call mdio_write ; returns with window #4 call mdio_write ; returns with window #4
; wait for reset to complete ; wait for reset to complete
mov esi, 200 mov esi, 2000
stdcall Sleep ; 2s stdcall Sleep ; 2s
mov eax, [esp] mov eax, [esp]
call mdio_read ; returns with window #4 call mdio_read ; returns with window #4
test ah , 0x80 test ah , 0x80
jnz .fail_finish jnz .fail1
mov eax, [esp] mov eax, [esp]
; wait for a while after reset ; wait for a while after reset
mov esi, 2 mov esi, 20
stdcall Sleep ; 20ms stdcall Sleep ; 20ms
mov eax, [esp] mov eax, [esp]
mov al , REG_MII_BMSR mov al , REG_MII_BMSR
call mdio_read ; returns with window #4 call mdio_read ; returns with window #4
test al , 1 ; extended capability supported? test al , 1 ; extended capability supported?
jz .no_ext_cap jz .fail2
; auto-neg capable? ; auto-neg capable?
test al , 1000b test al , 1000b
jz .fail_finish ; not auto-negotiation capable jz .fail2 ; not auto-negotiation capable
DEBUGF 1,"Device is auto-negotiation capable\n"
; auto-neg complete? ; auto-neg complete?
test al , 100000b test al , 100000b
jnz .auto_neg_ok jnz .auto_neg_ok
DEBUGF 1,"Restarting auto-negotiation\n"
; restart auto-negotiation ; restart auto-negotiation
mov eax, [esp] mov eax, [esp]
mov al , REG_MII_ANAR mov al , REG_MII_ANAR
@ -1182,16 +1198,18 @@ try_phy:
or bh , 10010b ; restart auto-negotiation or bh , 10010b ; restart auto-negotiation
mov eax, [esp] mov eax, [esp]
call mdio_write ; returns with window #4 call mdio_write ; returns with window #4
mov esi, 400 mov esi, 4000
stdcall Sleep ; 4 seconds stdcall Sleep ; 4 seconds
mov eax, [esp] mov eax, [esp]
mov al , REG_MII_BMSR mov al , REG_MII_BMSR
call mdio_read ; returns with window #4 call mdio_read ; returns with window #4
test al , 100000b ; auto-neg complete? test al , 100000b ; auto-neg complete?
jnz .auto_neg_ok jnz .auto_neg_ok
jmp .fail_finish jmp .fail3
.auto_neg_ok: .auto_neg_ok:
DEBUGF 1,"Auto-negotiation complete\n"
; compare advertisement and link partner ability registers ; compare advertisement and link partner ability registers
mov eax, [esp] mov eax, [esp]
mov al , REG_MII_ANAR mov al , REG_MII_ANAR
@ -1221,13 +1239,26 @@ try_phy:
jz .half_duplex jz .half_duplex
or ax , 0x120 ; set full duplex and flow control or ax , 0x120 ; set full duplex and flow control
.half_duplex: .half_duplex:
DEBUGF 1,"Using half-duplex\n"
out dx , ax out dx , ax
mov al , 1 mov al , 1
ret ret
.no_ext_cap:
; not yet implemented BCM5000
.fail_finish: .fail1:
DEBUGF 1,"reset failed!\n"
pop eax
xor al, al
ret
.fail2:
DEBUGF 1,"This device is not auto-negotiation capable!\n"
pop eax
xor al, al
ret
.fail3:
DEBUGF 1,"auto-negotiation reset failed!\n"
pop eax pop eax
xor al, al xor al, al
ret ret
@ -1255,7 +1286,7 @@ try_phy:
align 4 align 4
try_mii: try_mii:
DEBUGF 1,"trying mii\n" DEBUGF 1,"trying to find MII PHY\n"
; switch to register window 3 ; switch to register window 3
set_io 0 set_io 0
@ -1267,37 +1298,46 @@ try_mii:
and eax, (1111b shl 20) and eax, (1111b shl 20)
cmp eax, (1000b shl 20) ; is auto-negotiation set? cmp eax, (1000b shl 20) ; is auto-negotiation set?
jne .mii_device jne .mii_device
; auto-negotiation is set
DEBUGF 1,"auto-negotiation is set\n"
; switch to register window 4 ; switch to register window 4
set_io REG_COMMAND set_io REG_COMMAND
mov ax , SELECT_REGISTER_WINDOW+4 mov ax , SELECT_REGISTER_WINDOW+4
out dx , ax out dx , ax
; PHY==24 is the on-chip auto-negotiation logic ; PHY==24 is the on-chip auto-negotiation logic
; it supports only 10base-T and 100base-TX ; it supports only 10base-T and 100base-TX
mov ah , 24 mov ah , 24
call try_phy call try_phy
test al , al test al , al
jz .fail_finish jz .fail_finish
mov cl , 24 mov cl , 24
jmp .check_preamble jmp .check_preamble
.mii_device: .mii_device:
cmp eax, (0110b shl 20) cmp eax, (0110b shl 20)
jne .fail_finish jne .fail_finish
set_io 0 set_io 0
set_io REG_COMMAND set_io REG_COMMAND
mov ax , SELECT_REGISTER_WINDOW+4 mov ax , SELECT_REGISTER_WINDOW+4
out dx , ax out dx , ax
set_io REG_PHYSICAL_MGMT set_io REG_PHYSICAL_MGMT
in ax , dx in ax , dx
and al , (1 shl BIT_MGMT_DIR) or (1 shl BIT_MGMT_DATA) and al , (1 shl BIT_MGMT_DIR) or (1 shl BIT_MGMT_DATA)
cmp al , (1 shl BIT_MGMT_DATA) cmp al , (1 shl BIT_MGMT_DATA)
je .search_for_phy je .search_for_phy
xor al , al xor al , al
ret ret
.search_for_phy: .search_for_phy:
; search for PHY ; search for PHY
mov cx , 31 mov cx , 31
.search_phy_loop: .search_phy_loop:
DEBUGF 1,"Searching the PHY\n"
cmp cx , 24 cmp cx , 24
je .next_phy je .next_phy
mov ah , cl ; ah = phy mov ah , cl ; ah = phy
@ -1317,23 +1357,28 @@ try_mii:
jnz .check_preamble jnz .check_preamble
.next_phy: .next_phy:
loopw .search_phy_loop loopw .search_phy_loop
.fail_finish: .fail_finish:
xor al, al xor al, al
ret ret
; epilog ; epilog
.check_preamble: .check_preamble:
DEBUGF 1,"Using PHY: %u\nChecking PreAmble\n", cl
push eax ; eax contains the return value of try_phy push eax ; eax contains the return value of try_phy
; check hard coded preamble forcing ; check hard coded preamble forcing
movzx eax, [device.ver_id] movzx eax, [device.ver_id]
test word [eax*4+hw_versions+2], EXTRA_PREAMBLE test word [eax*4+hw_versions+2], EXTRA_PREAMBLE
setnz [device.preamble] ; force preamble setnz [device.preamble] ; force preamble
jnz .finish jnz .finish
; check mii for preamble suppression ; check mii for preamble suppression
mov ah, cl mov ah, cl
mov al, REG_MII_BMSR mov al, REG_MII_BMSR
call mdio_read call mdio_read
test al, 1000000b ; preamble suppression? test al, 1000000b ; preamble suppression?
setz [device.preamble] ; no setz [device.preamble] ; no
.finish: .finish:
pop eax pop eax
ret ret
@ -1384,9 +1429,16 @@ test_packet:
call rx_reset call rx_reset
call tx_reset call tx_reset
; download a self-directed test packet ; create self-directed packet
stdcall KernelAlloc, 20 ; create a buffer for the self-directed packet
test eax, eax
jz .fail
pushd 20 ; Packet parameters for device.transmit
push eax ;
mov edi, eax
lea esi, [device.mac] lea esi, [device.mac]
lea edi, [device.self_directed_packet]
movsw movsw
movsd movsd
sub esi, 6 sub esi, 6
@ -1395,14 +1447,12 @@ test_packet:
mov ax , 0x0608 mov ax , 0x0608
stosw stosw
push 20 ; download self-directed packet
lea eax, [device.self_directed_packet]
push eax
call [device.transmit] call [device.transmit]
; wait for 2s ; wait for 2s
mov esi, 200 mov esi, 2000
stdcall Sleep ; 2s call Sleep
; check if self-directed packet is received ; check if self-directed packet is received
mov eax, [device.packets_rx] mov eax, [device.packets_rx]
@ -1420,6 +1470,7 @@ test_packet:
in ax , dx in ax , dx
and ax , not 0x120 and ax , not 0x120
out dx , ax out dx , ax
.fail:
xor eax, eax xor eax, eax
.finish: .finish:
@ -1468,6 +1519,7 @@ try_loopback:
mov ax, (10b shl 11) ; EnableDcConverter mov ax, (10b shl 11) ; EnableDcConverter
out dx, ax out dx, ax
.complete_loopback: .complete_loopback:
mov cx, 2 ; give a port 3 chances to complete a loopback mov cx, 2 ; give a port 3 chances to complete a loopback
.next_try: .next_try:
push ecx push ecx
@ -1475,10 +1527,12 @@ try_loopback:
pop ecx pop ecx
test eax, eax test eax, eax
loopzw .next_try loopzw .next_try
.finish: .finish:
xchg eax, [esp] xchg eax, [esp]
test al, al test al, al
jz .aui_finish jz .aui_finish
; issue DisableDcConverter command ; issue DisableDcConverter command
set_io 0 set_io 0
set_io REG_COMMAND set_io REG_COMMAND
@ -1509,13 +1563,14 @@ try_loopback:
align 4 align 4
set_active_port: set_active_port:
DEBUGF 1,"Setting active port: " DEBUGF 1,"Trying to find the active port\n"
; switch to register window 3 ; switch to register window 3
set_io 0 set_io 0
set_io REG_COMMAND set_io REG_COMMAND
mov ax, SELECT_REGISTER_WINDOW + 3 mov ax, SELECT_REGISTER_WINDOW + 3
out dx, ax out dx, ax
set_io REG_INTERNAL_CONFIG set_io REG_INTERNAL_CONFIG
in eax, dx in eax, dx
test eax, (1 shl 24) ; check if autoselect enable test eax, (1 shl 24) ; check if autoselect enable
@ -1538,14 +1593,10 @@ set_active_port:
jz .mii_device jz .mii_device
DEBUGF 1,"Using auto negotiation\n" DEBUGF 1,"Using auto negotiation\n"
ret ret
.mii_device:
.mii_device:
; switch to register window 3 ; switch to register window 3
set_io 0 set_io 0
set_io REG_COMMAND
mov ax, SELECT_REGISTER_WINDOW+3
out dx, ax
; check for off-chip mii device ; check for off-chip mii device
set_io REG_MEDIA_OPTIONS set_io REG_MEDIA_OPTIONS
in ax, dx in ax, dx
@ -1561,13 +1612,10 @@ set_active_port:
jz .base_fx jz .base_fx
DEBUGF 1,"Using off-chip mii device\n" DEBUGF 1,"Using off-chip mii device\n"
ret ret
.base_fx:
.base_fx:
; switch to register window 3 ; switch to register window 3
set_io 0 set_io 0
set_io REG_COMMAND
mov ax, SELECT_REGISTER_WINDOW+3
out dx, ax
; check for 100BASE-FX ; check for 100BASE-FX
set_io REG_MEDIA_OPTIONS set_io REG_MEDIA_OPTIONS
in ax, dx ; read media option register in ax, dx ; read media option register
@ -1583,13 +1631,10 @@ set_active_port:
jz .aui_enable jz .aui_enable
DEBUGF 1,"Using 100Base-FX\n" DEBUGF 1,"Using 100Base-FX\n"
ret ret
.aui_enable:
.aui_enable:
; switch to register window 3 ; switch to register window 3
set_io 0 set_io 0
set_io REG_COMMAND
mov ax, SELECT_REGISTER_WINDOW+3
out dx, ax
; check for 10Mbps AUI connector ; check for 10Mbps AUI connector
set_io REG_MEDIA_OPTIONS set_io REG_MEDIA_OPTIONS
in ax, dx ; read media option register in ax, dx ; read media option register
@ -1606,18 +1651,16 @@ set_active_port:
jz .coax_available jz .coax_available
DEBUGF 1,"Using 10Mbps aui\n" DEBUGF 1,"Using 10Mbps aui\n"
ret ret
.coax_available:
.coax_available:
; switch to register window 3 ; switch to register window 3
set_io 0 set_io 0
set_io REG_COMMAND
mov ax, SELECT_REGISTER_WINDOW+3
out dx, ax
; check for coaxial 10BASE-2 port ; check for coaxial 10BASE-2 port
set_io REG_MEDIA_OPTIONS set_io REG_MEDIA_OPTIONS
in ax, dx ; read media option register in ax, dx ; read media option register
test al, 10000b ; check 10BASE-2 test al, 10000b ; check 10BASE-2
jz .set_first_available_media jz .set_first_available_media
set_io REG_INTERNAL_CONFIG set_io REG_INTERNAL_CONFIG
in eax, dx in eax, dx
and eax, not (1111b shl 20) and eax, not (1111b shl 20)
@ -1629,8 +1672,9 @@ set_active_port:
jz .set_first_available_media jz .set_first_available_media
DEBUGF 1,"Using 10BASE-2 port\n" DEBUGF 1,"Using 10BASE-2 port\n"
ret ret
.set_first_available_media:
.set_first_available_media:
DEBUGF 1,"Using the first available media\n"
;*************************************************************************** ;***************************************************************************
; Function ; Function
@ -1638,7 +1682,7 @@ set_active_port:
; Description ; Description
; sets the first available media ; sets the first available media
; Parameters ; Parameters
; ebp - io_addr ; ebx - ptr to device struct
; Return value ; Return value
; al - 0 ; al - 0
; al - 1 ; al - 1
@ -1650,23 +1694,26 @@ set_active_port:
align 4 align 4
set_available_media: set_available_media:
DEBUGF 1,"Using the first available media\n" DEBUGF 1,"Setting the available media\n"
; switch to register window 3 ; switch to register window 3
set_io 0 set_io 0
set_io REG_COMMAND set_io REG_COMMAND
mov ax, SELECT_REGISTER_WINDOW+3 mov ax, SELECT_REGISTER_WINDOW+3
out dx, ax out dx, ax
set_io REG_INTERNAL_CONFIG
in eax, dx
push eax
set_io REG_MEDIA_OPTIONS set_io REG_MEDIA_OPTIONS
in ax, dx in ax, dx
test al, 10b DEBUGF 1,"available media:%x\n", al
mov cl, al
set_io REG_INTERNAL_CONFIG
in eax, dx
and eax, not (1111b shl 20) ; these bits hold the 'transceiver select' value
test cl, 10b ; baseTXAvailable
jz @f jz @f
; baseTXAvailable
pop eax DEBUGF 1,"base TX is available\n"
and eax, not (1111b shl 20)
or eax, (100b shl 20) or eax, (100b shl 20)
if defined FORCE_FD if defined FORCE_FD
mov word [device.mode], (1 shl 8) mov word [device.mode], (1 shl 8)
@ -1675,76 +1722,74 @@ else
end if end if
jmp .set_media jmp .set_media
@@: @@:
test al, 100b
test cl, 100b ; baseFXAvailable
jz @f jz @f
; baseFXAvailable
pop eax DEBUGF 1,"base FX is available\n"
and eax, not (1111b shl 20)
or eax, (101b shl 20) or eax, (101b shl 20)
mov word [device.mode], (1 shl 10) mov word [device.mode], (1 shl 10)
jmp .set_media jmp .set_media
@@: @@:
test al, 1000000b
test cl, 1000000b ; miiDevice
jz @f jz @f
; miiDevice
pop eax DEBUGF 1,"mii-device is available\n"
and eax, not (1111b shl 20)
or eax, (0110b shl 20) or eax, (0110b shl 20)
mov word [device.mode], (1 shl 13) mov word [device.mode], (1 shl 13)
jmp .set_media jmp .set_media
@@: @@:
test al, 1000b
test cl, 1000b ; 10bTAvailable
jz @f jz @f
DEBUGF 1,"10base-T is available\n"
.set_default: .set_default:
; 10bTAvailable
pop eax
and eax, not (1111b shl 20)
if FORCE_FD if FORCE_FD
mov word [device.mode], (1 shl 6) mov word [device.mode], (1 shl 6)
else else
mov word [device.mode], (1 shl 5) mov word [device.mode], (1 shl 5)
end if ; FORCE_FD end if
jmp .set_media jmp .set_media
@@: @@:
test al, 10000b
test cl, 10000b ; coaxAvailable
jz @f jz @f
; coaxAvailable
DEBUGF 1,"coax is available\n"
push eax
set_io REG_COMMAND set_io REG_COMMAND
mov ax, (10b shl 11) ; EnableDcConverter mov ax, (10b shl 11) ; EnableDcConverter
out dx, ax out dx, ax
pop eax pop eax
and eax, not (1111b shl 20)
or eax, (11b shl 20) or eax, (11b shl 20)
mov word [device.mode], (1 shl 12) mov word [device.mode], (1 shl 12)
jmp .set_media jmp .set_media
@@: @@:
test al, 10000b
jz .set_default
; auiAvailable
pop eax
and eax, not (1111b shl 20)
or eax, (1 shl 20)
test cl, 10000b ; auiAvailable
jz .set_default
DEBUGF 1,"AUI is available\n"
or eax, (1 shl 20)
mov word [device.mode], (1 shl 11) mov word [device.mode], (1 shl 11)
.set_media: .set_media:
set_io 0
set_io REG_INTERNAL_CONFIG set_io REG_INTERNAL_CONFIG
out dx, eax out dx, eax
if FORCE_FD if FORCE_FD
; set fullDuplexEnable in MacControl register DEBUGF 1,"Forcing full duplex\n"
set_io REG_MAC_CONTROL set_io REG_MAC_CONTROL
in ax, dx in ax, dx
or ax, 0x120 or ax, 0x120
out dx, ax out dx, ax
end if ; FORCE_FD end if
mov al, 1
mov al, 1
ret ret
@ -1771,15 +1816,11 @@ wake_up:
test al, 10000b ; is there "new capabilities" linked list? test al, 10000b ; is there "new capabilities" linked list?
jz .device_awake jz .device_awake
DEBUGF 1,"1 "
; search for power management register ; search for power management register
stdcall PciRead16, ecx, edx, PCI_REG_CAP_PTR stdcall PciRead16, ecx, edx, PCI_REG_CAP_PTR
cmp al, 0x3f cmp al, 0x3f
jbe .device_awake jbe .device_awake
DEBUGF 1,"2 "
; traverse the list ; traverse the list
movzx esi, al movzx esi, al
.pm_loop: .pm_loop:
@ -1797,16 +1838,14 @@ wake_up:
; waku up the device if necessary ; waku up the device if necessary
.set_pm_state: .set_pm_state:
DEBUGF 1,"3 "
add esi, PCI_REG_PM_CTRL add esi, PCI_REG_PM_CTRL
stdcall PciRead32, ecx, edx, esi stdcall PciRead32, ecx, edx, esi
test al, 3 test al, 3
jz .device_awake jz .device_awake
and al, not 11b ; set state to D0 and al, not 11b ; set state to D0
stdcall PciWrite32, ecx, edx, esi, eax stdcall PciWrite32, ecx, edx, esi, eax
.device_awake:
.device_awake:
DEBUGF 1,"Device is awake\n" DEBUGF 1,"Device is awake\n"
ret ret
@ -1895,6 +1934,8 @@ wake_up:
; out dx, ax ; out dx, ax
;.finish: ;.finish:
; ret ; ret
;*************************************************************************** ;***************************************************************************
; Function ; Function
; read_eeprom ; read_eeprom
@ -1906,14 +1947,14 @@ wake_up:
; Return value: ; Return value:
; ax - word read ; ax - word read
; Destroyed registers ; Destroyed registers
; ax, ebx, edx, ebp ; ax, ebx, edx
; ;
;*************************************************************************** ;***************************************************************************
align 4 align 4
read_eeprom: read_eeprom:
DEBUGF 1,"Reading from eeprom:\n" DEBUGF 1,"Reading from eeprom.. "
push eax push eax
; switch to register window 0 ; switch to register window 0
@ -2011,7 +2052,7 @@ mdio_sync:
align 4 align 4
mdio_read: mdio_read:
DEBUGF 1,"reading MII registers\n" DEBUGF 1,"Reading MII registers\n"
push eax push eax
call mdio_sync ; returns with window #4 call mdio_sync ; returns with window #4
@ -2099,12 +2140,13 @@ mdio_write:
mov ax, si mov ax, si
mov esi, eax mov esi, eax
mov ecx, 31 mov ecx, 31
.cmd_loop: .cmd_loop:
mov ax, (1 shl BIT_MGMT_DIR) ; write mii mov ax, (1 shl BIT_MGMT_DIR) ; write mii
bt esi, ecx bt esi, ecx
jnc .zero_bit jnc @f
or al, (1 shl BIT_MGMT_DATA) or al, (1 shl BIT_MGMT_DATA)
.zero_bit: @@:
out dx, ax out dx, ax
push eax push eax
in ax, dx ; delay in ax, dx ; delay
@ -2139,6 +2181,7 @@ check_tx_status:
set_io 0 set_io 0
set_io REG_TX_STATUS set_io REG_TX_STATUS
mov ecx, 31 ; max number of queue entries mov ecx, 31 ; max number of queue entries
.tx_status_loop: .tx_status_loop:
in al, dx in al, dx
test al, al test al, al
@ -2150,6 +2193,7 @@ check_tx_status:
xor al, al xor al, al
out dx, al out dx, al
loop .tx_status_loop loop .tx_status_loop
.finish: .finish:
ret ret
@ -2357,9 +2401,8 @@ boomerang_transmit:
;--------------------------------- ;---------------------------------
; Write MAC ; Write MAC
align 4 align 4
write_mac: ; Tested - ok write_mac:
DEBUGF 1,"Writing mac\n" DEBUGF 1,"Writing mac\n"
@ -2381,14 +2424,12 @@ write_mac: ; Tested - ok
inc dx inc dx
outsw outsw
;---------------------------- ;----------------------------
; Read MAC ; Read MAC
align 4 align 4
read_mac: ; Tested - ok read_mac:
set_io 0 set_io 0
set_io REG_COMMAND set_io REG_COMMAND
@ -2416,7 +2457,6 @@ read_mac: ; Tested - ok
;------------------------------------ ;------------------------------------
; Read MAC from eeprom ; Read MAC from eeprom
align 4 align 4
read_mac_eeprom: ; Tested - ok read_mac_eeprom: ; Tested - ok
@ -2431,7 +2471,6 @@ read_mac_eeprom: ; Tested - ok
pop ecx pop ecx
xchg ah, al ; htons xchg ah, al ; htons
mov word [device.mac+ecx*2-2], ax mov word [device.mac+ecx*2-2], ax
loop .mac_loop loop .mac_loop
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 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
@ -2554,8 +2593,6 @@ int_vortex:
; check for master operation in progress ; check for master operation in progress
set_io REG_MASTER_STATUS ; TODO: use timeout and reset after timeout expired set_io REG_MASTER_STATUS ; TODO: use timeout and reset after timeout expired
.dma_loop: .dma_loop:
xor esi, esi
stdcall Sleep
in ax, dx in ax, dx
test ah, 0x80 test ah, 0x80
jnz .dma_loop jnz .dma_loop

View File

@ -54,11 +54,14 @@ macro set_io addr {
macro allocate_and_clear dest, size, err { macro allocate_and_clear dest, size, err {
; We need to allocate at least 8 pages, if we want a continuous memory in ram ; We need to allocate at least 8 pages, if we want a continuous memory in ram
push edx
if (size < 8*4096) & (size > 4096) if (size < 8*4096) & (size > 4096)
stdcall KernelAlloc, 8*4096 stdcall KernelAlloc, 8*4096
else else
stdcall KernelAlloc, size stdcall KernelAlloc, size
end if end if
pop edx
test eax, eax test eax, eax
jz err jz err
mov dest, eax ; Save the address to it into the device struct mov dest, eax ; Save the address to it into the device struct
@ -68,7 +71,9 @@ macro allocate_and_clear dest, size, err {
if (size < 8*4096) & (size > 4096) if (size < 8*4096) & (size > 4096)
add eax, (size/4096+1)*4096 add eax, (size/4096+1)*4096
mov ecx, 8-(size/4096+1) mov ecx, 8-(size/4096+1)
push edx
call ReleasePages call ReleasePages
pop edx
end if end if
; Clear the allocated buffer ; Clear the allocated buffer