forked from KolibriOS/kolibrios
* fixes in FDO for drivers from FDO for the kernel
* fixes in PCNet driver (works in VirtualBox, still problems in VMWare) git-svn-id: svn://kolibrios.org@1201 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
83387bfc23
commit
bbdad4119d
@ -199,7 +199,6 @@ macro DEBUGH_N _sign,_num,_hex {
|
|||||||
if ~_hex eq ax
|
if ~_hex eq ax
|
||||||
movzx eax,_hex
|
movzx eax,_hex
|
||||||
end if
|
end if
|
||||||
shl eax,16
|
|
||||||
if (_num eq)
|
if (_num eq)
|
||||||
mov edx,4
|
mov edx,4
|
||||||
end if
|
end if
|
||||||
@ -207,7 +206,6 @@ macro DEBUGH_N _sign,_num,_hex {
|
|||||||
if ~_hex eq al
|
if ~_hex eq al
|
||||||
movzx eax,_hex
|
movzx eax,_hex
|
||||||
end if
|
end if
|
||||||
shl eax,24
|
|
||||||
if (_num eq)
|
if (_num eq)
|
||||||
mov edx,2
|
mov edx,2
|
||||||
end if
|
end if
|
||||||
|
@ -75,11 +75,17 @@ struc ETH_DEVICE {
|
|||||||
.pci_bus db ?
|
.pci_bus db ?
|
||||||
.pci_dev db ?
|
.pci_dev db ?
|
||||||
|
|
||||||
|
; The following fields up to .tx_ring_phys inclusive form
|
||||||
|
; initialization block for hardware; do not modify
|
||||||
|
align 4 ; initialization block must be dword-aligned
|
||||||
.private:
|
.private:
|
||||||
.mode_ dw ?
|
.mode_ dw ?
|
||||||
.tlen_rlen dw ?
|
.tlen_rlen dw ?
|
||||||
|
.phys_addr dp ?
|
||||||
.reserved dw ?
|
.reserved dw ?
|
||||||
.filter dq ?
|
.filter dq ?
|
||||||
|
.rx_ring_phys dd ?
|
||||||
|
.tx_ring_phys dd ?
|
||||||
.rx_ring dd ?
|
.rx_ring dd ?
|
||||||
.tx_ring dd ?
|
.tx_ring dd ?
|
||||||
.cur_rx db ?
|
.cur_rx db ?
|
||||||
@ -116,7 +122,8 @@ struc buf_head {
|
|||||||
.base dd ?
|
.base dd ?
|
||||||
.length dw ?
|
.length dw ?
|
||||||
.status dw ?
|
.status dw ?
|
||||||
.misc dd ?
|
.msg_length dw ?
|
||||||
|
.misc dw ?
|
||||||
.reserved dd ?
|
.reserved dd ?
|
||||||
|
|
||||||
.size:
|
.size:
|
||||||
@ -191,12 +198,12 @@ end virtual
|
|||||||
|
|
||||||
PCNET_DMA_MASK equ 0xffffffff
|
PCNET_DMA_MASK equ 0xffffffff
|
||||||
|
|
||||||
PCNET_LOG_TX_BUFFERS equ 1
|
PCNET_LOG_TX_BUFFERS equ 2
|
||||||
PCNET_LOG_RX_BUFFERS equ 2
|
PCNET_LOG_RX_BUFFERS equ 2
|
||||||
|
|
||||||
PCNET_TX_RING_SIZE equ 4
|
PCNET_TX_RING_SIZE equ 4
|
||||||
PCNET_TX_RING_MOD_MASK equ (PCNET_TX_RING_SIZE-1)
|
PCNET_TX_RING_MOD_MASK equ (PCNET_TX_RING_SIZE-1)
|
||||||
PCNET_TX_RING_LEN_BITS equ 0
|
PCNET_TX_RING_LEN_BITS equ (PCNET_LOG_TX_BUFFERS shl 12)
|
||||||
|
|
||||||
PCNET_RX_RING_SIZE equ 4
|
PCNET_RX_RING_SIZE equ 4
|
||||||
PCNET_RX_RING_MOD_MASK equ (PCNET_RX_RING_SIZE-1)
|
PCNET_RX_RING_MOD_MASK equ (PCNET_RX_RING_SIZE-1)
|
||||||
@ -603,6 +610,8 @@ proc service_proc stdcall, ioctl:dword
|
|||||||
test eax, eax
|
test eax, eax
|
||||||
jz .err
|
jz .err
|
||||||
mov dword [ebx + device.rx_ring], eax
|
mov dword [ebx + device.rx_ring], eax
|
||||||
|
call GetPgAddr
|
||||||
|
mov dword [ebx + device.rx_ring_phys], eax
|
||||||
|
|
||||||
; Allocate the TX ring
|
; Allocate the TX ring
|
||||||
|
|
||||||
@ -610,6 +619,8 @@ proc service_proc stdcall, ioctl:dword
|
|||||||
test eax, eax
|
test eax, eax
|
||||||
jz .err
|
jz .err
|
||||||
mov dword [ebx + device.tx_ring], eax
|
mov dword [ebx + device.tx_ring], eax
|
||||||
|
call GetPgAddr
|
||||||
|
mov dword [ebx + device.tx_ring_phys], eax
|
||||||
|
|
||||||
; fill in some of the structure variables
|
; fill in some of the structure variables
|
||||||
|
|
||||||
@ -630,24 +641,26 @@ proc service_proc stdcall, ioctl:dword
|
|||||||
|
|
||||||
mov edi, [ebx + device.tx_ring]
|
mov edi, [ebx + device.tx_ring]
|
||||||
mov ecx, PCNET_TX_RING_SIZE
|
mov ecx, PCNET_TX_RING_SIZE
|
||||||
|
mov eax, [ebx + device.tx_buffer]
|
||||||
|
call GetPgAddr
|
||||||
.tx_init:
|
.tx_init:
|
||||||
mov [edi + buf_head.base], 0
|
mov [edi + buf_head.base], eax
|
||||||
mov [edi + buf_head.status], 0
|
add eax, PCNET_PKT_BUF_SZ
|
||||||
add edi, buf_head.size
|
add edi, buf_head.size
|
||||||
loop .tx_init
|
loop .tx_init
|
||||||
|
|
||||||
mov [ebx + device.tlen_rlen],(PCNET_TX_RING_LEN_BITS or PCNET_RX_RING_LEN_BITS)
|
mov [ebx + device.tlen_rlen],(PCNET_TX_RING_LEN_BITS or PCNET_RX_RING_LEN_BITS)
|
||||||
|
|
||||||
; Ok, the eth_device structure is ready, let's probe the device
|
; Ok, the eth_device structure is ready, let's probe the device
|
||||||
|
; Because initialization fires IRQ, IRQ handler must be aware of this device
|
||||||
call probe ; this function will output in eax
|
|
||||||
test eax, eax
|
|
||||||
jnz .err ; If an error occured, exit
|
|
||||||
|
|
||||||
mov eax, [PCNET_DEV] ; Add the device structure to our device list
|
mov eax, [PCNET_DEV] ; Add the device structure to our device list
|
||||||
mov [PCNET_LIST+4*eax], ebx ; (IRQ handler uses this list to find device)
|
mov [PCNET_LIST+4*eax], ebx ; (IRQ handler uses this list to find device)
|
||||||
inc [PCNET_DEV] ;
|
inc [PCNET_DEV] ;
|
||||||
|
|
||||||
|
call probe ; this function will output in eax
|
||||||
|
test eax, eax
|
||||||
|
jnz .destroy ; If an error occured, exit
|
||||||
|
|
||||||
call EthRegDev
|
call EthRegDev
|
||||||
cmp eax, -1
|
cmp eax, -1
|
||||||
je .destroy
|
je .destroy
|
||||||
@ -670,6 +683,7 @@ proc service_proc stdcall, ioctl:dword
|
|||||||
.destroy:
|
.destroy:
|
||||||
; todo: reset device into virgin state
|
; todo: reset device into virgin state
|
||||||
|
|
||||||
|
dec [PCNET_DEV]
|
||||||
.err:
|
.err:
|
||||||
DEBUGF 1,"Error, removing all data !\n"
|
DEBUGF 1,"Error, removing all data !\n"
|
||||||
stdcall KernelFree, dword [ebx+device.rx_buffer]
|
stdcall KernelFree, dword [ebx+device.rx_buffer]
|
||||||
@ -941,7 +955,8 @@ if 0
|
|||||||
; ------------------------------------------------
|
; ------------------------------------------------
|
||||||
end if
|
end if
|
||||||
|
|
||||||
stdcall Sleep, 1
|
; mov esi, 1
|
||||||
|
; call Sleep
|
||||||
|
|
||||||
|
|
||||||
reset:
|
reset:
|
||||||
@ -1053,6 +1068,12 @@ reset:
|
|||||||
mov dword [ebx + device.filter], -1
|
mov dword [ebx + device.filter], -1
|
||||||
mov dword [ebx + device.filter+4], -1
|
mov dword [ebx + device.filter+4], -1
|
||||||
|
|
||||||
|
call read_mac
|
||||||
|
|
||||||
|
lea esi, [ebx + device.mac]
|
||||||
|
lea edi, [ebx + device.phys_addr]
|
||||||
|
movsd
|
||||||
|
movsw
|
||||||
|
|
||||||
lea eax, [ebx + device.private]
|
lea eax, [ebx + device.private]
|
||||||
mov ecx, eax
|
mov ecx, eax
|
||||||
@ -1102,8 +1123,6 @@ reset:
|
|||||||
xor ecx, ecx
|
xor ecx, ecx
|
||||||
call [ebx + device.access_read_csr]
|
call [ebx + device.access_read_csr]
|
||||||
|
|
||||||
call read_mac
|
|
||||||
|
|
||||||
xor ecx, ecx
|
xor ecx, ecx
|
||||||
mov eax, PCNET_CSR_INTEN or PCNET_CSR_START
|
mov eax, PCNET_CSR_INTEN or PCNET_CSR_START
|
||||||
call [ebx + device.access_write_csr]
|
call [ebx + device.access_write_csr]
|
||||||
@ -1140,30 +1159,31 @@ transmit:
|
|||||||
jl .finish ; packet is too short
|
jl .finish ; packet is too short
|
||||||
|
|
||||||
; check descriptor
|
; check descriptor
|
||||||
DEBUGF 1,"Checking descriptor, "
|
|
||||||
movzx eax, [ebx + device.cur_tx]
|
movzx eax, [ebx + device.cur_tx]
|
||||||
mov edx, buf_head.size ;;PCNET_PKT_BUF_SZ
|
imul edi, eax, PCNET_PKT_BUF_SZ
|
||||||
mul dx
|
shl eax, 4
|
||||||
mov edi, [ebx + device.tx_buffer]
|
add edi, [ebx + device.tx_buffer]
|
||||||
add edi, eax
|
add eax, [ebx + device.tx_ring]
|
||||||
|
test byte [eax + buf_head.status + 1], 80h
|
||||||
mov edx, [ebx + device.io_addr]
|
jnz .nospace
|
||||||
|
; descriptor is free, copy data
|
||||||
|
mov esi, [esp]
|
||||||
mov ecx, [esp+4]
|
mov ecx, [esp+4]
|
||||||
neg cx ;;;;
|
mov edx, ecx
|
||||||
mov [edi + buf_head.length], cx
|
shr ecx, 2
|
||||||
mov [edi + buf_head.misc], 0
|
and edx, 3
|
||||||
|
rep movsd
|
||||||
mov eax, [esp]
|
mov ecx, edx
|
||||||
mov ecx, eax
|
rep movsb
|
||||||
and ecx, 0xfff
|
; set length
|
||||||
call GetPgAddr
|
mov ecx, [esp+4]
|
||||||
add eax, ecx
|
neg ecx
|
||||||
mov [edi + buf_head.base], eax
|
mov [eax + buf_head.length], cx
|
||||||
mov [edi + buf_head.status], 0x8300
|
; put to transfer queue
|
||||||
|
mov [eax + buf_head.status], 0x8300
|
||||||
|
|
||||||
; trigger an immediate send
|
; trigger an immediate send
|
||||||
mov ecx, 0 ; CSR0
|
xor ecx, ecx ; CSR0
|
||||||
call [ebx + device.access_read_csr]
|
call [ebx + device.access_read_csr]
|
||||||
or eax, PCNET_CSR_TX
|
or eax, PCNET_CSR_TX
|
||||||
call [ebx + device.access_write_csr]
|
call [ebx + device.access_write_csr]
|
||||||
@ -1180,7 +1200,11 @@ transmit:
|
|||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
.nospace:
|
||||||
|
DEBUGF 1, 'ERROR: no free transmit descriptors\n'
|
||||||
|
; todo: maybe somehow notify the kernel about the error?
|
||||||
|
add esp, 4+4
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1193,7 +1217,7 @@ transmit:
|
|||||||
align 4
|
align 4
|
||||||
int_handler:
|
int_handler:
|
||||||
|
|
||||||
DEBUGF 1,"IRQ %x ",eax:2 ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO
|
; DEBUGF 1,"IRQ %x ",eax:2 ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO
|
||||||
|
|
||||||
; find pointer of device wich made IRQ occur
|
; find pointer of device wich made IRQ occur
|
||||||
|
|
||||||
@ -1206,12 +1230,12 @@ int_handler:
|
|||||||
mov edx, [ebx + device.io_addr] ; get IRQ reason
|
mov edx, [ebx + device.io_addr] ; get IRQ reason
|
||||||
|
|
||||||
push ecx
|
push ecx
|
||||||
mov ecx, 0 ; CSR0
|
xor ecx, ecx ; CSR0
|
||||||
call [ebx + device.access_read_csr]
|
call [ebx + device.access_read_csr]
|
||||||
pop ecx
|
pop ecx
|
||||||
|
|
||||||
test ax , ax
|
test al , al
|
||||||
jnz .got_it
|
js .got_it
|
||||||
|
|
||||||
add esi, 4
|
add esi, 4
|
||||||
loop .nextdevice
|
loop .nextdevice
|
||||||
@ -1219,8 +1243,16 @@ int_handler:
|
|||||||
ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver
|
ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver
|
||||||
|
|
||||||
.got_it:
|
.got_it:
|
||||||
|
|
||||||
;-------------------------------------------------------
|
;-------------------------------------------------------
|
||||||
|
; Possible reasons:
|
||||||
|
; initialization done - ignore
|
||||||
|
; transmit done - ignore
|
||||||
|
; packet received - handle
|
||||||
|
; Clear ALL IRQ reasons.
|
||||||
|
; N.B. One who wants to handle more than one reason must be ready
|
||||||
|
; to two or more reasons in one IRQ.
|
||||||
|
xor ecx, ecx
|
||||||
|
call [ebx + device.access_write_csr]
|
||||||
; Received packet ok?
|
; Received packet ok?
|
||||||
|
|
||||||
test ax, PCNET_CSR_RINT
|
test ax, PCNET_CSR_RINT
|
||||||
@ -1241,17 +1273,18 @@ int_handler:
|
|||||||
test cx , PCNET_RXSTAT_OWN ; If this bit is set, the controller OWN's the packet, if not, we do
|
test cx , PCNET_RXSTAT_OWN ; If this bit is set, the controller OWN's the packet, if not, we do
|
||||||
jnz .abort
|
jnz .abort
|
||||||
|
|
||||||
cmp cx , PCNET_RXSTAT_ENP
|
test cx , PCNET_RXSTAT_ENP
|
||||||
jz .abort
|
jz .abort
|
||||||
|
|
||||||
cmp cx , PCNET_RXSTAT_STP
|
test cx , PCNET_RXSTAT_STP
|
||||||
jz .abort
|
jz .abort
|
||||||
|
|
||||||
movzx ecx, [ebx + buf_head.length] ; get packet length in ecx
|
movzx ecx, [edi + buf_head.msg_length] ; get packet length in ecx
|
||||||
and ecx, 0xfff ;
|
|
||||||
sub ecx, 4 ;
|
sub ecx, 4 ;
|
||||||
|
|
||||||
|
push ecx
|
||||||
stdcall KernelAlloc, ecx ; Allocate a buffer to put packet into
|
stdcall KernelAlloc, ecx ; Allocate a buffer to put packet into
|
||||||
|
pop ecx
|
||||||
test eax, eax ; Test if we allocated succesfully
|
test eax, eax ; Test if we allocated succesfully
|
||||||
jz .abort ;
|
jz .abort ;
|
||||||
|
|
||||||
@ -1267,8 +1300,8 @@ int_handler:
|
|||||||
and ecx, 3
|
and ecx, 3
|
||||||
rep movsb
|
rep movsb
|
||||||
|
|
||||||
mov word [eax + buf_head.length], PCNET_PKT_BUF_SZ_NEG
|
; mov word [eax + buf_head.length], PCNET_PKT_BUF_SZ_NEG
|
||||||
or word [eax + buf_head.status], PCNET_RXSTAT_OWN ; Set OWN bit back to 1 (controller may write to tx-buffer again now)
|
mov word [eax + buf_head.status], PCNET_RXSTAT_OWN ; Set OWN bit back to 1 (controller may write to tx-buffer again now)
|
||||||
|
|
||||||
inc [ebx + device.cur_rx] ; update descriptor
|
inc [ebx + device.cur_rx] ; update descriptor
|
||||||
and [ebx + device.cur_rx], 3 ;
|
and [ebx + device.cur_rx], 3 ;
|
||||||
@ -1472,7 +1505,7 @@ wio_reset:
|
|||||||
dwio_read_csr:
|
dwio_read_csr:
|
||||||
|
|
||||||
add edx, PCNET_DWIO_RAP
|
add edx, PCNET_DWIO_RAP
|
||||||
mov ecx, eax
|
mov eax, ecx
|
||||||
out dx , eax
|
out dx , eax
|
||||||
add edx, PCNET_DWIO_RDP - PCNET_DWIO_RAP
|
add edx, PCNET_DWIO_RDP - PCNET_DWIO_RAP
|
||||||
in eax, dx
|
in eax, dx
|
||||||
@ -1502,7 +1535,7 @@ dwio_write_csr:
|
|||||||
dwio_read_bcr:
|
dwio_read_bcr:
|
||||||
|
|
||||||
add edx, PCNET_DWIO_RAP
|
add edx, PCNET_DWIO_RAP
|
||||||
mov ecx, eax
|
mov eax, ecx
|
||||||
out dx , eax
|
out dx , eax
|
||||||
add edx, PCNET_DWIO_BDP - PCNET_DWIO_RAP
|
add edx, PCNET_DWIO_BDP - PCNET_DWIO_RAP
|
||||||
in eax, dx
|
in eax, dx
|
||||||
|
Loading…
Reference in New Issue
Block a user