forked from KolibriOS/kolibrios
New network buffers - phase I
git-svn-id: svn://kolibrios.org@5522 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
a07659c72e
commit
0ba1fff7a7
@ -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
|
||||
@ -902,6 +905,7 @@ start_device:
|
||||
|
||||
; Set link state to 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
|
||||
@ -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:
|
||||
@ -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:
|
||||
|
@ -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,12 +396,11 @@ 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
|
||||
|
||||
|
||||
@ -452,6 +451,7 @@ probe:
|
||||
cmp ax, 0xFFFF
|
||||
jne @f
|
||||
DEBUGF 2, "Failed to detect an attached PHY!\n"
|
||||
.err:
|
||||
mov eax, -1
|
||||
ret
|
||||
@@:
|
||||
@ -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
|
||||
@ -662,19 +664,19 @@ init_rxbufs:
|
||||
|
||||
.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:
|
||||
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,11 +933,10 @@ 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
|
||||
|
||||
@ -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
|
||||
|
@ -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]
|
||||
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
|
||||
@ -826,8 +828,8 @@ int_handler:
|
||||
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
|
||||
@ -840,7 +842,8 @@ int_handler:
|
||||
; calculate packet length in ecx
|
||||
shr ecx, 16
|
||||
sub ecx, 4 ; CRC doesnt count as data byte
|
||||
mov [esp + 8], ecx
|
||||
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
|
||||
|
@ -404,7 +404,6 @@ unload:
|
||||
; - Remove all allocated structures and buffers the card used
|
||||
|
||||
or eax, -1
|
||||
|
||||
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
|
||||
|
||||
|
@ -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,37 +1154,43 @@ 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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
;---------------
|
||||
; re set OWN bit
|
||||
|
||||
mov eax, DSB_OWNbit or RX_BUF_SIZE
|
||||
@ -1179,15 +1200,15 @@ int_handler:
|
||||
@@:
|
||||
mov [esi + rx_desc.status], eax
|
||||
|
||||
;--------------
|
||||
; 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
|
||||
|
@ -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
|
||||
@ -1241,7 +1251,7 @@ int_handler:
|
||||
|
||||
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]
|
||||
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
|
||||
@ -1271,7 +1280,7 @@ int_handler:
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
@ -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"
|
||||
|
@ -473,7 +473,6 @@ unload:
|
||||
; - Remove all allocated structures and buffers the card used
|
||||
|
||||
or eax, -1
|
||||
|
||||
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.
|
||||
@ -676,6 +677,11 @@ reset:
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.err:
|
||||
DEBUGF 2, "Error!\n"
|
||||
or eax, -1
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -750,6 +759,11 @@ init_ring:
|
||||
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
|
||||
|
@ -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"
|
||||
@ -522,7 +522,6 @@ unload:
|
||||
; - Remove all allocated structures and buffers the card used
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
|
||||
; 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]
|
||||
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
|
||||
@@:
|
||||
|
@ -414,7 +414,6 @@ unload:
|
||||
; - Remove all allocated structures and buffers the card used
|
||||
|
||||
or eax, -1
|
||||
|
||||
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
|
||||
|
@ -104,7 +104,8 @@ kernel_export \
|
||||
NetUnRegDev,\
|
||||
NetPtrToNum,\
|
||||
NetLinkChanged,\
|
||||
Eth_input,\
|
||||
IPv4_input,\
|
||||
NetAlloc,\
|
||||
NetFree,\
|
||||
EthInput,\
|
||||
\
|
||||
GetPCIList
|
||||
|
@ -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 ?
|
||||
|
@ -155,8 +155,9 @@ import core,\
|
||||
NetUnRegDev,\
|
||||
NetPtrToNum,\
|
||||
NetLinkChanged,\
|
||||
Eth_input,\
|
||||
IPv4_input,\
|
||||
EthInput,\
|
||||
NetAlloc,\
|
||||
NetFree,\
|
||||
\
|
||||
GetPCIList
|
||||
end data
|
||||
|
@ -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', \
|
||||
\
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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_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
|
||||
; [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
|
||||
|
||||
|
||||
|
@ -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
|
||||
; Is this an echo request?
|
||||
cmp [esi + ICMP_header.Type], ICMP_ECHO
|
||||
je .echo_request
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user