RTL8139: Improved interrupt handeling.

git-svn-id: svn://kolibrios.org@9161 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2021-08-28 10:54:08 +00:00
parent 61d6d826c7
commit 3fa8866797

View File

@ -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