forked from KolibriOS/kolibrios
R6040: Improved interrupt handeling.
git-svn-id: svn://kolibrios.org@9158 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
650af770ae
commit
d297ba3894
@ -1,6 +1,6 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
|
;; Copyright (C) KolibriOS team 2004-2021. All rights reserved. ;;
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
;; Distributed under terms of the GNU General Public License ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; R6040 driver for KolibriOS ;;
|
;; R6040 driver for KolibriOS ;;
|
||||||
@ -15,6 +15,8 @@
|
|||||||
;; ;;
|
;; ;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
; TODO: test for RX-overrun
|
||||||
|
|
||||||
format PE DLL native
|
format PE DLL native
|
||||||
entry START
|
entry START
|
||||||
|
|
||||||
@ -31,8 +33,8 @@ entry START
|
|||||||
|
|
||||||
TX_TIMEOUT = 6000 ; Time before concluding the transmitter is hung, in ms
|
TX_TIMEOUT = 6000 ; Time before concluding the transmitter is hung, in ms
|
||||||
|
|
||||||
TX_RING_SIZE = 4 ; RING sizes must be a power of 2
|
TX_RING_SIZE = 16 ; RING sizes must be a power of 2
|
||||||
RX_RING_SIZE = 4
|
RX_RING_SIZE = 16
|
||||||
|
|
||||||
RX_BUF_LEN_IDX = 3 ; 0==8K, 1==16K, 2==32K, 3==64K
|
RX_BUF_LEN_IDX = 3 ; 0==8K, 1==16K, 2==32K, 3==64K
|
||||||
|
|
||||||
@ -379,17 +381,6 @@ endp
|
|||||||
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
|
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
|
||||||
|
|
||||||
|
|
||||||
;mdio_read:
|
|
||||||
; stdcall phy_read, [ebx + device.io_addr], [ebx + device.phy_addr], ecx
|
|
||||||
|
|
||||||
; ret
|
|
||||||
|
|
||||||
;mdio_write:
|
|
||||||
; stdcall phy_write, [ebx + device.io_addr], [ebx + device.phy_addr], ecx, eax
|
|
||||||
|
|
||||||
; ret
|
|
||||||
|
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
unload:
|
unload:
|
||||||
; TODO: (in this particular order)
|
; TODO: (in this particular order)
|
||||||
@ -602,7 +593,7 @@ reset:
|
|||||||
;Enable RX
|
;Enable RX
|
||||||
mov ax, [ebx + device.mcr0]
|
mov ax, [ebx + device.mcr0]
|
||||||
or ax, MCR0_RCVEN
|
or ax, MCR0_RCVEN
|
||||||
set_io [ebx + device.io_addr], 0
|
set_io [ebx + device.io_addr], MCR0
|
||||||
out dx, ax
|
out dx, ax
|
||||||
|
|
||||||
;Let TX poll the descriptors
|
;Let TX poll the descriptors
|
||||||
@ -738,13 +729,13 @@ phy_mode_chk:
|
|||||||
;; Transmit ;;
|
;; Transmit ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; In: pointer to device structure in ebx ;;
|
;; In: pointer to device structure in ebx ;;
|
||||||
|
;; Out: eax = 0 on success ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
align 16
|
||||||
proc transmit stdcall bufferptr
|
proc transmit stdcall bufferptr
|
||||||
|
|
||||||
pushf
|
spin_lock_irqsave
|
||||||
cli
|
|
||||||
|
|
||||||
mov esi, [bufferptr]
|
mov esi, [bufferptr]
|
||||||
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
|
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
|
||||||
@ -755,9 +746,9 @@ proc transmit stdcall bufferptr
|
|||||||
[eax+13]:2,[eax+12]:2
|
[eax+13]:2,[eax+12]:2
|
||||||
|
|
||||||
cmp [esi + NET_BUFF.length], 1514
|
cmp [esi + NET_BUFF.length], 1514
|
||||||
ja .fail
|
ja .error
|
||||||
cmp [esi + NET_BUFF.length], 60
|
cmp [esi + NET_BUFF.length], 60
|
||||||
jb .fail
|
jb .error
|
||||||
|
|
||||||
movzx edi, [ebx + device.cur_tx]
|
movzx edi, [ebx + device.cur_tx]
|
||||||
shl edi, 5
|
shl edi, 5
|
||||||
@ -767,10 +758,7 @@ proc transmit stdcall bufferptr
|
|||||||
DEBUGF 1,"TX buffer status: 0x%x\n", [edi + x_head.status]:4
|
DEBUGF 1,"TX buffer status: 0x%x\n", [edi + x_head.status]:4
|
||||||
|
|
||||||
test [edi + x_head.status], DSC_OWNER_MAC ; check if buffer is available
|
test [edi + x_head.status], DSC_OWNER_MAC ; check if buffer is available
|
||||||
jnz .wait_to_send
|
jnz .overrun
|
||||||
|
|
||||||
.do_send:
|
|
||||||
DEBUGF 1,"Sending now\n"
|
|
||||||
|
|
||||||
mov [edi + x_head.skb_ptr], esi
|
mov [edi + x_head.skb_ptr], esi
|
||||||
mov eax, esi
|
mov eax, esi
|
||||||
@ -796,32 +784,25 @@ proc transmit stdcall bufferptr
|
|||||||
add dword[ebx + device.bytes_tx], eax
|
add dword[ebx + device.bytes_tx], eax
|
||||||
adc dword[ebx + device.bytes_tx + 4], 0
|
adc dword[ebx + device.bytes_tx + 4], 0
|
||||||
|
|
||||||
popf
|
spin_unlock_irqrestore
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.wait_to_send:
|
.error:
|
||||||
DEBUGF 1,"Waiting for TX buffer\n"
|
DEBUGF 2, "TX packet error\n"
|
||||||
invoke GetTimerTicks ; returns in eax
|
inc [ebx + device.packets_tx_err]
|
||||||
lea edx, [eax + 100]
|
|
||||||
.l2:
|
|
||||||
mov esi, [bufferptr]
|
|
||||||
test [edi + x_head.status], DSC_OWNER_MAC
|
|
||||||
jz .do_send
|
|
||||||
popf
|
|
||||||
mov esi, 10
|
|
||||||
invoke Sleep
|
|
||||||
invoke GetTimerTicks
|
|
||||||
pushf
|
|
||||||
cli
|
|
||||||
cmp edx, eax
|
|
||||||
jb .l2
|
|
||||||
|
|
||||||
DEBUGF 2,"Send timeout\n"
|
|
||||||
.fail:
|
|
||||||
DEBUGF 2,"Send failed\n"
|
|
||||||
invoke NetFree, [bufferptr]
|
invoke NetFree, [bufferptr]
|
||||||
popf
|
|
||||||
|
spin_unlock_irqrestore
|
||||||
|
or eax, -1
|
||||||
|
ret
|
||||||
|
|
||||||
|
.overrun:
|
||||||
|
DEBUGF 2, "TX overrun\n"
|
||||||
|
inc [ebx + device.packets_tx_ovr]
|
||||||
|
invoke NetFree, [bufferptr]
|
||||||
|
|
||||||
|
spin_unlock_irqrestore
|
||||||
or eax, -1
|
or eax, -1
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -834,44 +815,24 @@ endp
|
|||||||
;; Interrupt handler ;;
|
;; Interrupt handler ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
align 16
|
||||||
align 4
|
|
||||||
int_handler:
|
int_handler:
|
||||||
|
|
||||||
push ebx esi edi
|
push ebx esi edi
|
||||||
|
|
||||||
DEBUGF 1,"int\n"
|
mov ebx, [esp+4*4]
|
||||||
|
DEBUGF 1,"INT for 0x%x\n", ebx
|
||||||
|
|
||||||
; Find pointer of device wich made IRQ occur
|
; TODO? if we are paranoid, we can check that the value from ebx is present in the current device_list
|
||||||
|
|
||||||
mov ecx, [devices]
|
|
||||||
test ecx, ecx
|
|
||||||
jz .nothing
|
|
||||||
mov esi, device_list
|
|
||||||
.nextdevice:
|
|
||||||
mov ebx, [esi]
|
|
||||||
|
|
||||||
set_io [ebx + device.io_addr], 0
|
set_io [ebx + device.io_addr], 0
|
||||||
set_io [ebx + device.io_addr], MISR
|
set_io [ebx + device.io_addr], MISR
|
||||||
in ax, dx
|
in ax, dx
|
||||||
out dx, ax ; send it back to ACK
|
|
||||||
test ax, ax
|
test ax, ax
|
||||||
jnz .got_it
|
jz .nothing
|
||||||
.continue:
|
|
||||||
add esi, 4
|
|
||||||
dec ecx
|
|
||||||
jnz .nextdevice
|
|
||||||
.nothing:
|
|
||||||
pop edi esi ebx
|
|
||||||
xor eax, eax
|
|
||||||
|
|
||||||
ret ; If no device was found, abort
|
out dx, ax ; ACK interrupt
|
||||||
|
DEBUGF 1,"Status: %x\n", ax
|
||||||
; At this point, test for all possible reasons, and handle accordingly
|
|
||||||
|
|
||||||
.got_it:
|
|
||||||
|
|
||||||
DEBUGF 1,"Device: %x Status: %x\n", ebx, ax
|
|
||||||
|
|
||||||
push ax
|
push ax
|
||||||
|
|
||||||
@ -934,12 +895,10 @@ int_handler:
|
|||||||
|
|
||||||
; At last, send packet to kernel
|
; At last, send packet to kernel
|
||||||
jmp [EthInput]
|
jmp [EthInput]
|
||||||
|
|
||||||
|
|
||||||
.no_RX:
|
.no_RX:
|
||||||
|
|
||||||
test word[esp], TX_FINISH
|
test word[esp], TX_FINISH
|
||||||
jz .no_TX
|
jz .no_TX
|
||||||
|
|
||||||
.loop_tx:
|
.loop_tx:
|
||||||
movzx edi, [ebx + device.last_tx]
|
movzx edi, [ebx + device.last_tx]
|
||||||
shl edi, 5
|
shl edi, 5
|
||||||
@ -961,47 +920,55 @@ int_handler:
|
|||||||
and [ebx + device.last_tx], TX_RING_SIZE - 1
|
and [ebx + device.last_tx], TX_RING_SIZE - 1
|
||||||
|
|
||||||
jmp .loop_tx
|
jmp .loop_tx
|
||||||
|
|
||||||
.no_TX:
|
.no_TX:
|
||||||
|
|
||||||
test word[esp], RX_NO_DESC
|
test word[esp], RX_NO_DESC
|
||||||
jz .no_rxdesc
|
jz .no_rxdesc
|
||||||
|
|
||||||
DEBUGF 2, "No more RX descriptors!\n"
|
DEBUGF 2, "No more RX descriptors!\n"
|
||||||
|
|
||||||
.no_rxdesc:
|
.no_rxdesc:
|
||||||
|
|
||||||
test word[esp], RX_FIFO_FULL
|
test word[esp], RX_FIFO_FULL
|
||||||
jz .no_rxfifo
|
jz .no_rxfifo
|
||||||
|
|
||||||
DEBUGF 2, "RX FIFO full!\n"
|
DEBUGF 2, "RX FIFO full!\n"
|
||||||
|
|
||||||
.no_rxfifo:
|
.no_rxfifo:
|
||||||
|
|
||||||
test word[esp], RX_EARLY
|
test word[esp], RX_EARLY
|
||||||
jz .no_rxearly
|
jz .no_rxearly
|
||||||
|
|
||||||
DEBUGF 2, "RX early\n"
|
DEBUGF 2, "RX early\n"
|
||||||
|
|
||||||
.no_rxearly:
|
.no_rxearly:
|
||||||
|
|
||||||
test word[esp], TX_EARLY
|
test word[esp], TX_EARLY
|
||||||
jz .no_txearly
|
jz .no_txearly
|
||||||
|
|
||||||
DEBUGF 2, "TX early\n"
|
DEBUGF 2, "TX early\n"
|
||||||
|
|
||||||
.no_txearly:
|
.no_txearly:
|
||||||
|
|
||||||
test word[esp], EVENT_OVRFL
|
test word[esp], EVENT_OVRFL
|
||||||
jz .no_ovrfl
|
jz .no_ovrfl
|
||||||
|
|
||||||
DEBUGF 2, "Event counter overflow!\n"
|
DEBUGF 2, "Event counter overflow!\n"
|
||||||
|
|
||||||
.no_ovrfl:
|
.no_ovrfl:
|
||||||
|
|
||||||
test word[esp], LINK_CHANGED
|
test word[esp], LINK_CHANGED
|
||||||
jz .no_link
|
jz .no_link
|
||||||
|
|
||||||
DEBUGF 2, "Link changed\n"
|
DEBUGF 2, "Link changed\n"
|
||||||
|
|
||||||
.no_link:
|
.no_link:
|
||||||
|
|
||||||
pop ax
|
pop ax
|
||||||
|
|
||||||
pop edi esi ebx
|
pop edi esi ebx
|
||||||
|
xor eax, eax
|
||||||
|
inc eax
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
.nothing:
|
||||||
|
pop edi esi ebx
|
||||||
|
xor eax, eax
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user