Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1520 → Rev 1521

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