New network buffers - phase I

git-svn-id: svn://kolibrios.org@5522 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2015-03-17 21:50:29 +00:00
parent a07659c72e
commit 0ba1fff7a7
31 changed files with 902 additions and 689 deletions

View File

@ -289,9 +289,7 @@ include '../netdrv.inc'
RxBroadcast = 4
RxProm = 8
; RX/TX buffers sizes
MAX_ETH_PKT_SIZE = 1536 ; max packet size
MAX_ETH_FRAME_SIZE = 1520 ; size of ethernet frame + bytes alignment
MAX_ETH_FRAME_SIZE = 1514
struct tx_desc
@ -806,6 +804,9 @@ end if
call set_active_port
call create_rx_ring
test eax, eax
jnz .err
call rx_reset
call tx_reset
@ -816,11 +817,13 @@ end if
mov ecx, 6
rep stosd
xor eax, eax
ret
.err:
DEBUGF 2,"reset failed\n"
or eax, -1
ret
align 4
@ -901,7 +904,8 @@ start_device:
mov [ebx + device.mtu], 1514
; Set link state to unknown
mov [ebx + device.state], ETH_LINK_UNKNOWN
mov [ebx + device.state], ETH_LINK_UNKNOWN
xor eax, eax
ret
@ -997,10 +1001,13 @@ create_rx_ring:
mov [edx + rx_desc.next_ptr], edi
push ecx edx
invoke KernelAlloc, MAX_ETH_FRAME_SIZE
invoke NetAlloc, MAX_ETH_FRAME_SIZE+NET_BUFF.data
pop edx ecx
test eax, eax
jz .out_of_mem
mov [esi + rx_desc.realaddr], eax
invoke GetPgAddr
invoke GetPhysAddr
add eax, NET_BUFF.data
mov [esi + rx_desc.frag_addr], eax
and [esi + rx_desc.pkt_status], 0
mov [esi + rx_desc.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31)
@ -1014,6 +1021,11 @@ create_rx_ring:
dec ecx
jnz .loop
xor eax, eax
ret
.out_of_mem:
or eax, -1
ret
@ -1039,15 +1051,14 @@ try_link_detect:
DEBUGF 1,"Trying to detect link\n"
; create self-directed packet
invoke KernelAlloc, 20 ; create a buffer for the self-directed packet
invoke NetAlloc, 20+NET_BUFF.data ; create a buffer for the self-directed packet
test eax, eax
jz .fail
pushd 20 ; Packet parameters for device.transmit
push eax ;
mov edi, eax
push eax
mov [eax + NET_BUFF.length], 20
lea edi, [eax + NET_BUFF.data]
lea esi, [ebx + device.mac]
movsw
movsd
@ -1092,10 +1103,12 @@ try_link_detect:
jz @f
or byte [ebx + device.internal_link+1], 100b
@@:
xor eax, eax
ret
.fail:
DEBUGF 1,"No link detected!\n"
or eax, -1
ret
@ -1135,7 +1148,7 @@ try_phy:
; wait for reset to complete
mov esi, 2000
invoke Sleep ; 2s
invoke Sleep ; 2s FIXME
mov eax, [esp]
call mdio_read ; returns with window #4
test ah, 0x80
@ -1144,7 +1157,7 @@ try_phy:
; wait for a while after reset
mov esi, 20
invoke Sleep ; 20ms
invoke Sleep ; 20ms
mov eax, [esp]
mov al , MII_BMSR
call mdio_read ; returns with window #4
@ -1407,14 +1420,15 @@ test_packet:
call tx_reset
; create self-directed packet
invoke KernelAlloc, 20 ; create a buffer for the self-directed packet
invoke NetAlloc, 20 + NET_BUFF.data ; create a buffer for the self-directed packet
test eax, eax
jz .fail
pushd 20 ; Packet parameters for device.transmit
push eax ;
push eax
mov [eax + NET_BUFF.length], 20
; mov [eax + NET_BUFF.device], ebx
mov edi, eax
lea edi, [eax + NET_BUFF.data]
lea esi, [ebx + device.mac]
movsw
movsd
@ -1428,7 +1442,7 @@ test_packet:
call [ebx + device.transmit]
; wait for 2s
mov esi, 2000
mov esi, 2000 ; FIXME
invoke Sleep
; check if self-directed packet is received
@ -2124,26 +2138,26 @@ check_tx_status:
;; Transmit (vortex) ;;
;; ;;
;; In: buffer pointer in [esp+4] ;;
;; size of buffer in [esp+8] ;;
;; pointer to device structure in ebx ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
proc vortex_transmit stdcall bufferptr, buffersize
proc vortex_transmit stdcall bufferptr
pushf
cli
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
mov eax, [bufferptr]
mov esi, [bufferptr]
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
lea eax, [esi + NET_BUFF.data]
DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
[eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
[eax+13]:2,[eax+12]:2
cmp [buffersize], 1514
cmp [esi + NET_BUFF.length], 1514
ja .fail
cmp [buffersize], 60
cmp [esi + NET_BUFF.length], 60
jb .fail
call check_tx_status
@ -2153,20 +2167,25 @@ proc vortex_transmit stdcall bufferptr, buffersize
set_io [ebx + device.io_addr], REG_COMMAND
mov ax, SELECT_REGISTER_WINDOW+7
out dx, ax
; check for master operation in progress
set_io [ebx + device.io_addr], REG_MASTER_STATUS
in ax, dx
test ah, 0x80
jnz .fail ; no DMA for sending
; program frame address to be sent
set_io [ebx + device.io_addr], REG_MASTER_ADDRESS
mov eax, [bufferptr]
mov eax, esi
add eax, [eax + NET_BUFF.offset]
invoke GetPhysAddr
out dx, eax
; program frame length
set_io [ebx + device.io_addr], REG_MASTER_LEN
mov eax, [buffersize]
mov eax, [esi + NET_BUFF.length]
out dx, ax
; start DMA Down
set_io [ebx + device.io_addr], REG_COMMAND
mov ax, (10100b shl 11) + 1 ; StartDMADown
@ -2178,7 +2197,7 @@ proc vortex_transmit stdcall bufferptr, buffersize
.fail:
DEBUGF 2,"Send failed\n"
invoke KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
@ -2190,38 +2209,38 @@ endp
;; Transmit (boomerang) ;;
;; ;;
;; In: buffer pointer in [esp+4] ;;
;; size of buffer in [esp+8] ;;
;; pointer to device structure in ebx ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
proc boomerang_transmit stdcall bufferptr, buffersize
proc boomerang_transmit stdcall bufferptr
pushf
cli
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
mov eax, [bufferptr]
mov esi, [bufferptr]
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
lea eax, [esi + NET_BUFF.data]
DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
[eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
[eax+13]:2,[eax+12]:2
cmp [buffersize], 1514
cmp [esi + NET_BUFF.length], 1514
ja .fail
cmp [buffersize], 60
cmp [esi + NET_BUFF.length], 60
jb .fail
call check_tx_status ; Reset TX engine if needed
; calculate descriptor address
mov esi, [ebx + device.curr_tx]
DEBUGF 1,"Previous TX desc: %x\n", esi
add esi, sizeof.tx_desc
mov edi, [ebx + device.curr_tx]
DEBUGF 1,"Previous TX desc: %x\n", edi
add edi, sizeof.tx_desc
lea ecx, [ebx + device.tx_desc_buffer + (NUM_TX_DESC)*sizeof.tx_desc]
cmp esi, ecx
cmp edi, ecx
jb @f
lea esi, [ebx + device.tx_desc_buffer] ; Wrap if needed
lea edi, [ebx + device.tx_desc_buffer] ; Wrap if needed
@@:
DEBUGF 1,"Using TX desc: %x\n", esi
@ -2239,31 +2258,32 @@ proc boomerang_transmit stdcall bufferptr, buffersize
; update statistics
inc [ebx + device.packets_tx]
mov ecx, [buffersize]
mov ecx, [esi + NET_BUFF.length]
add dword [ebx + device.bytes_tx], ecx
adc dword [ebx + device.bytes_tx + 4], 0
; program DPD
and [esi + tx_desc.next_ptr], 0
and [edi + tx_desc.next_ptr], 0
mov eax, [bufferptr]
mov [esi + tx_desc.realaddr], eax
mov [edi + tx_desc.realaddr], eax
add eax, [eax + NET_BUFF.offset]
invoke GetPhysAddr
mov [esi + tx_desc.frag_addr], eax
mov ecx, [buffersize]
mov [edi + tx_desc.frag_addr], eax
;;; mov ecx, [buffersize]
or ecx, 0x80000000 ; last fragment flag
mov [esi + tx_desc.frag_len], ecx
mov [edi + tx_desc.frag_len], ecx
mov ecx, [buffersize] ; packet size
;;; mov ecx, [buffersize] ; packet size
or ecx, 0x80008000 ; set OWN bit + transmission complete notification flag
; test byte [ebx + device.has_hwcksm], 0xff
; jz @f
; or ecx, (1 shl 26) ; set AddTcpChecksum
;@@:
mov [esi + tx_desc.frame_start_hdr], ecx
DEBUGF 1,"TX desc: lin=%x phys=%x len=%x start hdr=%x\n", [esi+tx_desc.realaddr]:8, [esi+tx_desc.frag_addr]:8, [esi+tx_desc.frag_len]:8, [esi+tx_desc.frame_start_hdr]:8
mov [edi + tx_desc.frame_start_hdr], ecx
DEBUGF 1,"TX desc: lin=%x phys=%x len=%x start hdr=%x\n", [edi+tx_desc.realaddr]:8, [edi+tx_desc.frag_addr]:8, [edi+tx_desc.frag_len]:8, [edi+tx_desc.frame_start_hdr]:8
; calculate physical address of tx descriptor
mov eax, esi
mov eax, edi
invoke GetPhysAddr
cmp [ebx + device.dn_list_ptr_cleared], 0
je .add_to_list
@ -2318,14 +2338,14 @@ proc boomerang_transmit stdcall bufferptr, buffersize
out dx, ax
.finish:
mov [ebx + device.curr_tx], esi
mov [ebx + device.curr_tx], edi
popf
xor eax, eax
ret
.fail:
DEBUGF 2,"Send failed\n"
invoke KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
@ -2493,7 +2513,7 @@ int_vortex:
.check_length:
and eax, 0x1fff
cmp eax, MAX_ETH_PKT_SIZE
cmp eax, MAX_ETH_FRAME_SIZE
ja .discard_frame ; frame is too long discard it
.check_dma:
@ -2513,15 +2533,18 @@ int_vortex:
.read_frame:
; program buffer address to read in
push ecx
invoke KernelAlloc, MAX_ETH_FRAME_SIZE
invoke NetAlloc, MAX_ETH_FRAME_SIZE + NET_BUFF.data
pop ecx
test eax, eax
jz .finish
push .discard_frame
push ecx
push eax
; zero_to_dma eax
mov [eax + NET_BUFF.length], ecx
mov [eax + NET_BUFF.device], ebx
mov [eax + NET_BUFF.offset], NET_BUFF.data
invoke GetPhysAddr
add eax, NET_BUFF.data
set_io [ebx + device.io_addr], REG_MASTER_ADDRESS
out dx, eax
@ -2543,7 +2566,7 @@ int_vortex:
jnz .dma_loop
; registrate the received packet to kernel
jmp Eth_input
jmp [EthInput]
; discard the top frame received
.discard_frame:
@ -2555,7 +2578,7 @@ int_vortex:
.finish:
.noRX:
.noRX:
test ax, DMADone
jz .noDMA
@ -2579,11 +2602,11 @@ int_vortex:
.noDMA:
.noDMA:
.ACK:
.ACK:
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], REG_COMMAND
mov ax, AckIntr + IntReq + IntLatch
@ -2678,8 +2701,11 @@ int_boomerang:
DEBUGF 1, "Received %u bytes in buffer %x\n", ecx, [esi + rx_desc.realaddr]:8
push dword .loop ;.finish
push ecx
push [esi + rx_desc.realaddr]
mov eax, [esi + rx_desc.realaddr]
push eax
mov [eax + NET_BUFF.length], ecx
mov [eax + NET_BUFF.device], ebx
mov [eax + NET_BUFF.offset], NET_BUFF.data
; update statistics
inc [ebx + device.packets_rx]
@ -2687,9 +2713,10 @@ int_boomerang:
adc dword [ebx + device.bytes_rx + 4], 0
; update rx descriptor (Alloc new buffer for next packet)
invoke KernelAlloc, MAX_ETH_FRAME_SIZE
invoke NetAlloc, MAX_ETH_FRAME_SIZE + NET_BUFF.data
mov [esi + rx_desc.realaddr], eax
invoke GetPhysAddr
add eax, NET_BUFF.data
mov [esi + rx_desc.frag_addr], eax
and [esi + rx_desc.pkt_status], 0
mov [esi + rx_desc.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31)
@ -2704,7 +2731,7 @@ int_boomerang:
mov [ebx + device.curr_rx], esi
DEBUGF 1, "Next RX desc: %x\n", esi
jmp [Eth_input]
jmp [EthInput]
.loop:
mov ebx, [esp]
@ -2742,7 +2769,7 @@ int_boomerang:
and [esi+tx_desc.frame_start_hdr], 0
push ecx
invoke KernelFree, [esi+tx_desc.realaddr]
invoke NetFree, [esi+tx_desc.realaddr]
pop ecx
.maybenext:

View File

@ -137,7 +137,7 @@ PHY_ST = 0x8A ; PHY status register
MAC_SM = 0xAC ; MAC status machine
MAC_ID = 0xBE ; Identifier register
MAX_BUF_SIZE = 0x600 ; 1536
MAX_BUF_SIZE = 1514
MBCR_DEFAULT = 0x012A ; MAC Bus Control Register
MCAST_MAX = 3 ; Max number multicast addresses to filter
@ -396,13 +396,12 @@ unload:
;
; - Stop the device
; - Detach int handler
; - Remove device from local list (RTL8139_LIST)
; - Remove device from local list (device_list)
; - call unregister function in kernel
; - Remove all allocated structures and buffers the card used
or eax,-1
ret
or eax, -1
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -430,7 +429,7 @@ probe:
jnz @f
mov ax, 0x9F07
out dx, ax
@@:
@@:
call read_mac
@ -441,7 +440,7 @@ probe:
jnz @f
DEBUGF 2, "MAC address not initialized!\n"
@@:
@@:
; Init RDC private data
mov [ebx + device.mcr0], MCR0_XMTEN or MCR0_RCVEN
mov [ebx + device.phy_addr], PHY1_ADDR
@ -452,9 +451,10 @@ probe:
cmp ax, 0xFFFF
jne @f
DEBUGF 2, "Failed to detect an attached PHY!\n"
.err:
mov eax, -1
ret
@@:
@@:
; Set MAC address
call init_mac_regs
@ -462,6 +462,8 @@ probe:
; Initialize and alloc RX/TX buffers
call init_txbufs
call init_rxbufs
test eax, eax
jnz .err
; Read the PHY ID
mov [ebx + device.phy_mode], MCR0_FD
@ -471,7 +473,7 @@ probe:
jne @f
stdcall phy_write, 29, 31, 0x175C ; Enable registers
jmp .phy_readen
@@:
@@:
; PHY Mode Check
stdcall phy_write, [ebx + device.phy_addr], 4, PHY_CAP
@ -487,7 +489,7 @@ probe:
mov [ebx + device.phy_mode], 0
end if
.phy_readen:
.phy_readen:
; Set duplex mode
mov ax, [ebx + device.phy_mode]
@ -530,7 +532,7 @@ reset:
DEBUGF 2,"Could not attach int handler!\n"
or eax, -1
ret
@@:
@@:
;Reset RDC MAC
mov eax, MAC_RST
@ -632,7 +634,7 @@ init_txbufs:
invoke GetPhysAddr
mov ecx, TX_RING_SIZE
.next_desc:
.next_desc:
mov [esi + x_head.ndesc], eax
mov [esi + x_head.skb_ptr], 0
mov [esi + x_head.status], DSC_OWNER_MAC
@ -660,21 +662,21 @@ init_rxbufs:
mov edx, eax
mov ecx, RX_RING_SIZE
.next_desc:
.next_desc:
mov [esi + x_head.ndesc], edx
push esi ecx edx
invoke KernelAlloc, MAX_BUF_SIZE
invoke NetAlloc, MAX_BUF_SIZE+NET_BUFF.data
pop edx ecx esi
test eax, eax
jz .out_of_mem
mov [esi + x_head.skb_ptr], eax
invoke GetPhysAddr
add eax, NET_BUFF.data
mov [esi + x_head.buf], eax
mov [esi + x_head.status], DSC_OWNER_MAC
add edx, sizeof.x_head
add esi, sizeof.x_head
dec ecx
jnz .next_desc
@ -683,6 +685,11 @@ init_rxbufs:
invoke GetPhysAddr
mov dword[ebx + device.rx_ring + sizeof.x_head*(RX_RING_SIZE-1) + x_head.ndesc], eax
xor eax, eax
ret
.out_of_mem:
or eax, -1
ret
@ -734,21 +741,22 @@ phy_mode_chk:
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
proc transmit stdcall bufferptr, buffersize
proc transmit stdcall bufferptr
pushf
cli
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
mov eax, [bufferptr]
mov esi, [bufferptr]
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
lea eax, [esi + NET_BUFF.data]
DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
[eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
[eax+13]:2,[eax+12]:2
cmp [buffersize], 1514
cmp [esi + NET_BUFF.length], 1514
ja .fail
cmp [buffersize], 60
cmp [esi + NET_BUFF.length], 60
jb .fail
movzx edi, [ebx + device.cur_tx]
@ -764,11 +772,12 @@ proc transmit stdcall bufferptr, buffersize
.do_send:
DEBUGF 1,"Sending now\n"
mov eax, [bufferptr]
mov [edi + x_head.skb_ptr], eax
mov [edi + x_head.skb_ptr], esi
mov eax, esi
add eax, [eax + NET_BUFF.offset]
invoke GetPhysAddr
mov [edi + x_head.buf], eax
mov ecx, [buffersize]
mov ecx, [esi + NET_BUFF.length]
mov [edi + x_head.len], cx
mov [edi + x_head.status], DSC_OWNER_MAC
@ -783,7 +792,7 @@ proc transmit stdcall bufferptr, buffersize
; Update stats
inc [ebx + device.packets_tx]
mov eax, [buffersize]
mov eax, [esi + NET_BUFF.length]
add dword[ebx + device.bytes_tx], eax
adc dword[ebx + device.bytes_tx + 4], 0
@ -793,22 +802,25 @@ proc transmit stdcall bufferptr, buffersize
.wait_to_send:
DEBUGF 1,"Waiting for TX buffer\n"
invoke GetTimerTicks ; returns in eax
lea edx, [eax + 100]
.l2:
.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 KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
@ -890,26 +902,29 @@ int_handler:
and ecx, 0xFFF
sub ecx, 4 ; Do not count the CRC
DEBUGF 1,"packet ptr=0x%x size=%u\n", [edx + x_head.skb_ptr], ecx
; Update stats
add dword[ebx + device.bytes_rx], ecx
adc dword[ebx + device.bytes_rx + 4], 0
inc dword[ebx + device.packets_rx]
; Push packet size and pointer, kernel will need it..
push ebx
; Push packet ptr and return addr for Eth_input
push .more_RX
mov eax, [edx + x_head.skb_ptr]
push eax
mov [eax + NET_BUFF.length], ecx
mov [eax + NET_BUFF.device], ebx
mov [eax + NET_BUFF.offset], NET_BUFF.data
push ecx
push [edx + x_head.skb_ptr]
DEBUGF 1,"packet ptr=0x%x\n", [edx + x_head.skb_ptr]
; reset the RX descriptor
; reset the RX descriptor (alloc new buffer)
push edx
invoke KernelAlloc, MAX_BUF_SIZE
invoke NetAlloc, MAX_BUF_SIZE+NET_BUFF.data
pop edx
mov [edx + x_head.skb_ptr], eax
invoke GetPhysAddr
add eax, NET_BUFF.data
mov [edx + x_head.buf], eax
mov [edx + x_head.status], DSC_OWNER_MAC
@ -918,15 +933,14 @@ int_handler:
and [ebx + device.cur_rx], RX_RING_SIZE - 1
; At last, send packet to kernel
jmp [Eth_input]
jmp [EthInput]
.no_RX:
test word[esp], TX_FINISH
jz .no_TX
.loop_tx:
.loop_tx:
movzx edi, [ebx + device.last_tx]
shl edi, 5
lea edi, [ebx + device.tx_ring + edi]
@ -941,7 +955,7 @@ int_handler:
push [edi + x_head.skb_ptr]
mov [edi + x_head.skb_ptr], 0
invoke KernelFree
invoke NetFree
inc [ebx + device.last_tx]
and [ebx + device.last_tx], TX_RING_SIZE - 1
@ -1106,13 +1120,13 @@ read_mac:
lea edi, [ebx + device.mac]
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], MID_0L
.mac:
.loop:
in ax, dx
stosw
inc dx
inc dx
dec cx
jnz .mac
jnz .loop
DEBUGF 1,"%x-%x-%x-%x-%x-%x\n",\
[edi-6]:2, [edi-5]:2, [edi-4]:2, [edi-3]:2, [edi-2]:2, [edi-1]:2

View File

@ -665,17 +665,18 @@ reset:
;***************************************************************************
; Function
; transmit
; buffer in [esp+4], size in [esp+8], pointer to device struct in ebx
; buffer in [esp+4], pointer to device struct in ebx
;***************************************************************************
proc transmit stdcall buffer_ptr, buffer_size
proc transmit stdcall buffer_ptr
pushf
cli
mov esi, [buffer_ptr]
mov ecx, [buffer_size]
DEBUGF 1, "Transmitting packet, buffer:%x, size:%u\n", esi, ecx
mov ecx, [esi + NET_BUFF.length]
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", esi, ecx
lea eax, [esi + NET_BUFF.data]
DEBUGF 1, "To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
[esi+0]:2,[esi+1]:2,[esi+2]:2,[esi+3]:2,[esi+4]:2,[esi+5]:2,[esi+6]:2,[esi+7]:2,[esi+8]:2,[esi+9]:2,[esi+10]:2,[esi+11]:2,[esi+13]:2,[esi+12]:2
@ -686,9 +687,10 @@ proc transmit stdcall buffer_ptr, buffer_size
movzx edi, [ebx + device.tx_start]
shl edi, 8
push cx
add esi, [esi + NET_BUFF.offset]
push ecx
call PIO_write
pop cx
pop ecx
set_io [ebx + device.io_addr], 0
; set_io [ebx + device.io_addr], P0_COMMAND
@ -714,18 +716,17 @@ proc transmit stdcall buffer_ptr, buffer_size
DEBUGF 1, "Packet Sent!\n"
inc [ebx + device.packets_tx]
mov eax, [buffer_size]
add dword[ebx + device.bytes_tx], eax
add dword[ebx + device.bytes_tx], ecx
adc dword[ebx + device.bytes_tx + 4], 0
invoke KernelFree, [buffer_ptr]
invoke NetFree, [buffer_ptr]
popf
xor eax, eax
ret
.err:
DEBUGF 2, "Transmit error!\n"
invoke KernelFree, [buffer_ptr]
invoke NetFree, [buffer_ptr]
popf
or eax, -1
ret
@ -785,14 +786,15 @@ int_handler:
jz .no_rx ; FIXME: Only PIO mode supported for now
; allocate a buffer
invoke KernelAlloc, ETH_FRAME_LEN
invoke NetAlloc, ETH_FRAME_LEN+NET_BUFF.data
test eax, eax
jz .rx_fail_2
; Push return address and packet ptr to stack
pushd .no_rx
pushd 0 ; Reserve some space for the packet size
push eax
mov [eax + NET_BUFF.device], ebx
mov [eax + NET_BUFF.offset], NET_BUFF.data
; read offset for current packet from device
set_io [ebx + device.io_addr], 0
@ -809,7 +811,7 @@ int_handler:
mov al, CMD_PS1
out dx, al
set_io [ebx + device.io_addr], P1_CURR
in al, dx ; get current page in cl
in al, dx ; get current page in cl
mov cl, al
set_io [ebx + device.io_addr], P1_COMMAND
@ -823,11 +825,11 @@ int_handler:
cmp cl, ch
je .rx_fail
movzx esi, ch ; we are using 256 byte pages
shl esi, 8 ; esi now holds the offset for current packet
movzx esi, ch ; we are using 256 byte pages
shl esi, 8 ; esi now holds the offset for current packet
; Get packet header in ecx
push ecx ; reserve 4 bytes on stack to put packet header in
; Write packet header to frame header size field
push ecx
mov edi, esp
mov cx, 4
call PIO_read
@ -839,8 +841,9 @@ int_handler:
; calculate packet length in ecx
shr ecx, 16
sub ecx, 4 ; CRC doesnt count as data byte
mov [esp + 8], ecx
sub ecx, 4 ; CRC doesnt count as data byte
mov edi, [esp+4]
mov [edi + NET_BUFF.length], ecx
; check if packet size is ok
cmp ecx, ETH_ZLEN
@ -856,7 +859,7 @@ int_handler:
; update read and write pointers
add esi, 4
mov edi, [esp + 4]
add edi, NET_BUFF.data
; now check if we can read all data at once (if we cross the end boundary, we need to wrap back to the beginning)
xor eax, eax
@ -894,7 +897,7 @@ int_handler:
out dx, al
; now send the data to the kernel
jmp [Eth_input]
jmp [EthInput]
.rx_fail_3:
add esp, 4

View File

@ -404,8 +404,7 @@ unload:
; - Remove all allocated structures and buffers the card used
or eax, -1
ret
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -628,27 +627,26 @@ reset:
;; ;;
;; Transmit ;;
;; ;;
;; In: buffer pointer in [esp+4] ;;
;; size of buffer in [esp+8] ;;
;; pointer to device structure in ebx ;;
;; In: pointer to device structure in ebx ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
proc transmit stdcall bufferptr, buffersize
proc transmit stdcall bufferptr
pushf
cli
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
mov eax, [bufferptr]
mov esi, [bufferptr]
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
lea eax, [esi + NET_BUFF.data]
DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
[eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
[eax+13]:2,[eax+12]:2
cmp [buffersize], 1514
cmp [esi + NET_BUFF.length], 1514
ja .fail
cmp [buffersize], 60
cmp [esi + NET_BUFF.length], 60
jb .fail
; check if we own the current discriptor
@ -662,29 +660,30 @@ proc transmit stdcall bufferptr, buffersize
jz .wait_to_send
.send_packet:
; Set the buffer address
set_io [ebx + device.io_addr], REG_TSAD0
mov [ebx + device.TX_DESC+ecx], esi
mov eax, esi
add eax, [eax + NET_BUFF.offset]
invoke GetPhysAddr
out dx, eax
; And the size of the buffer
set_io [ebx + device.io_addr], REG_TSD0
mov eax, [esi + NET_BUFF.length]
or eax, (ERTXTH shl BIT_ERTXTH) ; Early threshold
out dx, eax
; get next descriptor
inc [ebx + device.curr_tx_desc]
and [ebx + device.curr_tx_desc], NUM_TX_DESC-1
; Update stats
inc [ebx + device.packets_tx]
mov eax, [buffersize]
add dword [ebx + device.bytes_tx], eax
mov ecx, [esi + NET_BUFF.length]
add dword [ebx + device.bytes_tx], ecx
adc dword [ebx + device.bytes_tx+4], 0
; Set the buffer address
set_io [ebx + device.io_addr], REG_TSAD0
mov eax, [bufferptr]
mov [ebx + device.TX_DESC+ecx], eax
invoke GetPhysAddr
out dx, eax
; And the size of the buffer
set_io [ebx + device.io_addr], REG_TSD0
mov eax, [buffersize]
or eax, (ERTXTH shl BIT_ERTXTH) ; Early threshold
out dx, eax
DEBUGF 1, "Packet Sent!\n"
popf
xor eax, eax
@ -710,7 +709,7 @@ proc transmit stdcall bufferptr, buffersize
.fail:
DEBUGF 2, "transmit failed!\n"
invoke KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
@ -795,18 +794,21 @@ int_handler:
DEBUGF 1, "Received %u bytes\n", ecx
push ebx eax ecx
invoke KernelAlloc, ecx ; Allocate a buffer to put packet into
add ecx, NET_BUFF.data
invoke NetAlloc, ecx ; Allocate a buffer to put packet into
pop ecx
test eax, eax ; Test if we allocated succesfully
jz .abort
mov [eax + NET_BUFF.length], ecx
mov [eax + NET_BUFF.device], ebx
mov [eax + NET_BUFF.offset], NET_BUFF.data
mov edi, eax ; Where we will copy too
lea edi, [eax + NET_BUFF.data] ; Where we will copy too
mov esi, [esp] ; The buffer we will copy from
add esi, 4 ; Dont copy CRC
push dword .abort ; Kernel will return to this address after EthReceiver
push ecx edi ; Save buffer pointer and size, to pass to kernel
push .abort ; return addr for Eth_input
push eax ; buffer ptr for Eth_input
.copy:
shr ecx, 1
@ -821,7 +823,7 @@ int_handler:
rep movsd
.nd:
jmp [Eth_input] ; Send it to kernel
jmp [EthInput] ; Send it to kernel
.abort:
pop eax ebx
@ -923,7 +925,7 @@ int_handler:
.no_tok:
DEBUGF 1, "free transmit buffer 0x%x\n", [ebx + device.TX_DESC+ecx]:8
push ecx ebx
invoke KernelFree, [ebx + device.TX_DESC+ecx]
invoke NetFree, [ebx + device.TX_DESC+ecx]
pop ebx ecx
mov [ebx + device.TX_DESC+ecx], 0

View File

@ -175,10 +175,10 @@ include '../netdrv.inc'
DSB_FSbit = 0x20000000
DSB_LSbit = 0x10000000
RX_BUF_SIZE = 1536 ; Rx Buffer size
RX_BUF_SIZE = 1514 ; Rx Buffer size
; max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4)
MAX_ETH_FRAME_SIZE = 1536
MAX_ETH_FRAME_SIZE = 1514
TX_FIFO_THRESH = 256 ; In bytes
@ -200,7 +200,7 @@ include '../netdrv.inc'
ETH_HDR_LEN = 14
DEFAULT_MTU = 1500
DEFAULT_RX_BUF_LEN = 1536
DEFAULT_RX_BUF_LEN = 1514
;ifdef JUMBO_FRAME_SUPPORT
@ -662,6 +662,9 @@ reset:
DEBUGF 1,"resetting\n"
call init_ring
test eax, eax
jnz .err
call hw_start
; clear packet/byte counters
@ -678,7 +681,10 @@ reset:
xor eax, eax
ret
.err:
DEBUGF 2,"failed!\n"
or eax, -1
ret
@ -800,9 +806,12 @@ init_ring:
mov ecx, NUM_RX_DESC
.loop:
push ecx
invoke KernelAlloc, RX_BUF_SIZE
invoke NetAlloc, RX_BUF_SIZE+NET_BUFF.data
test eax, eax
jz .err
mov dword [edi + rx_desc.buf_soft_addr], eax
invoke GetPhysAddr
add eax, NET_BUFF.data
mov dword [edi + rx_desc.buf_addr], eax
mov [edi + rx_desc.status], DSB_OWNbit or RX_BUF_SIZE
add edi, sizeof.rx_desc
@ -811,8 +820,13 @@ init_ring:
jnz .loop
or [edi - sizeof.rx_desc + rx_desc.status], DSB_EORbit
xor eax, eax
ret
.err:
pop eax
or eax, -1
ret
align 4
hw_start:
@ -990,21 +1004,22 @@ write_mac:
;
;***************************************************************************
proc transmit stdcall bufferptr, buffersize
proc transmit stdcall bufferptr
pushf
cli
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
mov eax, [bufferptr]
mov esi, [bufferptr]
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
lea eax, [esi + NET_BUFF.data]
DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
[eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
[eax+13]:2,[eax+12]:2
cmp [buffersize], 1514
cmp [esi + NET_BUFF.length], 1514
ja .fail
cmp [buffersize], 60
cmp [esi + NET_BUFF.length], 60
jb .fail
;----------------------------------
@ -1026,15 +1041,16 @@ proc transmit stdcall bufferptr, buffersize
; Program the packet pointer
mov eax, [bufferptr]
mov ecx, [eax + NET_BUFF.length]
mov [esi + tx_desc.buf_soft_addr], eax
add eax, [eax + NET_BUFF.offset]
invoke GetPhysAddr
mov dword [esi + tx_desc.buf_addr], eax
;------------------------
; Program the packet size
mov eax, [buffersize]
@@:
mov eax, ecx
or eax, DSB_OWNbit or DSB_FSbit or DSB_LSbit
cmp [ebx + device.cur_tx], NUM_TX_DESC - 1
jne @f
@ -1060,8 +1076,7 @@ proc transmit stdcall bufferptr, buffersize
; Update stats
inc [ebx + device.packets_tx]
mov eax, [buffersize]
add dword [ebx + device.bytes_tx], eax
add dword [ebx + device.bytes_tx], ecx
adc dword [ebx + device.bytes_tx + 4], 0
popf
@ -1072,7 +1087,7 @@ proc transmit stdcall bufferptr, buffersize
DEBUGF 2,"Descriptor is still in use!\n"
.fail:
DEBUGF 2,"Transmit failed\n"
invoke KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
@ -1139,38 +1154,44 @@ int_handler:
lea esi, [ebx + device.rx_ring + eax]
DEBUGF 1,"RxDesc.status = 0x%x\n", [esi + rx_desc.status]
mov eax, [esi + rx_desc.status]
test eax, DSB_OWNbit ;;;
jnz .no_own
mov ecx, [esi + rx_desc.status]
test ecx, DSB_OWNbit ;;;
jnz .rx_return
DEBUGF 1,"cur_rx = %u\n", [ebx + device.cur_rx]
test eax, SD_RxRES
test ecx, SD_RxRES
jnz .rx_return ;;;;; RX error!
push ebx
push .check_more
and eax, 0x00001FFF
add eax, -4 ; we dont need CRC
and ecx, 0x00001FFF
add ecx, -4 ; we dont need CRC
DEBUGF 1,"data length = %u\n", ecx
mov eax, [esi + rx_desc.buf_soft_addr]
push eax
DEBUGF 1,"data length = %u\n", ax
mov [eax + NET_BUFF.length], ecx
mov [eax + NET_BUFF.device], ebx
mov [eax + NET_BUFF.offset], NET_BUFF.data
; Update stats
;-------------
; Update stats
add dword [ebx + device.bytes_rx], eax
adc dword [ebx + device.bytes_rx + 4], 0
inc [ebx + device.packets_rx]
pushd [esi + rx_desc.buf_soft_addr]
;----------------------
; Allocate a new buffer
; Allocate a new buffer
invoke KernelAlloc, RX_BUF_SIZE
invoke NetAlloc, RX_BUF_SIZE+NET_BUFF.data
mov [esi + rx_desc.buf_soft_addr], eax
invoke GetPhysAddr
add eax, NET_BUFF.data
mov dword [esi + rx_desc.buf_addr], eax
; reset OWN bit
;---------------
; re set OWN bit
mov eax, DSB_OWNbit or RX_BUF_SIZE
cmp [ebx + device.cur_rx], NUM_RX_DESC - 1
@ -1179,15 +1200,15 @@ int_handler:
@@:
mov [esi + rx_desc.status], eax
; Update rx ptr
;--------------
; Update rx ptr
inc [ebx + device.cur_rx]
and [ebx + device.cur_rx], NUM_RX_DESC - 1
jmp [Eth_input]
jmp [EthInput]
.rx_return:
DEBUGF 1,"RX error!\n"
.no_own:
pop ax
.no_rx:
@ -1196,30 +1217,31 @@ int_handler:
test ax, ISB_TxOK or ISB_TxErr or ISB_TxDescUnavail
jz .no_tx
push ax
DEBUGF 1,"TX done!\n"
.txloop:
mov esi, [ebx + device.last_tx]
imul esi, sizeof.tx_desc
lea esi, [ebx + device.tx_ring + esi]
mov ecx, NUM_TX_DESC
lea esi, [ebx + device.tx_ring]
.txloop:
cmp dword [esi + tx_desc.buf_soft_addr], 0
je .no_tx
jz .maybenext
test [esi + tx_desc.status], DSB_OWNbit
jnz .no_tx
jnz .maybenext
DEBUGF 1,"Freeing up TX desc: 0x%x\n", esi
DEBUGF 1,"buff: 0x%x\n", [esi + tx_desc.buf_soft_addr]
push eax
push dword [esi + tx_desc.buf_soft_addr]
push ecx
DEBUGF 1,"Freeing up TX desc: %x\n", esi
invoke NetFree, [esi + tx_desc.buf_soft_addr]
pop ecx
and dword [esi + tx_desc.buf_soft_addr], 0
invoke KernelFree
pop eax
inc [ebx + device.last_tx]
and [ebx + device.last_tx], NUM_TX_DESC-1
jmp .txloop
.maybenext:
add esi, sizeof.tx_desc
dec ecx
jnz .txloop
pop ax
.no_tx:
test ax, ISB_LinkChg
@ -1333,10 +1355,10 @@ dd 0x7cf00000, 0x28800000, 27, name_27
dd 0x7cf00000, 0x28a00000, 28, name_27
; 8168C family.
dd 0x7cf00000, 0x3cb00000, 24, name_23
dd 0x7cf00000, 0x3c900000, 23, name_23
dd 0x7cf00000, 0x3cb00000, 24, name_18
dd 0x7cf00000, 0x3c900000, 23, name_18
dd 0x7cf00000, 0x3c800000, 18, name_18
dd 0x7c800000, 0x3c800000, 24, name_23
dd 0x7c800000, 0x3c800000, 24, name_18
dd 0x7cf00000, 0x3c000000, 19, name_19
dd 0x7cf00000, 0x3c200000, 20, name_19
dd 0x7cf00000, 0x3c300000, 21, name_19
@ -1401,7 +1423,7 @@ name_19 db "RTL8168c/8111c",0
;name_20 db "RTL8168c/8111c",0
;name_21 db "RTL8168c/8111c",0
;name_22 db "RTL8168c/8111c",0
name_23 db "RTL8168cp/8111cp",0
;name_23 db "RTL8168cp/8111cp",0
;name_24 db "RTL8168cp/8111cp",0
name_25 db "RTL8168d/8111d",0
;name_26 db "RTL8168d/8111d",0

View File

@ -594,8 +594,6 @@ reset:
@@:
;;; Find connected mii xceivers? 993-1043
; Reset the xcvr interface and turn on heartbeat.
cmp [ebx + device.id], DC21041
jne @f
@ -869,19 +867,23 @@ init_ring:
DEBUGF 1,"RX descriptor 0x%x\n", edi
add edx, sizeof.desc
mov [edi + desc.status], DES0_OWN
mov [edi + desc.length], 1536
mov [edi + desc.length], 1514
push edx edi ecx
invoke KernelAlloc, 1536
invoke NetAlloc, 1514+NET_BUFF.data
pop ecx edi edx
test eax, eax
jz .out_of_mem
mov [edi + RX_RING_SIZE*sizeof.desc], eax
push edx
invoke GetPhysAddr
add eax, NET_BUFF.data
pop edx
mov [edi + desc.buffer1], eax
mov [edi + desc.buffer2], edx
add edi, sizeof.desc
dec ecx
jnz .loop_rx_des
; set last descriptor as LAST
or [edi - sizeof.desc + desc.length], RDES1_RER ; EndOfRing
pop [edi - sizeof.desc + desc.buffer2] ; point it to the first descriptor
@ -917,6 +919,7 @@ init_ring:
mov [ebx + device.last_tx], eax
mov [ebx + device.cur_rx], eax
; xor eax, eax
ret
.out_of_mem:
@ -1043,13 +1046,15 @@ create_setup_frame:
DEBUGF 1,"Creating setup packet\n"
invoke KernelAlloc, 192
invoke NetAlloc, 192 + NET_BUFF.data
test eax, eax
jz .err
mov [eax + NET_BUFF.device], ebx
mov [eax + NET_BUFF.length], 192
push eax
mov edi, eax
lea edi, [eax + NET_BUFF.data]
xor eax, eax
dec ax
stosd
@ -1071,18 +1076,22 @@ create_setup_frame:
DEBUGF 1, "attaching setup packet 0x%x to descriptor 0x%x\n", eax, edi
mov [edi + TX_RING_SIZE*sizeof.desc], eax
invoke GetPhysAddr
add eax, NET_BUFF.data
mov [edi + desc.buffer1], eax
mov [edi + desc.length], TDES1_SET + 192 ; size must be EXACTLY 192 bytes + TDES1_IC
mov [edi + desc.length], TDES1_SET or 192 ; size must be EXACTLY 192 bytes + TDES1_IC
mov [edi + desc.status], DES0_OWN
DEBUGF 1, "descriptor 0x%x\n", edi
; go to next descriptor
inc [ebx + device.cur_tx]
and [ebx + device.cur_tx], TX_RING_SIZE-1
xor eax, eax
ret
.err:
DEBUGF 2, "Out of memory!\n"
or eax, -1
ret
@ -1091,50 +1100,51 @@ create_setup_frame:
;; ;;
;; Transmit ;;
;; ;;
;; In: buffer pointer in [esp+4] ;;
;; size of buffer in [esp+8] ;;
;; pointer to device structure in ebx ;;
;; In: ebx = pointer to device structure ;;
;; Out: eax = 0 on success ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
proc transmit stdcall bufferptr, buffersize
proc transmit stdcall bufferptr
pushf
cli
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
mov eax, [bufferptr]
mov esi, [bufferptr]
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
lea eax, [esi + NET_BUFF.data]
DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
[eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
[eax+13]:2,[eax+12]:2
cmp [buffersize], 1514
cmp [esi + NET_BUFF.length], 1514
ja .fail
cmp [esi + NET_BUFF.length], 60
jb .fail
mov eax, [ebx + device.cur_tx]
mov edx, sizeof.desc
mul edx
lea esi, [ebx + device.tx_ring + eax]
test [esi + desc.status], DES0_OWN
lea edi, [ebx + device.tx_ring + eax]
test [edi + desc.status], DES0_OWN
jnz .fail
DEBUGF 1, "Descriptor is free\n"
mov eax, [bufferptr]
mov [esi + TX_RING_SIZE*sizeof.desc], eax
mov [edi + TX_RING_SIZE*sizeof.desc], eax
add eax, [eax + NET_BUFF.offset]
invoke GetPhysAddr
mov [esi + desc.buffer1], eax
mov [edi + desc.buffer1], eax
; set packet size
mov eax, [esi + desc.length]
mov eax, [edi + desc.length]
and eax, TDES1_TER ; preserve 'End of Ring' bit
or eax, [buffersize] ; set size
or eax, [esi + NET_BUFF.length] ; set size
or eax, TDES1_FS or TDES1_LS or TDES1_IC ; first descr, last descr, interrupt on complete
mov [esi + desc.length], eax
mov [edi + desc.length], eax
; set descriptor status
mov [esi + desc.status], DES0_OWN ; say it is now owned by the 21x4x
mov [edi + desc.status], DES0_OWN ; say it is now owned by the 21x4x
; Check if transmitter is running
set_io [ebx + device.io_addr], 0
@ -1155,8 +1165,8 @@ proc transmit stdcall bufferptr, buffersize
; Update stats
inc [ebx + device.packets_tx]
mov eax, [buffersize]
add dword [ebx + device.bytes_tx], eax
mov ecx, [esi + NET_BUFF.length]
add dword [ebx + device.bytes_tx], ecx
adc dword [ebx + device.bytes_tx + 4], 0
; go to next descriptor
@ -1169,8 +1179,8 @@ proc transmit stdcall bufferptr, buffersize
ret
.fail:
DEBUGF 2,"Transmit failed\n"
invoke KernelFree, [bufferptr]
DEBUGF 1,"Transmit failed\n"
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
@ -1240,8 +1250,8 @@ int_handler:
je .end_tx
mov [eax + desc.buffer1], 0
DEBUGF 1,"Free buffer 0x%x\n", [eax + TX_RING_SIZE*sizeof.desc]
invoke KernelFree, [eax + TX_RING_SIZE*sizeof.desc]
DEBUGF 1, "Free buffer 0x%x\n", [eax + TX_RING_SIZE*sizeof.desc]
invoke NetFree, [eax + TX_RING_SIZE*sizeof.desc]
; advance to next descriptor
inc [ebx + device.last_tx]
@ -1254,7 +1264,6 @@ int_handler:
;----------------------------------
; RX irq
test eax, CSR5_RI
jz .not_rx
push eax esi ecx
@ -1265,13 +1274,13 @@ int_handler:
.rx_loop:
pop ebx
; get current descriptor
; get current descriptor
mov eax, [ebx + device.cur_rx]
mov edx, sizeof.desc
mul edx
lea edi, [ebx + device.rx_ring + eax]
; Check current RX descriptor status
; now check status
mov eax, [edi + desc.status]
test eax, DES0_OWN
@ -1290,11 +1299,14 @@ int_handler:
sub ecx, 4 ; throw away the CRC
DEBUGF 1,"got %u bytes\n", ecx
; Push arguments for Eth_input (and some more...)
; Push arguments for EthInput (and some more...)
push ebx
push .rx_loop ; return addr
push ecx ; packet size
push dword[edi + RX_RING_SIZE*sizeof.desc] ; packet ptr
mov eax, dword[edi + RX_RING_SIZE*sizeof.desc]
push eax
mov [eax + NET_BUFF.length], ecx
mov [eax + NET_BUFF.device], ebx
mov [eax + NET_BUFF.offset], NET_BUFF.data
; update statistics
inc [ebx + device.packets_rx]
@ -1303,10 +1315,12 @@ int_handler:
; Allocate new descriptor
push edi ebx
invoke KernelAlloc, 1536 ; Allocate a buffer to put packet into
invoke NetAlloc, 1514 + NET_BUFF.data ; Allocate a buffer to put packet into
pop ebx edi
jz .fail
mov [edi + RX_RING_SIZE*sizeof.desc], eax
invoke GetPhysAddr
add eax, NET_BUFF.data
mov [edi + desc.buffer1], eax
mov [edi + desc.status], DES0_OWN ; mark descriptor as being free
@ -1314,8 +1328,10 @@ int_handler:
inc [ebx + device.cur_rx] ; next descriptor
and [ebx + device.cur_rx], RX_RING_SIZE-1
jmp [Eth_input]
jmp [EthInput]
.end_rx:
.fail:
pop ecx esi eax
.not_rx:
pop edi esi ebx

View File

@ -35,7 +35,7 @@ entry START
MAX_DEVICES = 16
RBLEN = 0 ; Receive buffer size: 0=4K 1=8k 2=16k 3=32k 4=64k
; FIXME: option 1 and 2 will not allocate buffer correctly causing data loss!
; FIXME: option 1 and 2 may allocate a non contiguous buffer causing data loss!
DEBUG = 1
__DEBUG__ = 1
@ -1371,7 +1371,7 @@ align 4
init_ring:
DEBUGF 1,"init rings\n"
push eax esi ecx
push esi ecx
mov [ebx + device.cur_tx], 0
mov [ebx + device.last_tx], 0
@ -1392,10 +1392,13 @@ init_ring:
lea esi, [ebx + device.rx_ring]
.rx_loop:
push ecx esi
invoke KernelAlloc, 4096 shl RBLEN ; push/pop esi not needed, but just in case...
invoke NetAlloc, (4096 shl RBLEN) + NET_BUFF.data ; push/pop esi not needed, but just in case...
pop esi
test eax, eax
jz .out_of_mem
mov [esi + RX_RING*sizeof.RxDesc], eax
invoke GetPhysAddr
add eax, NET_BUFF.data
mov [esi + RxDesc.PacketBuffer], eax
mov [esi + RxDesc.FlagLen], (4096 shl RBLEN or NV_RX_AVAIL)
add esi, sizeof.RxDesc
@ -1403,8 +1406,14 @@ init_ring:
dec ecx
jnz .rx_loop
pop ecx esi eax
pop ecx esi
xor eax, eax
ret
.out_of_mem:
add esp, 12
or eax, -1
ret
@ -1781,41 +1790,42 @@ read_mac:
;; Transmit ;;
;; ;;
;; In: buffer pointer in [esp+4] ;;
;; size of buffer in [esp+8] ;;
;; pointer to device structure in ebx ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
proc transmit stdcall bufferptr, buffersize
proc transmit stdcall bufferptr
pushf
cli
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
mov eax, [bufferptr]
mov esi, [bufferptr]
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
lea eax, [esi + NET_BUFF.data]
DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
[eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
[eax+13]:2,[eax+12]:2
cmp [buffersize], 1514
cmp [esi + NET_BUFF.length], 1514
ja .fail
cmp [buffersize], 60
cmp [esi + NET_BUFF.length], 60
jb .fail
; get the descriptor address
mov eax, [ebx + device.cur_tx]
shl eax, 3 ; TX descriptor is 8 bytes.
lea esi, [ebx + device.tx_ring + eax]
lea edi, [ebx + device.tx_ring + eax]
mov eax, [bufferptr]
mov [esi + TX_RING*sizeof.TxDesc], eax
mov [edi + TX_RING*sizeof.TxDesc], eax
add eax, [eax + NET_BUFF.offset]
invoke GetPhysAddr ; Does not change esi/ebx :)
mov [esi + TxDesc.PacketBuffer], eax
mov [edi + TxDesc.PacketBuffer], eax
mov eax, [buffersize]
or eax, [ebx + device.txflags]
mov [esi + TxDesc.FlagLen], eax
mov ecx, [esi + NET_BUFF.length]
or ecx, [ebx + device.txflags]
mov [edi + TxDesc.FlagLen], ecx
mov edi, [ebx + device.mmio_addr]
mov eax, [ebx + device.desc_ver]
@ -1829,8 +1839,7 @@ proc transmit stdcall bufferptr, buffersize
; Update stats
inc [ebx + device.packets_tx]
mov eax, [buffersize]
add dword[ebx + device.bytes_tx], eax
add dword[ebx + device.bytes_tx], ecx
adc dword[ebx + device.bytes_tx + 4], 0
popf
@ -1839,7 +1848,7 @@ proc transmit stdcall bufferptr, buffersize
.fail:
DEBUGF 2,"Send failed\n"
invoke KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
@ -1896,33 +1905,33 @@ int_handler:
mov cx, sizeof.RxDesc
mul cx
lea esi, [ebx + device.rx_ring + eax]
mov eax, [esi + RxDesc.FlagLen]
mov ecx, [esi + RxDesc.FlagLen]
test eax, NV_RX_AVAIL ; still owned by hardware
test ecx, NV_RX_AVAIL ; still owned by hardware
jnz .no_rx
cmp [ebx + device.desc_ver], DESC_VER_1
jne @f
test eax, NV_RX_DESCRIPTORVALID
test ecx, NV_RX_DESCRIPTORVALID
jz .no_rx
jmp .next
@@:
test eax, NV_RX2_DESCRIPTORVALID
test ecx, NV_RX2_DESCRIPTORVALID
jz .no_rx
.next:
cmp dword[ebx + device.desc_ver], DESC_VER_1
jne @f
and eax, LEN_MASK_V1
and ecx, LEN_MASK_V1
jmp .next2
@@:
and eax, LEN_MASK_V2
and ecx, LEN_MASK_V2
.next2:
DEBUGF 1,"Received %u bytes\n", eax
DEBUGF 1,"Received %u bytes\n", ecx
; Update stats
add dword[ebx + device.bytes_rx], eax
add dword[ebx + device.bytes_rx], ecx
adc dword[ebx + device.bytes_rx + 4], 0
inc dword[ebx + device.packets_rx]
@ -1930,14 +1939,18 @@ int_handler:
push ebx
push .more_rx
mov eax, [esi + RX_RING*sizeof.RxDesc]
push eax
push dword[esi + RX_RING*sizeof.RxDesc]
mov [eax + NET_BUFF.device], ebx
mov [eax + NET_BUFF.length], ecx
mov [eax + NET_BUFF.offset], NET_BUFF.data
DEBUGF 1,"packet ptr=0x%x\n", [esi + RX_RING*sizeof.RxDesc]
; Allocate new buffer for this descriptor
invoke KernelAlloc, 4096 shl RBLEN
invoke NetAlloc, (4096 shl RBLEN) + NET_BUFF.data
mov [esi + RX_RING*sizeof.RxDesc], eax
invoke GetPhysAddr
add eax, NET_BUFF.data
mov [esi + RxDesc.PacketBuffer], eax
mov [esi + RxDesc.FlagLen], (4096 shl RBLEN or NV_RX_AVAIL)
@ -1945,7 +1958,7 @@ int_handler:
inc [ebx + device.cur_rx]
and [ebx + device.cur_rx], (RX_RING-1)
jmp [Eth_input]
jmp [EthInput]
.no_rx:
test eax, IRQ_RX_ERROR
@ -1999,7 +2012,7 @@ int_handler:
DEBUGF 1,"Freeing buffer 0x%x\n", [esi + TX_RING*sizeof.TxDesc]:8
push dword[esi + TX_RING*sizeof.TxDesc]
mov dword[esi + TX_RING*sizeof.TxDesc], 0
invoke KernelFree
invoke NetFree
inc [ebx + device.last_tx]
and [ebx + device.last_tx], TX_RING - 1

View File

@ -472,7 +472,6 @@ unload:
; - Remove all allocated structures and buffers the card used
or eax, -1
ret
@ -560,8 +559,9 @@ init_rx:
lea edi, [ebx + device.rx_desc]
mov ecx, RX_RING_SIZE
.loop:
push ecx edi
invoke KernelAlloc, MAX_PKT_SIZE
push ecx
push edi
invoke NetAlloc, MAX_PKT_SIZE+NET_BUFF.data
test eax, eax
jz .out_of_mem
DEBUGF 1,"RX buffer: 0x%x\n", eax
@ -570,6 +570,7 @@ init_rx:
push edi
invoke GetPhysAddr
pop edi
add eax, NET_BUFF.data
mov [edi + RDESC.addr_l], eax
mov [edi + RDESC.addr_h], 0
mov [edi + RDESC.status_l], 0
@ -707,25 +708,27 @@ read_mac:
;; ;;
;; Transmit ;;
;; ;;
;; In: pointer to device structure in ebx ;;
;; In: ebx = pointer to device structure ;;
;; Out: eax = 0 on success ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
proc transmit stdcall bufferptr, buffersize
proc transmit stdcall bufferptr
pushf
cli
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
mov eax, [bufferptr]
mov esi, [bufferptr]
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
lea eax, [esi + NET_BUFF.data]
DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
[eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
[eax+13]:2,[eax+12]:2
cmp [buffersize], 1514
cmp [esi + NET_BUFF.length], 1514
ja .fail
cmp [buffersize], 60
cmp [esi + NET_BUFF.length], 60
jb .fail
; Program the descriptor (use legacy mode)
@ -733,12 +736,14 @@ proc transmit stdcall bufferptr, buffersize
DEBUGF 1, "Using TX desc: %u\n", edi
shl edi, 4 ; edi = edi * sizeof.TDESC
lea edi, [ebx + device.tx_desc + edi]
mov eax, esi
mov dword[edi + TX_RING_SIZE*sizeof.TDESC], eax ; Store the data location (for driver)
add eax, [eax + NET_BUFF.offset]
invoke GetPhysAddr
mov [edi + TDESC.addr_l], eax ; Data location (for hardware)
mov [edi + TDESC.addr_h], 0
mov ecx, [buffersize]
mov ecx, [esi + NET_BUFF.length]
or ecx, TXDESC_EOP + TXDESC_IFCS + TXDESC_RS
mov [edi + TDESC.length_cso_cmd], ecx
mov [edi + TDESC.status], 0
@ -753,7 +758,7 @@ proc transmit stdcall bufferptr, buffersize
; Update stats
inc [ebx + device.packets_tx]
mov eax, [buffersize]
mov eax, [esi + NET_BUFF.length]
add dword[ebx + device.bytes_tx], eax
adc dword[ebx + device.bytes_tx + 4], 0
@ -767,7 +772,7 @@ proc transmit stdcall bufferptr, buffersize
call clean_tx
DEBUGF 2,"Send failed\n"
invoke KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
@ -833,8 +838,11 @@ int_handler:
push .retaddr
movzx ecx, word[esi + 8] ; Get the packet length
DEBUGF 1,"got %u bytes\n", ecx
push ecx
push dword[esi + RX_RING_SIZE*sizeof.RDESC] ; Get packet pointer
mov eax, [esi + RX_RING_SIZE*sizeof.RDESC] ; Get packet pointer
push eax
mov [eax + NET_BUFF.length], ecx
mov [eax + NET_BUFF.device], ebx
mov [eax + NET_BUFF.offset], NET_BUFF.data
; Update stats
add dword[ebx + device.bytes_rx], ecx
@ -843,12 +851,13 @@ int_handler:
; Allocate new descriptor
push esi
invoke KernelAlloc, MAX_PKT_SIZE
invoke NetAlloc, MAX_PKT_SIZE+NET_BUFF.data
pop esi
test eax, eax
jz .out_of_mem
mov dword[esi + RX_RING_SIZE*sizeof.RDESC], eax
invoke GetPhysAddr
add eax, NET_BUFF.data
mov [esi + RDESC.addr_l], eax
mov [esi + RDESC.status_l], 0
mov [esi + RDESC.status_h], 0
@ -862,7 +871,7 @@ int_handler:
inc [ebx + device.cur_rx]
and [ebx + device.cur_rx], RX_RING_SIZE-1
jmp [Eth_input]
jmp [EthInput]
.out_of_mem:
DEBUGF 2,"Out of memory!\n"
@ -871,7 +880,7 @@ int_handler:
inc [ebx + device.cur_rx]
and [ebx + device.cur_rx], RX_RING_SIZE-1
jmp [Eth_input]
jmp [EthInput]
.no_rx:
;--------------
@ -918,7 +927,7 @@ clean_tx:
push ebx
push dword[edi + TX_RING_SIZE*sizeof.TDESC]
mov dword[edi + TX_RING_SIZE*sizeof.TDESC], 0
invoke KernelFree
invoke NetFree
pop ebx
inc [ebx + device.last_tx]

View File

@ -18,8 +18,6 @@
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; TODO: use separate descriptors in memory instead of placing them in front of packets!
format PE DLL native
entry START
@ -78,6 +76,8 @@ CmdTx = 0x0004
CmdTxFlex = 0x0008
Cmdsuspend = 0x4000
CmdRxFlex = 0x0008
reg_scb_status = 0
reg_scb_cmd = 2
reg_scb_ptr = 4
@ -487,6 +487,8 @@ reset:
; Create RX and TX descriptors
call create_ring
test eax, eax
jz .error
; RX start
@ -494,6 +496,7 @@ reset:
set_io [ebx + device.io_addr], reg_scb_ptr
mov eax, [ebx + device.rx_desc]
invoke GetPhysAddr
add eax, NET_BUFF.data
out dx, eax
mov ax, INT_MASK + RX_START
@ -580,6 +583,10 @@ reset:
xor eax, eax ; indicate that we have successfully reset the card
ret
.error:
or eax, -1
ret
align 4
create_ring:
@ -589,15 +596,18 @@ create_ring:
;---------------------
; build rxfd structure
invoke KernelAlloc, 2000
invoke NetAlloc, 2000
test eax, eax
jz .out_of_mem
mov [ebx + device.rx_desc], eax
mov esi, eax
invoke GetPhysAddr
mov [esi + rxfd.status], 0x0000
mov [esi + rxfd.command], 0x0000
mov [esi + rxfd.link], eax
mov [esi + rxfd.count], 0
mov [esi + rxfd.size], 1528
add eax, NET_BUFF.data
mov [esi + sizeof.NET_BUFF + rxfd.status], 0x0000
mov [esi + sizeof.NET_BUFF + rxfd.command], 0x0000
mov [esi + sizeof.NET_BUFF + rxfd.link], eax
mov [esi + sizeof.NET_BUFF + rxfd.count], 0
mov [esi + sizeof.NET_BUFF + rxfd.size], 1528
;-----------------------
; build txfd structure
@ -610,6 +620,8 @@ create_ring:
invoke GetPhysAddr
mov [ebx + device.txfd.desc_addr], eax
.out_of_mem:
ret
@ -622,33 +634,37 @@ create_ring:
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
proc transmit stdcall bufferptr, buffersize
proc transmit stdcall bufferptr
pushf
cli
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
mov eax, [bufferptr]
mov esi, [bufferptr]
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
lea eax, [esi + NET_BUFF.data]
DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
[eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
[eax+13]:2,[eax+12]:2
cmp [buffersize], 1514
cmp [esi + NET_BUFF.length], 1514
ja .fail
cmp [buffersize], 60
cmp [esi + NET_BUFF.length], 60
jb .fail
;;; TODO: check if current descriptor is in use
; fill in buffer address and size
mov eax, [bufferptr]
mov [ebx + device.last_tx_buffer], eax
add eax, [eax + NET_BUFF.offset]
invoke GetPhysAddr
mov [ebx + device.txfd.buf_addr0], eax
mov ecx, [buffersize]
mov ecx, [bufferptr]
mov ecx, [ecx + NET_BUFF.length]
mov [ebx + device.txfd.buf_size0], ecx
mov [ebx + device.txfd.status], 0
mov [ebx + device.txfd.command], Cmdsuspend + CmdTx + CmdTxFlex + 1 shl 15 ;;; EL bit
mov [ebx + device.txfd.command], Cmdsuspend + CmdTx + CmdTxFlex ;+ 1 shl 15 ;;; EL bit
; mov [txfd.count], 0x02208000 ;;;;;;;;;;;
; Inform device of the new/updated transmit descriptor
@ -666,7 +682,6 @@ proc transmit stdcall bufferptr, buffersize
; Update stats
inc [ebx + device.packets_tx]
mov ecx, [buffersize]
add dword[ebx + device.bytes_tx], ecx
adc dword[ebx + device.bytes_tx + 4], 0
@ -676,7 +691,7 @@ proc transmit stdcall bufferptr, buffersize
ret
.fail:
invoke KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
@ -738,19 +753,20 @@ int_handler:
pop ebx
mov esi, [ebx + device.rx_desc]
cmp [esi + rxfd.status], 0 ; we could also check bits C and OK (bit 15 and 13)
cmp [esi + sizeof.NET_BUFF + rxfd.status], 0 ; we could also check bits C and OK (bit 15 and 13)
je .nodata
DEBUGF 1,"rxfd status=0x%x\n", [esi + rxfd.status]:4
DEBUGF 1,"rxfd status=0x%x\n", [esi + sizeof.NET_BUFF + rxfd.status]:4
movzx ecx, [esi + rxfd.count]
movzx ecx, [esi + sizeof.NET_BUFF + rxfd.count]
and ecx, 0x3fff
push ebx
push .rx_loop
push ecx
add esi, rxfd.packet
push esi
mov [esi + NET_BUFF.length], ecx
mov [esi + NET_BUFF.device], ebx
mov [esi + NET_BUFF.offset], NET_BUFF.data + rxfd.packet
; Update stats
add dword [ebx + device.bytes_rx], ecx
@ -759,15 +775,16 @@ int_handler:
; allocate new descriptor
invoke KernelAlloc, 2000
invoke NetAlloc, 2000
mov [ebx + device.rx_desc], eax
mov esi, eax
invoke GetPhysAddr
mov [esi + rxfd.status], 0x0000
mov [esi + rxfd.command], 0xc000 ; End of list + Suspend
mov [esi + rxfd.link], eax
mov [esi + rxfd.count], 0
mov [esi + rxfd.size], 1528
add eax, NET_BUFF.data
mov [esi + sizeof.NET_BUFF + rxfd.status], 0x0000
mov [esi + sizeof.NET_BUFF + rxfd.command], 0xc000 ; End of list + Suspend
mov [esi + sizeof.NET_BUFF + rxfd.link], eax
mov [esi + sizeof.NET_BUFF + rxfd.count], 0
mov [esi + sizeof.NET_BUFF + rxfd.size], 1528
; restart RX
@ -783,7 +800,7 @@ int_handler:
call cmd_wait
; And give packet to kernel
jmp [Eth_input]
jmp [EthInput]
.nodata:
DEBUGF 1, "no more data\n"

View File

@ -473,8 +473,7 @@ unload:
; - Remove all allocated structures and buffers the card used
or eax, -1
ret
ret
;-------
@ -627,6 +626,8 @@ reset:
out dx, eax
call init_ring
test eax, eax
jnz .err
; Initialize other registers.
; Configure the PCI bus bursts and FIFO thresholds.
@ -637,7 +638,7 @@ reset:
jne @f
or [ebx + device.bcrvalue], 0x200 ; set PROG bit
or [ebx + device.crvalue], 0x02000000 ; set enhanced bit
@@:
@@:
or [ebx + device.crvalue], RxEnable + TxThreshold + TxEnable
call set_rx_mode
@ -676,13 +677,18 @@ reset:
xor eax, eax
ret
.err:
DEBUGF 2, "Error!\n"
or eax, -1
ret
align 4
init_ring:
DEBUGF 1,"initializing rx and tx ring\n"
DEBUGF 1, "initializing rx and tx ring\n"
; Initialize all Rx descriptors
lea esi, [ebx + device.rx_desc]
@ -690,7 +696,7 @@ init_ring:
mov ecx, NUM_RX_DESC
.rx_desc_loop:
mov [esi + descriptor.status], RXOWN
mov [esi + descriptor.control], 1536 shl RBSShift
mov [esi + descriptor.control], 1514 shl RBSShift
lea eax, [esi + sizeof.descriptor]
mov [esi + descriptor.next_desc_logical], eax
@ -698,11 +704,14 @@ init_ring:
invoke GetPhysAddr
mov [esi + descriptor.next_desc], eax
invoke KernelAlloc, 1536
pop esi
push esi
invoke NetAlloc, 1514+NET_BUFF.data
pop esi ecx
test eax, eax
jz .out_of_mem
push ecx esi
mov [esi + descriptor.skbuff], eax
invoke GetPgAddr
add eax, NET_BUFF.data
pop esi ecx
mov [esi + descriptor.buffer], eax
@ -746,10 +755,15 @@ init_ring:
pop esi
mov [esi - sizeof.descriptor + descriptor.next_desc], eax
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], TXLBA
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], TXLBA
out dx, eax
xor eax, eax
ret
.out_of_mem:
or eax, -1
ret
@ -924,25 +938,25 @@ getlinktype:
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
proc transmit stdcall bufferptr, buffersize
proc transmit stdcall bufferptr
pushf
cli
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
mov eax, [bufferptr]
mov esi, [bufferptr]
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
lea eax, [esi + NET_BUFF.data]
DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
[eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
[eax+13]:2,[eax+12]:2
cmp [buffersize], 1514
cmp [esi + NET_BUFF.length], 1514
ja .fail
cmp [buffersize], 60
cmp [esi + NET_BUFF.length], 60
jb .fail
mov esi, [ebx + device.cur_tx]
test [esi + descriptor.status], TXOWN
jnz .fail
@ -951,10 +965,12 @@ proc transmit stdcall bufferptr, buffersize
mov eax, [bufferptr]
mov [esi + descriptor.skbuff], eax
add eax, [eax + NET_BUFF.offset]
invoke GetPhysAddr
mov [esi + descriptor.buffer], eax
mov eax, [buffersize]
mov eax, [bufferptr]
mov eax, [eax + NET_BUFF.length]
mov ecx, eax
shl eax, PKTSShift ; packet size
shl ecx, TBSShift
@ -965,8 +981,9 @@ proc transmit stdcall bufferptr, buffersize
; Update stats
inc [ebx + device.packets_tx]
mov eax, [buffersize]
add dword[ebx + device.bytes_tx], eax
mov eax, [bufferptr]
mov ecx, [eax + NET_BUFF.length]
add dword[ebx + device.bytes_tx], ecx
adc dword[ebx + device.bytes_tx + 4], 0
; TX Poll
@ -982,7 +999,7 @@ proc transmit stdcall bufferptr, buffersize
.fail:
DEBUGF 2,"Transmit failed\n"
invoke KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
@ -1068,26 +1085,32 @@ int_handler:
mov ecx, [esi + descriptor.status]
shr ecx, FLNGShift
sub ecx, 4 ; we dont need CRC
push ecx
DEBUGF 1,"Received %u bytes\n", ecx
mov eax, [esi + descriptor.skbuff]
push eax
mov [eax + NET_BUFF.length], ecx
mov [eax + NET_BUFF.device], ebx
mov [eax + NET_BUFF.offset], NET_BUFF.data
; Update stats
add dword[ebx + device.bytes_rx], ecx
adc dword[ebx + device.bytes_rx + 4], 0
inc [ebx + device.packets_rx]
push [esi + descriptor.skbuff]
jmp [Eth_input]
jmp [EthInput]
.rx_complete:
pop ebx
mov esi, [ebx + device.cur_rx]
mov [esi + descriptor.control], 1536 shl RBSShift
mov [esi + descriptor.control], 1514 shl RBSShift
push esi
invoke KernelAlloc, 1536
invoke NetAlloc, 1514+NET_BUFF.data
pop esi
; test eax, eax
; jz .rx_loop
mov [esi + descriptor.skbuff], eax
invoke GetPgAddr
invoke GetPhysAddr
add eax, NET_BUFF.data
mov [esi + descriptor.buffer], eax
mov [esi + descriptor.status], RXOWN
@ -1122,7 +1145,7 @@ int_handler:
je .skip_this_one
mov [esi + descriptor.skbuff], 0
DEBUGF 1,"freeing buffer: 0x%x\n", eax
invoke KernelFree, eax
invoke NetFree, eax
.skip_this_one:
mov esi, [esi + descriptor.next_desc_logical]
loop .tx_loop

View File

@ -491,7 +491,7 @@ proc service_proc stdcall, ioctl:dword
.destroy:
; todo: reset device into virgin state
add eax, NET_BUFF.data
dec [devices]
.err:
DEBUGF 2,"Error, removing all data !\n"
@ -521,9 +521,8 @@ unload:
; - call unregister function in kernel
; - Remove all allocated structures and buffers the card used
or eax,-1
ret
or eax, -1
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -868,6 +867,8 @@ reset:
movsw
call init_ring
test eax, eax
jnz .fail
mov edx, [ebx + device.io_addr] ; init ring destroys edx
@ -923,6 +924,7 @@ reset:
DEBUGF 1,"reset complete\n"
xor eax, eax
.fail:
ret
@ -938,10 +940,13 @@ init_ring:
mov ecx, RX_RING_SIZE
.rx_init:
push ecx
invoke KernelAlloc, PKT_BUF_SZ
invoke NetAlloc, PKT_BUF_SZ+NET_BUFF.data
pop ecx
test eax, eax
jz .out_of_mem
mov [edi + descriptor.virtual], eax
invoke GetPhysAddr
add eax, NET_BUFF.data
mov [edi + descriptor.base], eax
mov [edi + descriptor.length], - PKT_BUF_SZ
mov [edi + descriptor.status], RXSTAT_OWN
@ -967,6 +972,13 @@ init_ring:
mov [ebx + device.last_tx], 0
mov [ebx + device.cur_rx], 0
xor eax, eax
ret
.out_of_mem:
DEBUGF 2,"Out of memory!\n"
or eax, -1
ret
@ -980,38 +992,40 @@ init_ring:
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
proc transmit stdcall bufferptr, buffersize
proc transmit stdcall bufferptr
pushf
cli
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
mov eax, [bufferptr]
mov esi, [bufferptr]
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
lea eax, [esi + NET_BUFF.data]
DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
[eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
[eax+13]:2,[eax+12]:2
cmp [buffersize], 1514
cmp [esi + NET_BUFF.length], 1514
ja .fail
cmp [buffersize], 60
cmp [esi + NET_BUFF.length], 60
jb .fail
; check descriptor
lea edi, [ebx + device.tx_ring]
movzx eax, [ebx + device.cur_tx]
shl eax, 4
add edi, eax
movzx ecx, [ebx + device.cur_tx]
shl ecx, 4
add edi, ecx
test [edi + descriptor.status], TXCTL_OWN
jnz .fail
; descriptor is free, use it
mov eax, [bufferptr]
mov [edi + descriptor.virtual], eax
mov [edi + descriptor.virtual], esi
mov eax, esi
add eax, [eax + NET_BUFF.offset]
invoke GetPhysAddr
mov [edi + descriptor.base], eax
; set length
mov eax, [buffersize]
mov eax, [esi + NET_BUFF.length]
neg eax
mov [edi + descriptor.length], ax
; put to transfer queue
@ -1030,7 +1044,7 @@ proc transmit stdcall bufferptr, buffersize
; Update stats
inc [ebx + device.packets_tx]
mov eax, [buffersize]
mov eax, [esi + NET_BUFF.length]
add dword[ebx + device.bytes_tx], eax
adc dword[ebx + device.bytes_tx + 4], 0
@ -1041,7 +1055,7 @@ proc transmit stdcall bufferptr, buffersize
.fail:
DEBUGF 2, "Send failed\n"
invoke KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
@ -1124,8 +1138,11 @@ int_handler:
push ebx
push .rx_loop ; return address
push ecx ; packet size
push [edi + descriptor.virtual] ; packet address
mov eax, [edi + descriptor.virtual]
push eax ; packet address
mov [eax + NET_BUFF.length], ecx
mov [eax + NET_BUFF.device], ebx
mov [eax + NET_BUFF.offset], NET_BUFF.data
; Update stats
add dword[ebx + device.bytes_rx], ecx
@ -1133,16 +1150,27 @@ int_handler:
inc [ebx + device.packets_rx]
; now allocate a new buffer
invoke KernelAlloc, PKT_BUF_SZ ; 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
jz .out_of_mem
mov [edi + descriptor.virtual], eax ; set virtual address
invoke GetPhysAddr
add eax, NET_BUFF.data
mov [edi + descriptor.base], eax ; and physical address
mov [edi + descriptor.status], RXSTAT_OWN ; give it back to PCnet controller
inc [ebx + device.cur_rx] ; set next receive descriptor
and [ebx + device.cur_rx], RX_RING_SIZE - 1
jmp [Eth_input]
jmp [EthInput]
.out_of_mem:
DEBUGF 2,"Out of memory!\n"
inc [ebx + device.cur_rx] ; set next receive descriptor
and [ebx + device.cur_rx], RX_RING_SIZE - 1
jmp [EthInput]
.not_receive:
pop ax
@ -1167,7 +1195,7 @@ int_handler:
DEBUGF 1,"Removing packet %x from memory\n", eax
invoke KernelFree, eax
invoke NetFree, eax
inc [ebx + device.last_tx]
and [ebx + device.last_tx], TX_RING_SIZE - 1

View File

@ -346,7 +346,7 @@ NIC_LB_NONE = 0x00
NIC_LB_INTERNAL = 0x01
NIC_LB_PHY = 0x02 ; MII or Internal-10BaseT loopback
PKT_BUF_SZ = 1536 ; Size of each temporary Rx buffer.
PKT_BUF_SZ = 1514
PCI_REG_MODE3 = 0x53
MODE3_MIION = 0x04 ; in PCI_REG_MOD3 OF PCI space
@ -929,11 +929,7 @@ reset:
DEBUGF 1,"Attaching int handler to irq %x\n", eax:1
invoke AttachIntHandler, eax, int_handler, ebx
test eax, eax
jnz @f
DEBUGF 2,"Could not attach int handler!\n"
or eax, -1
ret
@@:
jz .err
; Soft reset the chip.
set_io [ebx + device.io_addr], 0
@ -945,6 +941,8 @@ reset:
; Initialize rings
call init_ring
test eax, eax
jnz .err
; Set Multicast
call set_rx_mode
@ -968,7 +966,6 @@ reset:
out dx, al
; Set Fulldupex
call QueryAuto
test eax, eax ; full duplex?
jz @f
@ -1007,6 +1004,11 @@ reset:
xor eax, eax
ret
.err:
DEBUGF 2,"Error!\n"
or eax, -1
ret
align 4
@ -1073,10 +1075,13 @@ init_ring:
mov [edi + rx_head.status], RX_SBITS_OWN_BIT
mov [edi + rx_head.control], PKT_BUF_SZ
push ecx
invoke KernelAlloc, PKT_BUF_SZ
invoke NetAlloc, PKT_BUF_SZ+NET_BUFF.data
pop ecx
test eax, eax
jz .out_of_mem
mov [edi + rx_head.buff_addr_virt], eax
invoke GetPhysAddr
add eax, NET_BUFF.data
mov [edi + rx_head.buff_addr], eax ; buffer ptr
mov [edi + rx_head.next_desc], esi ; next head
add edi, sizeof.rx_head
@ -1120,6 +1125,12 @@ init_ring:
mov [ebx + device.cur_tx], ax
mov [ebx + device.last_tx], ax
xor eax, eax
ret
.out_of_mem:
add esp, 4
or eax, -1
ret
@ -1349,8 +1360,8 @@ set_rx_mode:
out dx, eax
set_io [ebx + device.io_addr], byRCR
mov al, 0x6C ;rx_mode = 0x0C;
out dx, al ;outb(0x60 /* thresh */ | rx_mode, byRCR );
mov al, 0x6C ; thresh or rx_mode
out dx, al
ret
@ -1393,26 +1404,26 @@ read_mac:
;; Transmit ;;
;; ;;
;; In: buffer pointer in [esp+4] ;;
;; size of buffer in [esp+8] ;;
;; pointer to device structure in ebx ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 4
proc transmit stdcall bufferptr, buffersize
proc transmit stdcall bufferptr
pushf
cli
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
mov eax, [bufferptr]
mov esi, [bufferptr]
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
lea eax, [esi + NET_BUFF.data]
DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
[eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
[eax+13]:2,[eax+12]:2
cmp [buffersize], 1514
cmp [esi + NET_BUFF.length], 1514
ja .fail
cmp [buffersize], 60
cmp [esi + NET_BUFF.length], 60
jb .fail
movzx eax, [ebx + device.cur_tx]
@ -1424,11 +1435,12 @@ proc transmit stdcall bufferptr, buffersize
cmp [edi + tx_head.buff_addr_virt], 0
jne .fail
mov eax, [bufferptr]
mov eax, esi
mov [edi + tx_head.buff_addr_virt], eax
add eax, [eax + NET_BUFF.offset]
invoke GetPhysAddr
mov [edi + tx_head.buff_addr], eax
mov ecx, [buffersize]
mov ecx, [esi + NET_BUFF.length]
and ecx, TX_CBITS_TX_BUF_SIZE
or ecx, 0x00E08000
mov [edi + tx_head.control], ecx
@ -1447,7 +1459,7 @@ proc transmit stdcall bufferptr, buffersize
; Update stats
inc [ebx + device.packets_tx]
mov ecx, [buffersize]
mov ecx, [esi + NET_BUFF.length]
add dword [ebx + device.bytes_tx], ecx
adc dword [ebx + device.bytes_tx + 4], 0
@ -1458,7 +1470,7 @@ proc transmit stdcall bufferptr, buffersize
.fail:
DEBUGF 2,"Transmit failed\n"
invoke KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
@ -1481,7 +1493,6 @@ int_handler:
DEBUGF 1,"INT\n"
; Find pointer of device which made IRQ occur
mov ecx, [devices]
test ecx, ecx
jz .nothing
@ -1506,9 +1517,7 @@ int_handler:
ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
.got_it:
DEBUGF 1, "status=0x%x\n", ax
push ax
@ -1521,7 +1530,6 @@ int_handler:
pop ebx
; Get the current descriptor pointer
movzx eax, [ebx + device.cur_rx]
mov ecx, sizeof.rx_head
mul ecx
@ -1529,57 +1537,51 @@ int_handler:
add edi, eax
; Check it's status
test [edi + rx_head.status], RX_SBITS_OWN_BIT
jnz .not_bit_own
jnz .not_RX
DEBUGF 1, "Packet status = 0x%x\n", [edi + rx_head.status]
; TODO: check error bits
; get length
mov ecx, [edi + rx_head.status]
and ecx, RX_SBITS_FRAME_LENGTH
shr ecx, 16
sub ecx, 4 ; We dont want CRC
sub ecx, 4 ; We dont want CRC
; Update stats
add dword [ebx + device.bytes_rx], ecx
adc dword [ebx + device.bytes_rx + 4], 0
inc [ebx + device.packets_rx]
; Push packet size and pointer, kernel will need it..
; Push packet pointer, kernel will need it..
push ebx
push .more_RX ; return ptr
push ecx ; full packet size
push [edi + rx_head.buff_addr_virt]
push .more_RX ; return ptr
mov eax, [edi + rx_head.buff_addr_virt]
push eax
mov [eax + NET_BUFF.length], ecx
mov [eax + NET_BUFF.device], ebx
mov [eax + NET_BUFF.offset], NET_BUFF.data
; reset the RX descriptor
push edi
invoke KernelAlloc, PKT_BUF_SZ
invoke NetAlloc, PKT_BUF_SZ+NET_BUFF.data
pop edi
mov [edi + rx_head.buff_addr_virt], eax
invoke GetPhysAddr
add eax, NET_BUFF.data
mov [edi + rx_head.buff_addr], eax
mov [edi + rx_head.status], RX_SBITS_OWN_BIT
; Use next descriptor next time
inc [ebx + device.cur_rx]
and [ebx + device.cur_rx], RX_RING_SIZE - 1
; At last, send packet to kernel
jmp [EthInput]
jmp [Eth_input]
.not_bit_own:
.not_RX:
pop ax
test ax, IntrTxDone
@ -1602,7 +1604,7 @@ int_handler:
push [edi + tx_head.buff_addr_virt]
mov [edi + tx_head.buff_addr_virt], 0
invoke KernelFree
invoke NetFree
inc [ebx + device.last_tx]
and [ebx + device.last_tx], TX_RING_SIZE - 1
@ -1613,12 +1615,12 @@ int_handler:
; On Rhine-II, Bit 3 indicates Tx descriptor write-back race.
if 0
cmp [ebx + device.chip_id], 0x3065 ;if (tp->chip_id == 0x3065)
cmp [ebx + device.chip_id], 0x3065
jne @f
push ax
xor eax, eax
set_io [ebx + device.io_addr], IntrStatus2
in al, dx ; intr_status |= inb(nic->ioaddr + IntrStatus2) << 16;
in al, dx
shl eax, 16
pop ax
@@:

View File

@ -414,8 +414,7 @@ unload:
; - Remove all allocated structures and buffers the card used
or eax, -1
ret
ret
;***************************************************************************
;
@ -612,12 +611,13 @@ reset:
mov dword [esi + 4], RX_BUFF_SZ ; size
push ecx esi
invoke KernelAlloc, RX_BUFF_SZ
invoke NetAlloc, RX_BUFF_SZ+NET_BUFF.data
pop esi ecx
test eax, eax
jz .fail
mov dword [esi + 12], eax ; address
invoke GetPhysAddr
add eax, NET_BUFF.data
mov dword [esi + 8], eax ; real address
add esi, 16
dec ecx
@ -1006,21 +1006,22 @@ write_mac:
;***************************************************************************
align 4
proc transmit stdcall bufferptr, buffersize
proc transmit stdcall bufferptr
pushf
cli
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
mov eax, [bufferptr]
mov esi, [bufferptr]
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
lea eax, [esi + NET_BUFF.data]
DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
[eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
[eax+13]:2,[eax+12]:2
cmp [buffersize], 1514
cmp [esi + NET_BUFF.length], 1514
ja .fail
cmp [buffersize], 60
cmp [esi + NET_BUFF.length], 60
jb .fail
movzx ecx, [ebx + device.cur_tx]
@ -1030,12 +1031,13 @@ proc transmit stdcall bufferptr, buffersize
test dword[ecx + 4], 0x80000000 ; card owns descriptor ?
jnz .fail
mov eax, [bufferptr]
mov eax, esi
mov dword[ecx + 12], eax
add eax, [eax + NET_BUFF.offset]
invoke GetPhysAddr
mov dword[ecx + 8], eax ; buffer address
mov eax, [buffersize]
mov eax, [esi + NET_BUFF.length]
and eax, DSIZE
or eax, 0x80000000 ; card owns descriptor
mov dword[ecx + 4], eax ; status field
@ -1050,7 +1052,7 @@ proc transmit stdcall bufferptr, buffersize
and [ebx + device.cur_tx], NUM_TX_DESC-1
; update stats
mov ecx, [buffersize]
mov ecx, [esi + NET_BUFF.length]
inc [ebx + device.packets_tx]
add dword [ebx + device.bytes_tx], ecx
adc dword [ebx + device.bytes_tx + 4], 0
@ -1062,7 +1064,7 @@ proc transmit stdcall bufferptr, buffersize
.fail:
DEBUGF 2,"Transmit failed\n"
invoke KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
@ -1151,16 +1153,19 @@ int_handler:
adc dword [ebx + device.bytes_rx + 4], 0
push ebx
push .return
push ecx ; packet size
pushd [ebx + device.rxd + eax + 12] ; packet ptr
push .return ; return addr
mov eax, [ebx + device.rxd + eax + 12]
push eax ; packet ptr
mov [eax + NET_BUFF.length], ecx
mov [eax + NET_BUFF.device], ebx
mov [eax + NET_BUFF.offset], NET_BUFF.data
DEBUGF 1, "Packet received OK\n"
jmp [Eth_input]
jmp [EthInput]
.return:
pop ebx
; Reset status, allow ethernet card access to descriptor
invoke KernelAlloc, RX_BUFF_SZ
invoke NetAlloc, RX_BUFF_SZ + NET_BUFF.data
test eax, eax
jz .fail
movzx ecx, [ebx + device.cur_rx]
@ -1168,6 +1173,7 @@ int_handler:
lea ecx, [ebx + device.rxd + ecx]
mov dword [ecx + 12], eax
invoke GetPhysAddr
add eax, NET_BUFF.data
mov dword [ecx + 8], eax
mov dword [ecx + 4], RX_BUFF_SZ
@ -1204,7 +1210,7 @@ int_handler:
DEBUGF 1, "Freeing packet = %x\n", [ecx + 12]:8
push dword[ecx + 12]
mov dword[ecx + 12], 0
invoke KernelFree
invoke NetFree
inc [ebx + device.last_tx]
and [ebx + device.last_tx], NUM_TX_DESC-1

View File

@ -104,7 +104,8 @@ kernel_export \
NetUnRegDev,\
NetPtrToNum,\
NetLinkChanged,\
Eth_input,\
IPv4_input,\
NetAlloc,\
NetFree,\
EthInput,\
\
GetPCIList

View File

@ -122,6 +122,19 @@ struct NET_DEVICE
ends
struct NET_BUFF
NextPtr dd ? ; pointer to next frame in list
PrevPtr dd ? ; pointer to previous frame in list
device dd ? ; ptr to NET_DEVICE structure
type dd ? ; data type (e.g. Ethernet)
length dd ? ; data length
offset dd ? ; offset to actual data (24 bytes for default frame)
data rb 0
ends
struct ETH_DEVICE NET_DEVICE
mac dp ?

View File

@ -155,8 +155,9 @@ import core,\
NetUnRegDev,\
NetPtrToNum,\
NetLinkChanged,\
Eth_input,\
IPv4_input,\
EthInput,\
NetAlloc,\
NetFree,\
\
GetPCIList
end data

View File

@ -122,7 +122,9 @@ __exports:
NET_remove_device, 'NetUnRegDev', \
NET_ptr_to_num, 'NetPtrToNum', \
NET_link_changed, 'NetLinkChanged', \
ETH_input, 'Eth_input', \
ETH_input, 'EthInput', \
NET_BUFF_alloc, 'NetAlloc', \
NET_BUFF_free, 'NetFree', \
\
get_pcidev_list, 'GetPCIList', \
\

View File

@ -293,13 +293,10 @@ ARP_input:
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: IP address conflict detected!\n"
.exit:
call NET_packet_free
add esp, 4 ; pop (balance stack)
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: exiting\n"
call NET_BUFF_free
ret
;---------------------------------------------------------------------------
;
; ARP_output_request
@ -347,7 +344,7 @@ ARP_output_request:
movsd ;
popd [edi] ; DestIP
push edx eax
push eax
call [ebx + NET_DEVICE.transmit]
ret

View File

@ -225,10 +225,10 @@ macro IPv4_checksum ptr {
align 4
IPv4_input: ; TODO: add IPv4 raw sockets support
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input, packet from: %u.%u.%u.%u ",\
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: packet from %u.%u.%u.%u ",\
[edx + IPv4_header.SourceAddress + 0]:1,[edx + IPv4_header.SourceAddress + 1]:1,\
[edx + IPv4_header.SourceAddress + 2]:1,[edx + IPv4_header.SourceAddress + 3]:1
DEBUGF DEBUG_NETWORK_VERBOSE, "to: %u.%u.%u.%u\n",\
DEBUGF DEBUG_NETWORK_VERBOSE, "to %u.%u.%u.%u\n",\
[edx + IPv4_header.DestinationAddress + 0]:1,[edx + IPv4_header.DestinationAddress + 1]:1,\
[edx + IPv4_header.DestinationAddress + 2]:1,[edx + IPv4_header.DestinationAddress + 3]:1
@ -323,8 +323,7 @@ IPv4_input: ; TODO: add IPv4
.dump:
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: dumping\n"
inc [IPv4_packets_dumped] ; FIXME: use correct interface
call NET_packet_free
add esp, 4 ; pop (balance stack)
call NET_BUFF_free
ret
@ -371,7 +370,6 @@ IPv4_input: ; TODO: add IPv4
mov [eax + IPv4_FRAGMENT_entry.PrevPtr], edi
mov [eax + IPv4_FRAGMENT_entry.Owner], ebx
add esp, 4
ret
@ -405,7 +403,6 @@ IPv4_input: ; TODO: add IPv4
mov [eax + IPv4_FRAGMENT_entry.PrevPtr], -1
mov [eax + IPv4_FRAGMENT_entry.Owner], ebx
add esp, 4 ; balance stack and exit
ret
@ -506,7 +503,7 @@ IPv4_input: ; TODO: add IPv4
push [edx + IPv4_FRAGMENT_entry.NextPtr] ; Set edx to the next pointer
push edx ; Push pointer to fragment onto stack
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Next Fragment: 0x%x\n", edx
call NET_packet_free ; free the previous fragment buffer (this uses the value from stack)
call NET_BUFF_free ; free the previous fragment buffer (this uses the value from stack)
pop edx ebx eax
cmp edx, -1 ; Check if it is last fragment in chain
jne .rebuild_packet_loop
@ -654,7 +651,7 @@ IPv4_output:
ret
.loopback:
mov dword [esp + 2], eax ; change source IP to dest IP
mov dword [esp], eax ; set source IP to dest IP
mov ecx, [esp + 10]
add ecx, sizeof.IPv4_header
mov edi, AF_INET4
@ -749,7 +746,6 @@ IPv4_output_raw:
;
;
; IN: dword [esp] = pointer to buffer containing ipv4 packet to be fragmented
; dword [esp+4] = buffer size
; esi = pointer to ip header in that buffer
; ecx = max size of fragments
;
@ -857,9 +853,7 @@ IPv4_fragment:
add esp, 12 + 4 + 6
.err2:
DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: dumping\n"
call NET_packet_free
add esp, 4
call NET_BUFF_free
ret

View File

@ -147,9 +147,7 @@ IPv6_input:
.dump:
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv6_input - dumping\n"
call kernel_free
add esp, 4
call NET_BUFF_free
ret
.dump_options:

View File

@ -106,8 +106,7 @@ PPPoE_discovery_input:
popa
DEBUGF DEBUG_NETWORK_VERBOSE, 'PPPoE_discovery_input: dumping\n'
call NET_packet_free
add esp, 4
call NET_BUFF_free
ret
@ -232,13 +231,11 @@ PPPoE_session_input:
.dump:
DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_input: dumping\n"
call NET_packet_free
add esp, 4
call NET_BUFF_free
ret
;-----------------------------------------------------------------
;
; PPPoE_output

View File

@ -33,30 +33,25 @@ struct ETH_DEVICE NET_DEVICE
ends
struct ETH_queue_entry
device dd ?
packet dd ?
size dd ?
ends
iglobal
align 4
ETH_BROADCAST dp 0xffffffffffff
ETH_BROADCAST dp 0xffffffffffff
ETH_frame_queued dd 0 ; Number of queued frames
ETH_frame_head dd ETH_frame_head ; Pointer to next frame in the linked list
ETH_frame_tail dd ETH_frame_head ; Pointer to last frame in the linked list
endg
uglobal
align 4
ETH_input_event dd ?
ETH_queue rd (ETH_QUEUE_SIZE*sizeof.ETH_queue_entry + sizeof.queue)/4
endg
macro ETH_init {
init_queue ETH_queue
movi ebx, 1
mov ecx, ETH_process_input
call new_sys_threads
@ -72,23 +67,36 @@ macro ETH_init {
; ETH_input
;
; This function is called by ethernet drivers,
; It pushes the received ethernet packets onto the eth_in_queue
; It pushes the received ethernet packets onto the ethernet input queue
;
; IN: [esp] = Pointer to buffer
;
; IN: [esp] = Pointer to buffer
; [esp+4] = size of buffer
; ebx = pointer to eth_device
; OUT: /
;
;-----------------------------------------------------------------
align 4
ETH_input:
push ebx
mov esi, esp
pop eax
pushf
cli
add_to_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .fail
add esp, sizeof.ETH_queue_entry
cmp [ETH_frame_queued], ETH_QUEUE_SIZE
jae .full
inc [ETH_frame_queued]
; Add frame to the end of the linked list
mov [eax + NET_BUFF.NextPtr], ETH_frame_head
mov ebx, [ETH_frame_tail]
mov [eax + NET_BUFF.PrevPtr], ebx
mov [ETH_frame_tail], eax
mov [ebx + NET_BUFF.NextPtr], eax
popf
; Now queue an event to process it
xor edx, edx
mov eax, [ETH_input_event]
mov ebx, [eax + EVENT.id]
@ -97,13 +105,11 @@ ETH_input:
ret
.fail:
.full:
DEBUGF DEBUG_NETWORK_ERROR, "ETH incoming queue is full, discarding packet!\n"
pop ebx
call NET_packet_free
add esp, 4
popf
push eax
call NET_BUFF_free
ret
@ -116,29 +122,46 @@ ETH_process_input:
mov ecx, MANUAL_DESTROY
call create_event
mov [ETH_input_event], eax
pushf
.wait:
popf
mov eax, [ETH_input_event]
mov ebx, [eax + EVENT.id]
call wait_event
.loop:
get_from_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .wait
pushf
cli
cmp [ETH_frame_queued], 0
je .wait
mov eax, [esi + ETH_queue_entry.packet]
mov ecx, [esi + ETH_queue_entry.size]
mov ebx, [esi + ETH_queue_entry.device]
dec [ETH_frame_queued]
pushd .loop ; return address
push ecx eax
mov esi, [ETH_frame_head]
mov ebx, [esi + NET_BUFF.NextPtr]
mov [ETH_frame_head], ebx
mov [ebx + NET_BUFF.PrevPtr], ETH_frame_head
popf
mov eax, [esi + NET_BUFF.offset]
add eax, esi
mov ecx, [esi + NET_BUFF.length]
mov ebx, [esi + NET_BUFF.device]
pushd .loop ; return address for protocol handler
push esi ; keep pointer to NET_BUFF on stack
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: size=%u\n", ecx
sub ecx, sizeof.ETH_header
jb .dump
; Set registers for protocol handlers
lea edx, [eax + sizeof.ETH_header]
mov ax, [eax + ETH_header.Type]
; Place protocol handlers here
cmp ax, ETHER_PROTO_IPv4
je IPv4_input
@ -158,8 +181,7 @@ ETH_process_input:
.dump:
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: dumping\n"
call NET_packet_free
add esp, 4
call NET_BUFF_free
ret
;-----------------------------------------------------------------
@ -171,11 +193,10 @@ ETH_process_input:
; ecx = payload size
; edx = pointer to destination mac
;
; OUT: eax = start of ethernet frame / 0 on error
; OUT: eax = start of net frame / 0 on error
; ebx = device ptr
; ecx = payload size
; edx = ethernet frame size
; edi = start of ethernet payload
; edi = start of payload
;
;-----------------------------------------------------------------
align 4
@ -189,11 +210,14 @@ ETH_output:
push ecx
push ax edx
add ecx, sizeof.ETH_header
stdcall kernel_alloc, ecx
add ecx, sizeof.ETH_header + NET_BUFF.data
stdcall NET_BUFF_alloc, ecx
test eax, eax
jz .out_of_ram
mov edi, eax
mov [eax + NET_BUFF.type], NET_BUFF_ETH
mov [eax + NET_BUFF.device], ebx
mov [eax + NET_BUFF.offset], NET_BUFF.data
lea edi, [eax + NET_BUFF.data]
pop esi
movsd
@ -204,13 +228,14 @@ ETH_output:
pop ax
stosw
lea eax, [edi - sizeof.ETH_header] ; Set eax to buffer start
lea eax, [edi - sizeof.ETH_header - NET_BUFF.data] ; Set eax to buffer start
pop ecx
lea edx, [ecx + sizeof.ETH_header] ; Set edx to complete buffer size
lea edx, [ecx + sizeof.ETH_header] ; Set edx to complete buffer size
cmp edx, ETH_FRAME_MINIMUM
jbe .adjust_size
.done:
mov [eax + NET_BUFF.length], edx
DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: ptr=%x size=%u\n", eax, edx
ret
@ -272,7 +297,7 @@ ETH_api:
.read_mac:
movzx ebx, word [eax + ETH_DEVICE.mac]
mov eax, dword [eax + ETH_DEVICE.mac + 2]
mov [esp+20+4], ebx ; TODO: fix this ugly code
mov [esp+20+4], ebx ; FIXME
ret

View File

@ -131,7 +131,6 @@ macro ICMP_init {
; and insert packets into sockets when needed
;
; IN: Pointer to buffer in [esp]
; size of buffer in [esp+4]
; ebx = pointer to device struct
; ecx = ICMP Packet size
; esi = ptr to ICMP Packet data
@ -143,10 +142,9 @@ macro ICMP_init {
align 4
ICMP_input:
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input:\n"
; First, check the checksum (altough some implementations ignore it)
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input\n"
; Check the checksum
push esi ecx
push [esi + ICMP_header.Checksum]
mov [esi + ICMP_header.Checksum], 0
@ -155,100 +153,34 @@ ICMP_input:
call checksum_2
pop si
cmp dx, si
pop ecx edx
pop ecx esi
jne .checksum_mismatch
; Check packet type
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: Checksum OK\n"
cmp [edx + ICMP_header.Type], ICMP_ECHO ; Is this an echo request?
jne .check_sockets
; Update stats (and validate device ptr)
; Ualidate device ptr
mov eax, edi
call NET_ptr_to_num4
cmp edi, -1
je .dump
; Update stats
inc [ICMP_PACKETS_RX + edi]
; We well re-use the packet so we can create the response as fast as possible
; Notice: this only works on pure ethernet
DEBUGF DEBUG_NETWORK_VERBOSE, "got echo request\n"
mov [edx + ICMP_header.Type], ICMP_ECHOREPLY ; Change Packet type to reply
mov esi, [esp] ; Start of buffer
cmp ebx, LOOPBACK_DEVICE
je .loopback
; FIXME: dont assume device is an ethernet device!
; exchange dest and source address in IP header
; exchange dest and source MAC in ETH header
push dword [esi + ETH_header.DstMAC]
push dword [esi + ETH_header.SrcMAC]
pop dword [esi + ETH_header.DstMAC]
pop dword [esi + ETH_header.SrcMAC]
push word [esi + ETH_header.DstMAC + 4]
push word [esi + ETH_header.SrcMAC + 4]
pop word [esi + ETH_header.DstMAC + 4]
pop word [esi + ETH_header.SrcMAC + 4]
add esi, sizeof.ETH_header-4
.loopback:
add esi, 4
push [esi + IPv4_header.SourceAddress]
push [esi + IPv4_header.DestinationAddress]
pop [esi + IPv4_header.SourceAddress]
pop [esi + IPv4_header.DestinationAddress]
; Recalculate ip header checksum
movzx ecx, [esi + IPv4_header.VersionAndIHL] ; Calculate IP Header length by using IHL field
and ecx, 0x0f
shl cx, 2
mov edi, ecx ; IP header length
mov eax, edx ; ICMP packet start addr
push esi ; Calculate the IP checksum
xor edx, edx ;
call checksum_1 ;
call checksum_2 ;
pop esi ;
mov [esi + IPv4_header.HeaderChecksum], dx ;
; Recalculate ICMP CheckSum
movzx ecx, [esi + IPv4_header.TotalLength] ; Find length of IP Packet
xchg ch, cl ;
sub ecx, edi ; IP packet length - IP header length = ICMP packet length
mov esi, eax ; Calculate ICMP checksum
xor edx, edx ;
call checksum_1 ;
call checksum_2 ;
mov [eax + ICMP_header.Checksum], dx ;
; Transmit the packet (notice that packet ptr and packet size have been on stack since start of the procedure!)
call [ebx + NET_DEVICE.transmit]
test eax, eax
jnz @f
call NET_ptr_to_num4
inc [ICMP_PACKETS_TX + edi]
@@:
ret
.check_sockets:
; Look for an open ICMP socket
; Is this an echo request?
cmp [esi + ICMP_header.Type], ICMP_ECHO
je .echo_request
; Look for an open ICMP socket
pusha
mov ecx, socket_mutex
call mutex_lock
popa
mov esi, [edi] ; ipv4 source address
mov edx, [eax] ; ipv4 source address
mov eax, net_sockets
.try_more:
; mov , [edx + ICMP_header.Identifier]
; mov , [esi + ICMP_header.Identifier]
.next_socket:
mov eax, [eax + SOCKET.NextPtr]
or eax, eax
@ -260,18 +192,12 @@ ICMP_input:
cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP
jne .next_socket
cmp [eax + IP_SOCKET.RemoteIP], esi
cmp [eax + IP_SOCKET.RemoteIP], edx
jne .next_socket
; cmp [eax + ICMP_SOCKET.Identifier],
; jne .next_socket
; Update stats (and validate device ptr)
call NET_ptr_to_num4
cmp edi, -1
je .dump_
inc [ICMP_PACKETS_RX + edi]
pusha
mov ecx, socket_mutex
call mutex_unlock
@ -284,11 +210,82 @@ ICMP_input:
call mutex_lock
popa
mov esi, edx
jmp SOCKET_input
.dump_:
.echo_request:
; We'll reuse the packet so we can create the response as fast as possible
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP echo request\n"
; Change Packet type to reply
mov [esi + ICMP_header.Type], ICMP_ECHOREPLY
mov eax, [esp]
lea esi, [eax + NET_BUFF.data]
; Check frame type
cmp [eax + NET_BUFF.type], NET_BUFF_ETH
jne .not_ethernet
; exchange dest and source MAC in ETH header
push dword [esi + ETH_header.DstMAC]
push dword [esi + ETH_header.SrcMAC]
pop dword [esi + ETH_header.DstMAC]
pop dword [esi + ETH_header.SrcMAC]
push word [esi + ETH_header.DstMAC + 4]
push word [esi + ETH_header.SrcMAC + 4]
pop word [esi + ETH_header.DstMAC + 4]
pop word [esi + ETH_header.SrcMAC + 4]
add esi, sizeof.ETH_header
.not_ethernet:
; Exchange dest and source address in IP header
push [esi + IPv4_header.SourceAddress]
push [esi + IPv4_header.DestinationAddress]
pop [esi + IPv4_header.SourceAddress]
pop [esi + IPv4_header.DestinationAddress]
; Calculate IP header length
movzx ecx, [esi + IPv4_header.VersionAndIHL]
and ecx, 0x0f
shl cx, 2
mov edi, ecx ; put it in edi for later
; Calculate IP checksum
mov eax, esi
mov [eax + IPv4_header.HeaderChecksum], 0
xor edx, edx
call checksum_1
call checksum_2
mov [eax + IPv4_header.HeaderChecksum], dx
; Calculate ICMP packet length
movzx ecx, [eax + IPv4_header.TotalLength]
xchg ch, cl
sub ecx, edi ; IP packet length - IP header length = ICMP packet length
; Calculate ICMP checkSum
mov eax, esi
mov [esi + ICMP_header.Checksum], 0
xor edx, edx
call checksum_1
call checksum_2
mov [eax + ICMP_header.Checksum], dx
; Transmit the frame
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP transmitting reply\n"
call [ebx + NET_DEVICE.transmit]
test eax, eax
jnz @f
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP transmit failed\n"
call NET_ptr_to_num4
inc [ICMP_PACKETS_TX + edi]
@@:
ret
.dump_:
pusha
mov ecx, socket_mutex
call mutex_unlock
@ -297,16 +294,12 @@ ICMP_input:
DEBUGF DEBUG_NETWORK_ERROR, "ICMP_input: no socket found\n"
jmp .dump
.checksum_mismatch:
DEBUGF DEBUG_NETWORK_ERROR, "ICMP_input: checksum mismatch\n"
.dump:
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: dumping\n"
call NET_packet_free
add esp, 4 ; pop (balance stack)
call NET_BUFF_free
ret
@ -400,7 +393,6 @@ ICMP_output_raw:
jz .exit
pop esi
push edx
push eax
push edi ecx
@ -426,7 +418,6 @@ ICMP_output_raw:
ret
.exit:
DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
add esp, 4
ret

View File

@ -66,54 +66,56 @@ local .fail
; LOOP_input
;
; IN: [esp+4] = Pointer to buffer
; [esp+8] = size of buffer
;
; OUT: /
;
;-----------------------------------------------------------------
align 4
LOOP_input:
pop ebx
pop eax
pop ecx
push ebx
push ecx
push eax
mov eax, [esp+4]
; Update stats
inc [LOOPBACK_DEVICE.packets_rx]
mov ecx, [eax + NET_BUFF.length]
add dword[LOOPBACK_DEVICE.bytes_rx], ecx
adc dword[LOOPBACK_DEVICE.bytes_rx + 4], 0
DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_input: size=%u\n", ecx
lea edx, [eax + 4]
mov eax, dword[eax]
mov ebx, LOOPBACK_DEVICE
DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_input: ptr=%x size=%u\n", eax, ecx
; Reverse buffptr and returnaddr on stack
pop edx edi
push edx edi
; Set registers for protocol handlers
lea edx, [eax + NET_BUFF.data]
mov ebx, [eax + NET_BUFF.device]
mov eax, [eax + NET_BUFF.type]
; Place protocol handlers here
cmp eax, AF_INET4
je IPv4_input
DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_input: Unknown packet type=%x\n", ax
DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_input: Unknown packet type=%x\n", eax
.dump:
DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_input: dumping\n"
call NET_packet_free
add esp, 4
call NET_BUFF_free
ret
;-----------------------------------------------------------------
;
; LOOP_output
;
; IN:
; ecx = packet size
; IN: ecx = packet size
; edi = address family
;
; OUT: edi = 0 on error, pointer to buffer otherwise
; eax = buffer start
; OUT: eax = start of net frame / 0 on error
; ebx = to device structure
; ecx = unchanged (packet size of embedded data)
; edx = size of complete buffer
; edi = start of payload
;
;-----------------------------------------------------------------
align 4
@ -121,35 +123,38 @@ LOOP_output:
DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_output\n"
push ecx
push edi
add ecx, 4
cmp ecx, [LOOPBACK_DEVICE.mtu]
ja .out_of_ram
stdcall kernel_alloc, ecx
ja .too_large
push ecx edi
stdcall NET_BUFF_alloc, ecx
test eax, eax
jz .out_of_ram
mov edi, eax
pop eax
stosd
lea eax, [edi - 4] ; Set eax to buffer start
pop ecx
lea edx, [ecx + 4] ; Set edx to complete buffer size
pop edi
mov [eax + NET_BUFF.type], edi
mov ebx, LOOPBACK_DEVICE
mov [eax + NET_BUFF.device], ebx
pop ecx
mov [eax + NET_BUFF.length], ecx
lea edi, [eax + NET_BUFF.data]
inc [LOOPBACK_DEVICE.packets_tx]
add dword[LOOPBACK_DEVICE.bytes_tx], ecx
adc dword[LOOPBACK_DEVICE.bytes_tx + 4], 0
DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_output: ptr=%x size=%u\n", eax, edx
DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_output: ptr=%x size=%u\n", eax, ecx
ret
.too_large:
DEBUGF DEBUG_NETWORK_ERROR, "LOOP_output: packet is too large\n"
xor eax, eax
ret
.out_of_ram:
DEBUGF DEBUG_NETWORK_ERROR, "LOOP_output: out of memory\n"
add esp, 4+4
xor edi, edi
xor eax, eax
ret

View File

@ -179,8 +179,8 @@ ends
struct socket_queue_entry
data_ptr dd ?
buf_ptr dd ?
data_size dd ?
buf_ptr dd ?
ends
@ -822,7 +822,7 @@ SOCKET_receive_dgram:
rep movsd
.nd:
call NET_packet_free
call NET_BUFF_free
pop ecx eax ; return number of bytes copied to application
xor ebx, ebx
ret
@ -1441,7 +1441,6 @@ SOCKET_check_port:
; ecx = data size
; esi = ptr to data
; [esp] = ptr to buf
; [esp + 4] = buf size
;
; OUT: /
;
@ -1451,7 +1450,7 @@ SOCKET_input:
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_input: socket=%x, data=%x size=%u\n", eax, esi, ecx
mov [esp+4], ecx
push ecx
push esi
mov esi, esp
@ -1475,16 +1474,13 @@ SOCKET_input:
call mutex_unlock
popa
call NET_packet_free
add esp, 8
call NET_BUFF_free
ret
;--------------------------
;
; IN: eax = ptr to ring struct (just a buffer of the right size)
; OUT: eax = unchanged / 0 on error
; eax = ptr to ring struct (just a buffer of the right size)
;
align 4
SOCKET_ring_create:

View File

@ -155,6 +155,10 @@ NET_LINK_IEEE802.11 = 3 ; IEEE 802.11 (WiFi)
NET_HWACC_TCP_IPv4_IN = 1 shl 0
NET_HWACC_TCP_IPv4_OUT = 1 shl 1
; Network frame types
NET_BUFF_LOOPBACK = 0
NET_BUFF_ETH = 1
struct NET_DEVICE
device_type dd ? ; Type field
@ -175,6 +179,18 @@ struct NET_DEVICE
ends
struct NET_BUFF
NextPtr dd ? ; pointer to next frame in list
PrevPtr dd ? ; pointer to previous frame in list
device dd ? ; ptr to NET_DEVICE structure
type dd ? ; encapsulation type: e.g. Ethernet
length dd ? ; size of encapsulated data
offset dd ? ; offset to actual data (24 bytes for default frame)
data rb 0
ends
; Exactly as it says..
macro pseudo_random reg {
@ -327,7 +343,13 @@ stack_handler:
align 4
NET_packet_free:
NET_BUFF_alloc:
add dword[esp+4], NET_BUFF.data
jmp kernel_alloc
align 4
NET_BUFF_free:
and dword[esp+4], not 0xfff
jmp kernel_free
@ -482,8 +504,10 @@ NET_ptr_to_num:
align 4
NET_ptr_to_num4: ; Todo, place number in device structure so we only need to verify?
push ecx
test ebx, ebx
jz .fail
push ecx
mov ecx, NET_DEVICES_MAX
mov edi, NET_DRV_LIST
.loop:
@ -493,8 +517,9 @@ NET_ptr_to_num4: ; Todo, place number in device structure so we o
dec ecx
jnz .loop
or edi, -1
pop ecx
.fail:
or edi, -1
ret
.found:

View File

@ -124,9 +124,8 @@ struct TCP_queue_entry
segment_ptr dd ?
segment_size dd ?
device_ptr dd ?
buffer_ptr dd ?
timestamp dd ?
buffer_ptr dd ?
ends

View File

@ -23,7 +23,6 @@ $Revision$
; Add a segment to the incoming TCP queue
;
; IN: [esp] = ptr to buffer
; [esp+4] = buffer size (dont care)
; ebx = ptr to device struct
; ecx = segment size
; esi = ptr to TCP segment
@ -37,10 +36,8 @@ align 4
TCP_input:
; record the current time
mov eax, [timer_ticks] ; in 1/100 seconds
mov [esp + 4], eax
push ebx ecx esi edi ; mind the order
push [timer_ticks] ; in 1/100 seconds
push ebx ecx esi edi ; mind the order (see TCP_queue_entry struct)
mov esi, esp
add_to_queue TCP_queue, TCP_QUEUE_SIZE, sizeof.TCP_queue_entry, .fail
@ -64,14 +61,11 @@ TCP_input:
inc [TCP_segments_missed + edi]
add esp, sizeof.TCP_queue_entry - 8
call NET_packet_free
add esp, 4
call NET_BUFF_free
ret
align 4
proc TCP_process_input
@ -1595,7 +1589,7 @@ align 4
.done:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: dumping\n"
call NET_packet_free
call NET_BUFF_free
jmp .loop
@ -1714,7 +1708,7 @@ align 4
.drop_no_socket:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Drop (no socket)\n"
call NET_packet_free
call NET_BUFF_free
jmp .loop
endp

View File

@ -522,7 +522,6 @@ endl
pop esi ; headersize
add esp, esi ; remove it from stack
push edx ; packet size for send proc
push eax ; packet ptr for send proc
mov edx, edi ; begin of data
@ -537,7 +536,7 @@ endl
; ecx = buffer size
; edi = ptr to buffer
mov eax, [esp + 16] ; get socket ptr
mov eax, [esp + 12] ; get socket ptr
push edx
push [eax + TCP_SOCKET.SND_NXT] ; we'll need this for timing the transmission
@ -552,7 +551,7 @@ endl
pop edi
pop esi ; begin of data
pop ecx ; full packet size
mov eax, [esp + 12] ; socket ptr
mov eax, [esp + 8] ; socket ptr
;----------------------------------
; initialize retransmit timer (400)

View File

@ -292,7 +292,7 @@ TCP_respond:
call IPv4_output
jz .error
pop esi cx
push edx eax
push eax
;-----------------------------------------------
; Fill in the TCP header by using the socket ptr
@ -376,7 +376,7 @@ TCP_respond_segment:
jz .error
pop esi cx
push edx eax
push eax
;---------------------------------------------------
; Fill in the TCP header by using a received segment

View File

@ -154,7 +154,7 @@ UDP_input:
.next_socket:
mov eax, [eax + SOCKET.NextPtr]
or eax, eax
jz .dump_
jz .unlock_dump
cmp [eax + SOCKET.Domain], AF_INET4
jne .next_socket
@ -213,30 +213,25 @@ UDP_input:
mov [eax + UDP_SOCKET.RemotePort], cx
jmp .updatesock
.dump_:
.unlock_dump:
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: no socket found\n"
jmp .dump
.checksum_mismatch:
DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: checksum mismatch\n"
.dump:
call NET_packet_free
add esp, 4 ; pop (balance stack)
DEBUGF DEBUG_NETWORK_VERBOSE,"UDP_input: dumping\n"
DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: dumping\n"
call NET_BUFF_free
ret
;-----------------------------------------------------------------
;
; UDP_output
@ -260,7 +255,7 @@ UDP_output:
mov dx, [eax + UDP_SOCKET.LocalPort]
DEBUGF DEBUG_NETWORK_VERBOSE, "local port=%x\n", dx
sub esp, 8 ; Data ptr and data size will be placed here
sub esp, 4 ; Data ptr will be placed here
push edx esi
mov edx, [eax + IP_SOCKET.LocalIP]
mov eax, [eax + IP_SOCKET.RemoteIP]
@ -269,7 +264,6 @@ UDP_output:
call IPv4_output
jz .fail
mov [esp + 8], eax ; pointer to buffer start
mov [esp + 8 + 4], edx ; buffer size
mov [edi + UDP_header.Length], cx
rol [edi + UDP_header.Length], 8