PcNET32: Handle FIFO overruns gracefully.

git-svn-id: svn://kolibrios.org@8898 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2021-06-20 20:30:44 +00:00
parent c32ae93703
commit ff6bf9b758

View File

@ -1016,9 +1016,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 descriptor ; check descriptor
lea edi, [ebx + device.tx_ring] lea edi, [ebx + device.tx_ring]
@ -1027,7 +1027,7 @@ proc transmit stdcall bufferptr
add edi, ecx add edi, ecx
test [edi + descriptor.status], TXCTL_OWN test [edi + descriptor.status], TXCTL_OWN
jnz .fail jnz .overrun
; descriptor is free, use it ; descriptor is free, use it
mov [edi + descriptor.virtual], esi mov [edi + descriptor.virtual], esi
mov eax, esi mov eax, esi
@ -1058,14 +1058,24 @@ 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
.finish:
popf popf
xor eax, eax xor eax, eax
ret ret
.fail: .error:
DEBUGF 2, "Send failed\n" DEBUGF 2, "TX packet error\n"
inc [ebx + device.packets_tx_err]
invoke NetFree, [bufferptr] invoke NetFree, [bufferptr]
popf
or eax, -1
ret
.overrun:
DEBUGF 2, "TX overrun\n"
inc [ebx + device.packets_tx_ovr]
invoke NetFree, [bufferptr]
popf popf
or eax, -1 or eax, -1
ret ret
@ -1122,6 +1132,7 @@ int_handler:
push ebx push ebx
.rx_loop: .rx_loop:
pop ebx pop ebx
push ebx
mov eax, [ebx + device.cur_rx] mov eax, [ebx + device.cur_rx]
shl eax, 4 shl eax, 4
lea edi, [ebx + device.rx_ring] lea edi, [ebx + device.rx_ring]
@ -1131,21 +1142,18 @@ int_handler:
DEBUGF 1,"RX packet status: %x\n", eax:4 DEBUGF 1,"RX packet status: %x\n", eax:4
test ax, RXSTAT_OWN ; If this bit is set, the controller OWN's the packet, if not, we do test ax, RXSTAT_OWN ; If this bit is set, the controller OWN's the packet, if not, we do
jnz .not_receive jnz .rx_done
; Both Start of packet and End of packet bits should be set, we dont support multi frame packets
test ax, RXSTAT_ENP test ax, RXSTAT_ENP
jz .not_receive jz .rx_drop
test ax, RXSTAT_STP test ax, RXSTAT_STP
jz .not_receive jz .rx_drop
movzx ecx, [edi + descriptor.msg_length] ; get packet length in ecx movzx ecx, [edi + descriptor.msg_length] ; get packet length in ecx
sub ecx, 4 ; We dont need the CRC sub ecx, 4 ; We dont need the CRC
DEBUGF 1,"Got %u bytes\n", ecx DEBUGF 1,"Got %u bytes\n", ecx
; Set pointers for ETH_input ; Set pointers for ETH_input
push ebx
push .rx_loop ; return address push .rx_loop ; return address
mov eax, [edi + descriptor.virtual] mov eax, [edi + descriptor.virtual]
push eax ; packet address push eax ; packet address
@ -1161,7 +1169,7 @@ int_handler:
; now allocate a new buffer ; now allocate a new buffer
invoke NetAlloc, PKT_BUF_SZ+NET_BUFF.data ; Allocate a buffer for the next packet invoke NetAlloc, PKT_BUF_SZ+NET_BUFF.data ; Allocate a buffer for the next packet
test eax, eax test eax, eax
jz .out_of_mem jz .rx_overrun
mov [edi + descriptor.virtual], eax ; set virtual address mov [edi + descriptor.virtual], eax ; set virtual address
invoke GetPhysAddr invoke GetPhysAddr
add eax, NET_BUFF.data add eax, NET_BUFF.data
@ -1173,13 +1181,25 @@ int_handler:
jmp [EthInput] jmp [EthInput]
.out_of_mem: .rx_overrun:
DEBUGF 2,"Out of memory!\n" add esp, 4+4
DEBUGF 2,"RX FIFO overrun\n"
inc [ebx + device.packets_rx_ovr]
jmp .rx_next
.rx_drop:
DEBUGF 2,"Dropping incoming packet\n"
inc [ebx + device.packets_rx_drop]
.rx_next:
mov [edi + descriptor.status], RXSTAT_OWN ; give it back to PCnet controller
inc [ebx + device.cur_rx] ; set next receive descriptor inc [ebx + device.cur_rx] ; set next receive descriptor
and [ebx + device.cur_rx], RX_RING_SIZE - 1 and [ebx + device.cur_rx], RX_RING_SIZE - 1
jmp .rx_loop
jmp [EthInput] .rx_done:
pop ebx
.not_receive: .not_receive:
pop ax pop ax