RTL8139: Improved interrupt handeling.
git-svn-id: svn://kolibrios.org@9161 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
61d6d826c7
commit
3fa8866797
@ -15,6 +15,8 @@
|
|||||||
;; ;;
|
;; ;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
; TODO: test for RX-overrun
|
||||||
|
|
||||||
format PE DLL native
|
format PE DLL native
|
||||||
entry START
|
entry START
|
||||||
|
|
||||||
@ -22,6 +24,8 @@ entry START
|
|||||||
COMPATIBLE_API = 0x0100
|
COMPATIBLE_API = 0x0100
|
||||||
API_VERSION = (COMPATIBLE_API shl 16) + CURRENT_API
|
API_VERSION = (COMPATIBLE_API shl 16) + CURRENT_API
|
||||||
|
|
||||||
|
; configureable area
|
||||||
|
|
||||||
MAX_DEVICES = 16
|
MAX_DEVICES = 16
|
||||||
|
|
||||||
RBLEN = 3 ; Receive buffer size: 0==8K 1==16k 2==32k 3==64k
|
RBLEN = 3 ; Receive buffer size: 0==8K 1==16k 2==32k 3==64k
|
||||||
@ -35,6 +39,8 @@ entry START
|
|||||||
__DEBUG__ = 1
|
__DEBUG__ = 1
|
||||||
__DEBUG_LEVEL__ = 2 ; 1 = verbose, 2 = errors only
|
__DEBUG_LEVEL__ = 2 ; 1 = verbose, 2 = errors only
|
||||||
|
|
||||||
|
; end configureable area
|
||||||
|
|
||||||
section '.flat' readable writable executable
|
section '.flat' readable writable executable
|
||||||
|
|
||||||
include '../proc32.inc'
|
include '../proc32.inc'
|
||||||
@ -639,13 +645,13 @@ reset:
|
|||||||
;; 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]
|
||||||
@ -656,9 +662,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
|
||||||
|
|
||||||
; check if we own the current discriptor
|
; check if we own the current discriptor
|
||||||
set_io [ebx + device.io_addr], 0
|
set_io [ebx + device.io_addr], 0
|
||||||
@ -668,9 +674,8 @@ proc transmit stdcall bufferptr
|
|||||||
add edx, ecx
|
add edx, ecx
|
||||||
in eax, dx
|
in eax, dx
|
||||||
test eax, (1 shl BIT_OWN)
|
test eax, (1 shl BIT_OWN)
|
||||||
jz .wait_to_send
|
jz .overrun
|
||||||
|
|
||||||
.send_packet:
|
|
||||||
; Set the buffer address
|
; Set the buffer address
|
||||||
set_io [ebx + device.io_addr], REG_TSAD0
|
set_io [ebx + device.io_addr], REG_TSAD0
|
||||||
mov [ebx + device.TX_DESC+ecx], esi
|
mov [ebx + device.TX_DESC+ecx], esi
|
||||||
@ -691,37 +696,29 @@ proc transmit stdcall bufferptr
|
|||||||
|
|
||||||
; Update stats
|
; Update stats
|
||||||
inc [ebx + device.packets_tx]
|
inc [ebx + device.packets_tx]
|
||||||
mov ecx, [esi + NET_BUFF.length]
|
mov eax, [esi + NET_BUFF.length]
|
||||||
add dword [ebx + device.bytes_tx], ecx
|
add dword[ebx + device.bytes_tx], eax
|
||||||
adc dword[ebx + device.bytes_tx + 4], 0
|
adc dword[ebx + device.bytes_tx + 4], 0
|
||||||
|
|
||||||
DEBUGF 1, "Packet Sent!\n"
|
spin_unlock_irqrestore
|
||||||
popf
|
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.wait_to_send:
|
.error:
|
||||||
DEBUGF 1, "Waiting for timeout\n"
|
DEBUGF 2, "TX packet error\n"
|
||||||
|
inc [ebx + device.packets_tx_err]
|
||||||
push edx
|
|
||||||
mov esi, 30
|
|
||||||
invoke Sleep
|
|
||||||
pop edx
|
|
||||||
|
|
||||||
in ax, dx
|
|
||||||
test ax, (1 shl BIT_OWN)
|
|
||||||
jnz .send_packet
|
|
||||||
|
|
||||||
pusha
|
|
||||||
call reset ; if chip hung, reset it
|
|
||||||
popa
|
|
||||||
|
|
||||||
jmp .send_packet
|
|
||||||
|
|
||||||
.fail:
|
|
||||||
DEBUGF 2, "transmit 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
|
||||||
|
|
||||||
@ -736,41 +733,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], REG_ISR
|
set_io [ebx + device.io_addr], REG_ISR
|
||||||
in ax, dx ; Get interrupt status
|
in ax, dx ; Get interrupt status
|
||||||
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 (The irq was probably for a device, not registered to this driver)
|
out dx, ax ; ACK interrupt
|
||||||
|
DEBUGF 1, "Status: %x\n", ax
|
||||||
.got_it:
|
|
||||||
|
|
||||||
DEBUGF 1, "Device: %x Status: %x\n", ebx, ax
|
|
||||||
|
|
||||||
;----------------------------------------------------
|
;----------------------------------------------------
|
||||||
; Received packet ok?
|
; Received packet ok?
|
||||||
@ -884,10 +864,10 @@ int_handler:
|
|||||||
|
|
||||||
.finish:
|
.finish:
|
||||||
pop ax
|
pop ax
|
||||||
|
@@:
|
||||||
|
|
||||||
;----------------------------------------------------
|
;----------------------------------------------------
|
||||||
; Transmit ok / Transmit error
|
; Transmit ok / Transmit error
|
||||||
@@:
|
|
||||||
test ax, ISR_TOK + ISR_TER
|
test ax, ISR_TOK + ISR_TER
|
||||||
jz @f
|
jz @f
|
||||||
|
|
||||||
@ -944,10 +924,10 @@ int_handler:
|
|||||||
sub ecx, 4
|
sub ecx, 4
|
||||||
jae .txdescloop
|
jae .txdescloop
|
||||||
pop ax
|
pop ax
|
||||||
|
@@:
|
||||||
|
|
||||||
;----------------------------------------------------
|
;----------------------------------------------------
|
||||||
; Rx buffer overflow ?
|
; Rx buffer overflow ?
|
||||||
@@:
|
|
||||||
test ax, ISR_RXOVW
|
test ax, ISR_RXOVW
|
||||||
jz @f
|
jz @f
|
||||||
|
|
||||||
@ -959,20 +939,20 @@ int_handler:
|
|||||||
mov ax, ISR_FIFOOVW or ISR_RXOVW or ISR_ROK
|
mov ax, ISR_FIFOOVW or ISR_RXOVW or ISR_ROK
|
||||||
out dx, ax
|
out dx, ax
|
||||||
pop ax
|
pop ax
|
||||||
|
@@:
|
||||||
|
|
||||||
;----------------------------------------------------
|
;----------------------------------------------------
|
||||||
; Packet underrun?
|
; Packet underrun?
|
||||||
@@:
|
|
||||||
test ax, ISR_PUN
|
test ax, ISR_PUN
|
||||||
jz @f
|
jz @f
|
||||||
|
|
||||||
DEBUGF 1, "Packet underrun or link changed!\n"
|
DEBUGF 1, "Packet underrun or link changed!\n"
|
||||||
|
|
||||||
call link
|
call link
|
||||||
|
@@:
|
||||||
|
|
||||||
;----------------------------------------------------
|
;----------------------------------------------------
|
||||||
; Receive FIFO overflow ?
|
; Receive FIFO overflow ?
|
||||||
@@:
|
|
||||||
test ax, ISR_FIFOOVW
|
test ax, ISR_FIFOOVW
|
||||||
jz @f
|
jz @f
|
||||||
|
|
||||||
@ -984,24 +964,29 @@ int_handler:
|
|||||||
mov ax, ISR_FIFOOVW or ISR_RXOVW or ISR_ROK
|
mov ax, ISR_FIFOOVW or ISR_RXOVW or ISR_ROK
|
||||||
out dx, ax
|
out dx, ax
|
||||||
pop ax
|
pop ax
|
||||||
|
@@:
|
||||||
|
|
||||||
;----------------------------------------------------
|
;----------------------------------------------------
|
||||||
; cable length changed ?
|
; cable length changed ?
|
||||||
@@:
|
|
||||||
test ax, ISR_LENCHG
|
test ax, ISR_LENCHG
|
||||||
jz .fail
|
jz @f
|
||||||
|
|
||||||
DEBUGF 2, "Cable length changed!\n"
|
DEBUGF 2, "Cable length changed!\n"
|
||||||
|
|
||||||
call link
|
call link
|
||||||
|
@@:
|
||||||
|
|
||||||
.fail:
|
|
||||||
pop edi esi ebx
|
pop edi esi ebx
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
inc eax
|
inc eax
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
.nothing:
|
||||||
|
pop edi esi ebx
|
||||||
|
xor eax, eax
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user