New network buffers - phase I

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

View File

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

View File

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

View File

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

View File

@ -404,8 +404,7 @@ unload:
; - Remove all allocated structures and buffers the card used ; - Remove all allocated structures and buffers the card used
or eax, -1 or eax, -1
ret
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -628,27 +627,26 @@ reset:
;; ;; ;; ;;
;; Transmit ;; ;; Transmit ;;
;; ;; ;; ;;
;; In: buffer pointer in [esp+4] ;; ;; In: pointer to device structure in ebx ;;
;; size of buffer in [esp+8] ;;
;; pointer to device structure in ebx ;;
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
proc transmit stdcall bufferptr, buffersize proc transmit stdcall bufferptr
pushf pushf
cli cli
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] mov esi, [bufferptr]
mov eax, [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",\ 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+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+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
[eax+13]:2,[eax+12]:2 [eax+13]:2,[eax+12]:2
cmp [buffersize], 1514 cmp [esi + NET_BUFF.length], 1514
ja .fail ja .fail
cmp [buffersize], 60 cmp [esi + NET_BUFF.length], 60
jb .fail jb .fail
; check if we own the current discriptor ; check if we own the current discriptor
@ -662,29 +660,30 @@ proc transmit stdcall bufferptr, buffersize
jz .wait_to_send jz .wait_to_send
.send_packet: .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 ; get next descriptor
inc [ebx + device.curr_tx_desc] inc [ebx + device.curr_tx_desc]
and [ebx + device.curr_tx_desc], NUM_TX_DESC-1 and [ebx + device.curr_tx_desc], NUM_TX_DESC-1
; Update stats ; Update stats
inc [ebx + device.packets_tx] inc [ebx + device.packets_tx]
mov eax, [buffersize] mov ecx, [esi + NET_BUFF.length]
add dword [ebx + device.bytes_tx], eax add dword [ebx + device.bytes_tx], ecx
adc dword [ebx + device.bytes_tx+4], 0 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" DEBUGF 1, "Packet Sent!\n"
popf popf
xor eax, eax xor eax, eax
@ -710,7 +709,7 @@ proc transmit stdcall bufferptr, buffersize
.fail: .fail:
DEBUGF 2, "transmit failed!\n" DEBUGF 2, "transmit failed!\n"
invoke KernelFree, [bufferptr] invoke NetFree, [bufferptr]
popf popf
or eax, -1 or eax, -1
ret ret
@ -795,18 +794,21 @@ int_handler:
DEBUGF 1, "Received %u bytes\n", ecx DEBUGF 1, "Received %u bytes\n", ecx
push ebx eax 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 pop ecx
test eax, eax ; Test if we allocated succesfully test eax, eax ; Test if we allocated succesfully
jz .abort 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 mov esi, [esp] ; The buffer we will copy from
add esi, 4 ; Dont copy CRC add esi, 4 ; Dont copy CRC
push dword .abort ; Kernel will return to this address after EthReceiver push .abort ; return addr for Eth_input
push ecx edi ; Save buffer pointer and size, to pass to kernel push eax ; buffer ptr for Eth_input
.copy: .copy:
shr ecx, 1 shr ecx, 1
@ -821,7 +823,7 @@ int_handler:
rep movsd rep movsd
.nd: .nd:
jmp [Eth_input] ; Send it to kernel jmp [EthInput] ; Send it to kernel
.abort: .abort:
pop eax ebx pop eax ebx
@ -923,7 +925,7 @@ int_handler:
.no_tok: .no_tok:
DEBUGF 1, "free transmit buffer 0x%x\n", [ebx + device.TX_DESC+ecx]:8 DEBUGF 1, "free transmit buffer 0x%x\n", [ebx + device.TX_DESC+ecx]:8
push ecx ebx push ecx ebx
invoke KernelFree, [ebx + device.TX_DESC+ecx] invoke NetFree, [ebx + device.TX_DESC+ecx]
pop ebx ecx pop ebx ecx
mov [ebx + device.TX_DESC+ecx], 0 mov [ebx + device.TX_DESC+ecx], 0

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -122,6 +122,19 @@ struct NET_DEVICE
ends 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 struct ETH_DEVICE NET_DEVICE
mac dp ? mac dp ?

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -131,7 +131,6 @@ macro ICMP_init {
; and insert packets into sockets when needed ; and insert packets into sockets when needed
; ;
; IN: Pointer to buffer in [esp] ; IN: Pointer to buffer in [esp]
; size of buffer in [esp+4]
; ebx = pointer to device struct ; ebx = pointer to device struct
; ecx = ICMP Packet size ; ecx = ICMP Packet size
; esi = ptr to ICMP Packet data ; esi = ptr to ICMP Packet data
@ -143,10 +142,9 @@ macro ICMP_init {
align 4 align 4
ICMP_input: ICMP_input:
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input:\n" DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input\n"
; First, check the checksum (altough some implementations ignore it)
; Check the checksum
push esi ecx push esi ecx
push [esi + ICMP_header.Checksum] push [esi + ICMP_header.Checksum]
mov [esi + ICMP_header.Checksum], 0 mov [esi + ICMP_header.Checksum], 0
@ -155,100 +153,34 @@ ICMP_input:
call checksum_2 call checksum_2
pop si pop si
cmp dx, si cmp dx, si
pop ecx edx pop ecx esi
jne .checksum_mismatch 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? ; Ualidate device ptr
jne .check_sockets mov eax, edi
; Update stats (and validate device ptr)
call NET_ptr_to_num4 call NET_ptr_to_num4
cmp edi, -1 cmp edi, -1
je .dump je .dump
; Update stats
inc [ICMP_PACKETS_RX + edi] inc [ICMP_PACKETS_RX + edi]
; We well re-use the packet so we can create the response as fast as possible ; Is this an echo request?
; Notice: this only works on pure ethernet 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
; Look for an open ICMP socket
pusha pusha
mov ecx, socket_mutex mov ecx, socket_mutex
call mutex_lock call mutex_lock
popa popa
mov esi, [edi] ; ipv4 source address mov edx, [eax] ; ipv4 source address
mov eax, net_sockets mov eax, net_sockets
.try_more: .try_more:
; mov , [edx + ICMP_header.Identifier] ; mov , [esi + ICMP_header.Identifier]
.next_socket: .next_socket:
mov eax, [eax + SOCKET.NextPtr] mov eax, [eax + SOCKET.NextPtr]
or eax, eax or eax, eax
@ -260,18 +192,12 @@ ICMP_input:
cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP
jne .next_socket jne .next_socket
cmp [eax + IP_SOCKET.RemoteIP], esi cmp [eax + IP_SOCKET.RemoteIP], edx
jne .next_socket jne .next_socket
; cmp [eax + ICMP_SOCKET.Identifier], ; cmp [eax + ICMP_SOCKET.Identifier],
; jne .next_socket ; 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 pusha
mov ecx, socket_mutex mov ecx, socket_mutex
call mutex_unlock call mutex_unlock
@ -284,11 +210,82 @@ ICMP_input:
call mutex_lock call mutex_lock
popa popa
mov esi, edx
jmp SOCKET_input 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 pusha
mov ecx, socket_mutex mov ecx, socket_mutex
call mutex_unlock call mutex_unlock
@ -297,16 +294,12 @@ ICMP_input:
DEBUGF DEBUG_NETWORK_ERROR, "ICMP_input: no socket found\n" DEBUGF DEBUG_NETWORK_ERROR, "ICMP_input: no socket found\n"
jmp .dump jmp .dump
.checksum_mismatch: .checksum_mismatch:
DEBUGF DEBUG_NETWORK_ERROR, "ICMP_input: checksum mismatch\n" DEBUGF DEBUG_NETWORK_ERROR, "ICMP_input: checksum mismatch\n"
.dump: .dump:
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: dumping\n" DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: dumping\n"
call NET_BUFF_free
call NET_packet_free
add esp, 4 ; pop (balance stack)
ret ret
@ -400,7 +393,6 @@ ICMP_output_raw:
jz .exit jz .exit
pop esi pop esi
push edx
push eax push eax
push edi ecx push edi ecx
@ -426,7 +418,6 @@ ICMP_output_raw:
ret ret
.exit: .exit:
DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n" DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
add esp, 4
ret ret

View File

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

View File

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

View File

@ -155,6 +155,10 @@ NET_LINK_IEEE802.11 = 3 ; IEEE 802.11 (WiFi)
NET_HWACC_TCP_IPv4_IN = 1 shl 0 NET_HWACC_TCP_IPv4_IN = 1 shl 0
NET_HWACC_TCP_IPv4_OUT = 1 shl 1 NET_HWACC_TCP_IPv4_OUT = 1 shl 1
; Network frame types
NET_BUFF_LOOPBACK = 0
NET_BUFF_ETH = 1
struct NET_DEVICE struct NET_DEVICE
device_type dd ? ; Type field device_type dd ? ; Type field
@ -175,6 +179,18 @@ struct NET_DEVICE
ends 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.. ; Exactly as it says..
macro pseudo_random reg { macro pseudo_random reg {
@ -327,7 +343,13 @@ stack_handler:
align 4 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 and dword[esp+4], not 0xfff
jmp kernel_free jmp kernel_free
@ -482,8 +504,10 @@ NET_ptr_to_num:
align 4 align 4
NET_ptr_to_num4: ; Todo, place number in device structure so we only need to verify? 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 ecx, NET_DEVICES_MAX
mov edi, NET_DRV_LIST mov edi, NET_DRV_LIST
.loop: .loop:
@ -493,8 +517,9 @@ NET_ptr_to_num4: ; Todo, place number in device structure so we o
dec ecx dec ecx
jnz .loop jnz .loop
or edi, -1
pop ecx pop ecx
.fail:
or edi, -1
ret ret
.found: .found:

View File

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

View File

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

View File

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

View File

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

View File

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