From 0ba1fff7a79c77bc486dd2985c3e4511120d8cd2 Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Tue, 17 Mar 2015 21:50:29 +0000 Subject: [PATCH] New network buffers - phase I git-svn-id: svn://kolibrios.org@5522 a494cfbc-eb01-0410-851d-a64ba20cac60 --- drivers/ethernet/3c59x.asm | 159 +++++++++++++---------- drivers/ethernet/R6040.asm | 100 ++++++++------- drivers/ethernet/RTL8029.asm | 45 +++---- drivers/ethernet/RTL8139.asm | 68 +++++----- drivers/ethernet/RTL8169.asm | 124 ++++++++++-------- drivers/ethernet/dec21x4x.asm | 92 ++++++++------ drivers/ethernet/forcedeth.asm | 75 ++++++----- drivers/ethernet/i8254x.asm | 45 ++++--- drivers/ethernet/i8255x.asm | 75 ++++++----- drivers/ethernet/mtd80x.asm | 77 ++++++++---- drivers/ethernet/pcnet32.asm | 74 +++++++---- drivers/ethernet/rhine.asm | 92 +++++++------- drivers/ethernet/sis900.asm | 42 ++++--- drivers/imports.inc | 5 +- drivers/netdrv.inc | 13 ++ drivers/peimport.inc | 5 +- kernel/trunk/core/exports.inc | 4 +- kernel/trunk/network/ARP.inc | 7 +- kernel/trunk/network/IPv4.inc | 18 +-- kernel/trunk/network/IPv6.inc | 4 +- kernel/trunk/network/PPPoE.inc | 7 +- kernel/trunk/network/ethernet.inc | 113 ++++++++++------- kernel/trunk/network/icmp.inc | 187 +++++++++++++--------------- kernel/trunk/network/loopback.inc | 71 ++++++----- kernel/trunk/network/socket.inc | 14 +-- kernel/trunk/network/stack.inc | 31 ++++- kernel/trunk/network/tcp.inc | 3 +- kernel/trunk/network/tcp_input.inc | 16 +-- kernel/trunk/network/tcp_output.inc | 5 +- kernel/trunk/network/tcp_subr.inc | 4 +- kernel/trunk/network/udp.inc | 16 +-- 31 files changed, 902 insertions(+), 689 deletions(-) diff --git a/drivers/ethernet/3c59x.asm b/drivers/ethernet/3c59x.asm index 6763a9c7ba..ab89c34eff 100644 --- a/drivers/ethernet/3c59x.asm +++ b/drivers/ethernet/3c59x.asm @@ -289,9 +289,7 @@ include '../netdrv.inc' RxBroadcast = 4 RxProm = 8 -; RX/TX buffers sizes - MAX_ETH_PKT_SIZE = 1536 ; max packet size - MAX_ETH_FRAME_SIZE = 1520 ; size of ethernet frame + bytes alignment + MAX_ETH_FRAME_SIZE = 1514 struct tx_desc @@ -806,6 +804,9 @@ end if call set_active_port call create_rx_ring + test eax, eax + jnz .err + call rx_reset call tx_reset @@ -816,11 +817,13 @@ end if mov ecx, 6 rep stosd - + xor eax, eax ret - - + .err: + DEBUGF 2,"reset failed\n" + or eax, -1 + ret align 4 @@ -901,7 +904,8 @@ start_device: mov [ebx + device.mtu], 1514 ; Set link state to unknown - mov [ebx + device.state], ETH_LINK_UNKNOWN + mov [ebx + device.state], ETH_LINK_UNKNOWN + xor eax, eax ret @@ -997,10 +1001,13 @@ create_rx_ring: mov [edx + rx_desc.next_ptr], edi push ecx edx - invoke KernelAlloc, MAX_ETH_FRAME_SIZE + invoke NetAlloc, MAX_ETH_FRAME_SIZE+NET_BUFF.data pop edx ecx + test eax, eax + jz .out_of_mem mov [esi + rx_desc.realaddr], eax - invoke GetPgAddr + invoke GetPhysAddr + add eax, NET_BUFF.data mov [esi + rx_desc.frag_addr], eax and [esi + rx_desc.pkt_status], 0 mov [esi + rx_desc.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31) @@ -1014,6 +1021,11 @@ create_rx_ring: dec ecx jnz .loop + xor eax, eax + ret + + .out_of_mem: + or eax, -1 ret @@ -1039,15 +1051,14 @@ try_link_detect: DEBUGF 1,"Trying to detect link\n" ; create self-directed packet - invoke KernelAlloc, 20 ; create a buffer for the self-directed packet + invoke NetAlloc, 20+NET_BUFF.data ; create a buffer for the self-directed packet test eax, eax jz .fail - pushd 20 ; Packet parameters for device.transmit - push eax ; - - mov edi, eax + push eax + mov [eax + NET_BUFF.length], 20 + lea edi, [eax + NET_BUFF.data] lea esi, [ebx + device.mac] movsw movsd @@ -1092,10 +1103,12 @@ try_link_detect: jz @f or byte [ebx + device.internal_link+1], 100b @@: + xor eax, eax ret .fail: DEBUGF 1,"No link detected!\n" + or eax, -1 ret @@ -1135,7 +1148,7 @@ try_phy: ; wait for reset to complete mov esi, 2000 - invoke Sleep ; 2s + invoke Sleep ; 2s FIXME mov eax, [esp] call mdio_read ; returns with window #4 test ah, 0x80 @@ -1144,7 +1157,7 @@ try_phy: ; wait for a while after reset mov esi, 20 - invoke Sleep ; 20ms + invoke Sleep ; 20ms mov eax, [esp] mov al , MII_BMSR call mdio_read ; returns with window #4 @@ -1407,14 +1420,15 @@ test_packet: call tx_reset ; create self-directed packet - invoke KernelAlloc, 20 ; create a buffer for the self-directed packet + invoke NetAlloc, 20 + NET_BUFF.data ; create a buffer for the self-directed packet test eax, eax jz .fail - pushd 20 ; Packet parameters for device.transmit - push eax ; + push eax + mov [eax + NET_BUFF.length], 20 +; mov [eax + NET_BUFF.device], ebx - mov edi, eax + lea edi, [eax + NET_BUFF.data] lea esi, [ebx + device.mac] movsw movsd @@ -1428,7 +1442,7 @@ test_packet: call [ebx + device.transmit] ; wait for 2s - mov esi, 2000 + mov esi, 2000 ; FIXME invoke Sleep ; check if self-directed packet is received @@ -2124,26 +2138,26 @@ check_tx_status: ;; Transmit (vortex) ;; ;; ;; ;; In: buffer pointer in [esp+4] ;; -;; size of buffer in [esp+8] ;; ;; pointer to device structure in ebx ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -proc vortex_transmit stdcall bufferptr, buffersize +proc vortex_transmit stdcall bufferptr pushf cli - DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] - mov eax, [bufferptr] + mov esi, [bufferptr] + DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] + lea eax, [esi + NET_BUFF.data] DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ [eax+13]:2,[eax+12]:2 - cmp [buffersize], 1514 + cmp [esi + NET_BUFF.length], 1514 ja .fail - cmp [buffersize], 60 + cmp [esi + NET_BUFF.length], 60 jb .fail call check_tx_status @@ -2153,20 +2167,25 @@ proc vortex_transmit stdcall bufferptr, buffersize set_io [ebx + device.io_addr], REG_COMMAND mov ax, SELECT_REGISTER_WINDOW+7 out dx, ax + ; check for master operation in progress set_io [ebx + device.io_addr], REG_MASTER_STATUS in ax, dx test ah, 0x80 jnz .fail ; no DMA for sending + ; program frame address to be sent set_io [ebx + device.io_addr], REG_MASTER_ADDRESS - mov eax, [bufferptr] + mov eax, esi + add eax, [eax + NET_BUFF.offset] invoke GetPhysAddr out dx, eax + ; program frame length set_io [ebx + device.io_addr], REG_MASTER_LEN - mov eax, [buffersize] + mov eax, [esi + NET_BUFF.length] out dx, ax + ; start DMA Down set_io [ebx + device.io_addr], REG_COMMAND mov ax, (10100b shl 11) + 1 ; StartDMADown @@ -2178,7 +2197,7 @@ proc vortex_transmit stdcall bufferptr, buffersize .fail: DEBUGF 2,"Send failed\n" - invoke KernelFree, [bufferptr] + invoke NetFree, [bufferptr] popf or eax, -1 ret @@ -2190,38 +2209,38 @@ endp ;; Transmit (boomerang) ;; ;; ;; ;; In: buffer pointer in [esp+4] ;; -;; size of buffer in [esp+8] ;; ;; pointer to device structure in ebx ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -proc boomerang_transmit stdcall bufferptr, buffersize +proc boomerang_transmit stdcall bufferptr pushf cli - DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] - mov eax, [bufferptr] + mov esi, [bufferptr] + DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] + lea eax, [esi + NET_BUFF.data] DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ [eax+13]:2,[eax+12]:2 - cmp [buffersize], 1514 + cmp [esi + NET_BUFF.length], 1514 ja .fail - cmp [buffersize], 60 + cmp [esi + NET_BUFF.length], 60 jb .fail call check_tx_status ; Reset TX engine if needed ; calculate descriptor address - mov esi, [ebx + device.curr_tx] - DEBUGF 1,"Previous TX desc: %x\n", esi - add esi, sizeof.tx_desc + mov edi, [ebx + device.curr_tx] + DEBUGF 1,"Previous TX desc: %x\n", edi + add edi, sizeof.tx_desc lea ecx, [ebx + device.tx_desc_buffer + (NUM_TX_DESC)*sizeof.tx_desc] - cmp esi, ecx + cmp edi, ecx jb @f - lea esi, [ebx + device.tx_desc_buffer] ; Wrap if needed + lea edi, [ebx + device.tx_desc_buffer] ; Wrap if needed @@: DEBUGF 1,"Using TX desc: %x\n", esi @@ -2239,31 +2258,32 @@ proc boomerang_transmit stdcall bufferptr, buffersize ; update statistics inc [ebx + device.packets_tx] - mov ecx, [buffersize] + mov ecx, [esi + NET_BUFF.length] add dword [ebx + device.bytes_tx], ecx adc dword [ebx + device.bytes_tx + 4], 0 ; program DPD - and [esi + tx_desc.next_ptr], 0 + and [edi + tx_desc.next_ptr], 0 mov eax, [bufferptr] - mov [esi + tx_desc.realaddr], eax + mov [edi + tx_desc.realaddr], eax + add eax, [eax + NET_BUFF.offset] invoke GetPhysAddr - mov [esi + tx_desc.frag_addr], eax - mov ecx, [buffersize] + mov [edi + tx_desc.frag_addr], eax +;;; mov ecx, [buffersize] or ecx, 0x80000000 ; last fragment flag - mov [esi + tx_desc.frag_len], ecx + mov [edi + tx_desc.frag_len], ecx - mov ecx, [buffersize] ; packet size +;;; mov ecx, [buffersize] ; packet size or ecx, 0x80008000 ; set OWN bit + transmission complete notification flag ; test byte [ebx + device.has_hwcksm], 0xff ; jz @f ; or ecx, (1 shl 26) ; set AddTcpChecksum ;@@: - mov [esi + tx_desc.frame_start_hdr], ecx - DEBUGF 1,"TX desc: lin=%x phys=%x len=%x start hdr=%x\n", [esi+tx_desc.realaddr]:8, [esi+tx_desc.frag_addr]:8, [esi+tx_desc.frag_len]:8, [esi+tx_desc.frame_start_hdr]:8 + mov [edi + tx_desc.frame_start_hdr], ecx + DEBUGF 1,"TX desc: lin=%x phys=%x len=%x start hdr=%x\n", [edi+tx_desc.realaddr]:8, [edi+tx_desc.frag_addr]:8, [edi+tx_desc.frag_len]:8, [edi+tx_desc.frame_start_hdr]:8 ; calculate physical address of tx descriptor - mov eax, esi + mov eax, edi invoke GetPhysAddr cmp [ebx + device.dn_list_ptr_cleared], 0 je .add_to_list @@ -2318,14 +2338,14 @@ proc boomerang_transmit stdcall bufferptr, buffersize out dx, ax .finish: - mov [ebx + device.curr_tx], esi + mov [ebx + device.curr_tx], edi popf xor eax, eax ret .fail: DEBUGF 2,"Send failed\n" - invoke KernelFree, [bufferptr] + invoke NetFree, [bufferptr] popf or eax, -1 ret @@ -2493,7 +2513,7 @@ int_vortex: .check_length: and eax, 0x1fff - cmp eax, MAX_ETH_PKT_SIZE + cmp eax, MAX_ETH_FRAME_SIZE ja .discard_frame ; frame is too long discard it .check_dma: @@ -2513,15 +2533,18 @@ int_vortex: .read_frame: ; program buffer address to read in push ecx - invoke KernelAlloc, MAX_ETH_FRAME_SIZE + invoke NetAlloc, MAX_ETH_FRAME_SIZE + NET_BUFF.data pop ecx test eax, eax jz .finish push .discard_frame - push ecx push eax -; zero_to_dma eax + mov [eax + NET_BUFF.length], ecx + mov [eax + NET_BUFF.device], ebx + mov [eax + NET_BUFF.offset], NET_BUFF.data + invoke GetPhysAddr + add eax, NET_BUFF.data set_io [ebx + device.io_addr], REG_MASTER_ADDRESS out dx, eax @@ -2543,7 +2566,7 @@ int_vortex: jnz .dma_loop ; registrate the received packet to kernel - jmp Eth_input + jmp [EthInput] ; discard the top frame received .discard_frame: @@ -2555,7 +2578,7 @@ int_vortex: .finish: -.noRX: + .noRX: test ax, DMADone jz .noDMA @@ -2579,11 +2602,11 @@ int_vortex: -.noDMA: + .noDMA: -.ACK: + .ACK: set_io [ebx + device.io_addr], 0 set_io [ebx + device.io_addr], REG_COMMAND mov ax, AckIntr + IntReq + IntLatch @@ -2678,8 +2701,11 @@ int_boomerang: DEBUGF 1, "Received %u bytes in buffer %x\n", ecx, [esi + rx_desc.realaddr]:8 push dword .loop ;.finish - push ecx - push [esi + rx_desc.realaddr] + mov eax, [esi + rx_desc.realaddr] + push eax + mov [eax + NET_BUFF.length], ecx + mov [eax + NET_BUFF.device], ebx + mov [eax + NET_BUFF.offset], NET_BUFF.data ; update statistics inc [ebx + device.packets_rx] @@ -2687,9 +2713,10 @@ int_boomerang: adc dword [ebx + device.bytes_rx + 4], 0 ; update rx descriptor (Alloc new buffer for next packet) - invoke KernelAlloc, MAX_ETH_FRAME_SIZE + invoke NetAlloc, MAX_ETH_FRAME_SIZE + NET_BUFF.data mov [esi + rx_desc.realaddr], eax invoke GetPhysAddr + add eax, NET_BUFF.data mov [esi + rx_desc.frag_addr], eax and [esi + rx_desc.pkt_status], 0 mov [esi + rx_desc.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31) @@ -2704,7 +2731,7 @@ int_boomerang: mov [ebx + device.curr_rx], esi DEBUGF 1, "Next RX desc: %x\n", esi - jmp [Eth_input] + jmp [EthInput] .loop: mov ebx, [esp] @@ -2742,7 +2769,7 @@ int_boomerang: and [esi+tx_desc.frame_start_hdr], 0 push ecx - invoke KernelFree, [esi+tx_desc.realaddr] + invoke NetFree, [esi+tx_desc.realaddr] pop ecx .maybenext: diff --git a/drivers/ethernet/R6040.asm b/drivers/ethernet/R6040.asm index 3341846430..ce666e1304 100644 --- a/drivers/ethernet/R6040.asm +++ b/drivers/ethernet/R6040.asm @@ -137,7 +137,7 @@ PHY_ST = 0x8A ; PHY status register MAC_SM = 0xAC ; MAC status machine MAC_ID = 0xBE ; Identifier register -MAX_BUF_SIZE = 0x600 ; 1536 +MAX_BUF_SIZE = 1514 MBCR_DEFAULT = 0x012A ; MAC Bus Control Register MCAST_MAX = 3 ; Max number multicast addresses to filter @@ -396,13 +396,12 @@ unload: ; ; - Stop the device ; - Detach int handler - ; - Remove device from local list (RTL8139_LIST) + ; - Remove device from local list (device_list) ; - call unregister function in kernel ; - Remove all allocated structures and buffers the card used - or eax,-1 - -ret + or eax, -1 + ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -430,7 +429,7 @@ probe: jnz @f mov ax, 0x9F07 out dx, ax - @@: + @@: call read_mac @@ -441,7 +440,7 @@ probe: jnz @f DEBUGF 2, "MAC address not initialized!\n" - @@: + @@: ; Init RDC private data mov [ebx + device.mcr0], MCR0_XMTEN or MCR0_RCVEN mov [ebx + device.phy_addr], PHY1_ADDR @@ -452,9 +451,10 @@ probe: cmp ax, 0xFFFF jne @f DEBUGF 2, "Failed to detect an attached PHY!\n" + .err: mov eax, -1 ret - @@: + @@: ; Set MAC address call init_mac_regs @@ -462,6 +462,8 @@ probe: ; Initialize and alloc RX/TX buffers call init_txbufs call init_rxbufs + test eax, eax + jnz .err ; Read the PHY ID mov [ebx + device.phy_mode], MCR0_FD @@ -471,7 +473,7 @@ probe: jne @f stdcall phy_write, 29, 31, 0x175C ; Enable registers jmp .phy_readen - @@: + @@: ; PHY Mode Check stdcall phy_write, [ebx + device.phy_addr], 4, PHY_CAP @@ -487,7 +489,7 @@ probe: mov [ebx + device.phy_mode], 0 end if - .phy_readen: + .phy_readen: ; Set duplex mode mov ax, [ebx + device.phy_mode] @@ -530,7 +532,7 @@ reset: DEBUGF 2,"Could not attach int handler!\n" or eax, -1 ret - @@: + @@: ;Reset RDC MAC mov eax, MAC_RST @@ -632,7 +634,7 @@ init_txbufs: invoke GetPhysAddr mov ecx, TX_RING_SIZE - .next_desc: + .next_desc: mov [esi + x_head.ndesc], eax mov [esi + x_head.skb_ptr], 0 mov [esi + x_head.status], DSC_OWNER_MAC @@ -660,21 +662,21 @@ init_rxbufs: mov edx, eax mov ecx, RX_RING_SIZE - .next_desc: + .next_desc: mov [esi + x_head.ndesc], edx - push esi ecx edx - invoke KernelAlloc, MAX_BUF_SIZE + invoke NetAlloc, MAX_BUF_SIZE+NET_BUFF.data pop edx ecx esi - + test eax, eax + jz .out_of_mem mov [esi + x_head.skb_ptr], eax invoke GetPhysAddr + add eax, NET_BUFF.data mov [esi + x_head.buf], eax mov [esi + x_head.status], DSC_OWNER_MAC add edx, sizeof.x_head add esi, sizeof.x_head - dec ecx jnz .next_desc @@ -683,6 +685,11 @@ init_rxbufs: invoke GetPhysAddr mov dword[ebx + device.rx_ring + sizeof.x_head*(RX_RING_SIZE-1) + x_head.ndesc], eax + xor eax, eax + ret + + .out_of_mem: + or eax, -1 ret @@ -734,21 +741,22 @@ phy_mode_chk: ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -proc transmit stdcall bufferptr, buffersize +proc transmit stdcall bufferptr pushf cli - DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] - mov eax, [bufferptr] + mov esi, [bufferptr] + DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] + lea eax, [esi + NET_BUFF.data] DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ [eax+13]:2,[eax+12]:2 - cmp [buffersize], 1514 + cmp [esi + NET_BUFF.length], 1514 ja .fail - cmp [buffersize], 60 + cmp [esi + NET_BUFF.length], 60 jb .fail movzx edi, [ebx + device.cur_tx] @@ -764,11 +772,12 @@ proc transmit stdcall bufferptr, buffersize .do_send: DEBUGF 1,"Sending now\n" - mov eax, [bufferptr] - mov [edi + x_head.skb_ptr], eax + mov [edi + x_head.skb_ptr], esi + mov eax, esi + add eax, [eax + NET_BUFF.offset] invoke GetPhysAddr mov [edi + x_head.buf], eax - mov ecx, [buffersize] + mov ecx, [esi + NET_BUFF.length] mov [edi + x_head.len], cx mov [edi + x_head.status], DSC_OWNER_MAC @@ -783,7 +792,7 @@ proc transmit stdcall bufferptr, buffersize ; Update stats inc [ebx + device.packets_tx] - mov eax, [buffersize] + mov eax, [esi + NET_BUFF.length] add dword[ebx + device.bytes_tx], eax adc dword[ebx + device.bytes_tx + 4], 0 @@ -793,22 +802,25 @@ proc transmit stdcall bufferptr, buffersize .wait_to_send: DEBUGF 1,"Waiting for TX buffer\n" - invoke GetTimerTicks ; returns in eax lea edx, [eax + 100] - .l2: + .l2: + mov esi, [bufferptr] test [edi + x_head.status], DSC_OWNER_MAC jz .do_send + popf mov esi, 10 invoke Sleep invoke GetTimerTicks + pushf + cli cmp edx, eax jb .l2 DEBUGF 2,"Send timeout\n" .fail: DEBUGF 2,"Send failed\n" - invoke KernelFree, [bufferptr] + invoke NetFree, [bufferptr] popf or eax, -1 ret @@ -890,26 +902,29 @@ int_handler: and ecx, 0xFFF sub ecx, 4 ; Do not count the CRC + DEBUGF 1,"packet ptr=0x%x size=%u\n", [edx + x_head.skb_ptr], ecx + ; Update stats add dword[ebx + device.bytes_rx], ecx adc dword[ebx + device.bytes_rx + 4], 0 inc dword[ebx + device.packets_rx] - ; Push packet size and pointer, kernel will need it.. push ebx + ; Push packet ptr and return addr for Eth_input push .more_RX + mov eax, [edx + x_head.skb_ptr] + push eax + mov [eax + NET_BUFF.length], ecx + mov [eax + NET_BUFF.device], ebx + mov [eax + NET_BUFF.offset], NET_BUFF.data - push ecx - push [edx + x_head.skb_ptr] - - DEBUGF 1,"packet ptr=0x%x\n", [edx + x_head.skb_ptr] - - ; reset the RX descriptor + ; reset the RX descriptor (alloc new buffer) push edx - invoke KernelAlloc, MAX_BUF_SIZE + invoke NetAlloc, MAX_BUF_SIZE+NET_BUFF.data pop edx mov [edx + x_head.skb_ptr], eax invoke GetPhysAddr + add eax, NET_BUFF.data mov [edx + x_head.buf], eax mov [edx + x_head.status], DSC_OWNER_MAC @@ -918,15 +933,14 @@ int_handler: and [ebx + device.cur_rx], RX_RING_SIZE - 1 ; At last, send packet to kernel - jmp [Eth_input] + jmp [EthInput] .no_RX: - test word[esp], TX_FINISH jz .no_TX - .loop_tx: + .loop_tx: movzx edi, [ebx + device.last_tx] shl edi, 5 lea edi, [ebx + device.tx_ring + edi] @@ -941,7 +955,7 @@ int_handler: push [edi + x_head.skb_ptr] mov [edi + x_head.skb_ptr], 0 - invoke KernelFree + invoke NetFree inc [ebx + device.last_tx] and [ebx + device.last_tx], TX_RING_SIZE - 1 @@ -1106,13 +1120,13 @@ read_mac: lea edi, [ebx + device.mac] set_io [ebx + device.io_addr], 0 set_io [ebx + device.io_addr], MID_0L - .mac: + .loop: in ax, dx stosw inc dx inc dx dec cx - jnz .mac + jnz .loop DEBUGF 1,"%x-%x-%x-%x-%x-%x\n",\ [edi-6]:2, [edi-5]:2, [edi-4]:2, [edi-3]:2, [edi-2]:2, [edi-1]:2 diff --git a/drivers/ethernet/RTL8029.asm b/drivers/ethernet/RTL8029.asm index c71f2b1cab..7574e46634 100644 --- a/drivers/ethernet/RTL8029.asm +++ b/drivers/ethernet/RTL8029.asm @@ -665,17 +665,18 @@ reset: ;*************************************************************************** ; Function ; transmit -; buffer in [esp+4], size in [esp+8], pointer to device struct in ebx +; buffer in [esp+4], pointer to device struct in ebx ;*************************************************************************** -proc transmit stdcall buffer_ptr, buffer_size +proc transmit stdcall buffer_ptr pushf cli mov esi, [buffer_ptr] - mov ecx, [buffer_size] - DEBUGF 1, "Transmitting packet, buffer:%x, size:%u\n", esi, ecx + mov ecx, [esi + NET_BUFF.length] + DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", esi, ecx + lea eax, [esi + NET_BUFF.data] DEBUGF 1, "To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ [esi+0]:2,[esi+1]:2,[esi+2]:2,[esi+3]:2,[esi+4]:2,[esi+5]:2,[esi+6]:2,[esi+7]:2,[esi+8]:2,[esi+9]:2,[esi+10]:2,[esi+11]:2,[esi+13]:2,[esi+12]:2 @@ -686,9 +687,10 @@ proc transmit stdcall buffer_ptr, buffer_size movzx edi, [ebx + device.tx_start] shl edi, 8 - push cx + add esi, [esi + NET_BUFF.offset] + push ecx call PIO_write - pop cx + pop ecx set_io [ebx + device.io_addr], 0 ; set_io [ebx + device.io_addr], P0_COMMAND @@ -714,18 +716,17 @@ proc transmit stdcall buffer_ptr, buffer_size DEBUGF 1, "Packet Sent!\n" inc [ebx + device.packets_tx] - mov eax, [buffer_size] - add dword[ebx + device.bytes_tx], eax + add dword[ebx + device.bytes_tx], ecx adc dword[ebx + device.bytes_tx + 4], 0 - invoke KernelFree, [buffer_ptr] + invoke NetFree, [buffer_ptr] popf xor eax, eax ret .err: DEBUGF 2, "Transmit error!\n" - invoke KernelFree, [buffer_ptr] + invoke NetFree, [buffer_ptr] popf or eax, -1 ret @@ -785,14 +786,15 @@ int_handler: jz .no_rx ; FIXME: Only PIO mode supported for now ; allocate a buffer - invoke KernelAlloc, ETH_FRAME_LEN + invoke NetAlloc, ETH_FRAME_LEN+NET_BUFF.data test eax, eax jz .rx_fail_2 ; Push return address and packet ptr to stack pushd .no_rx - pushd 0 ; Reserve some space for the packet size push eax + mov [eax + NET_BUFF.device], ebx + mov [eax + NET_BUFF.offset], NET_BUFF.data ; read offset for current packet from device set_io [ebx + device.io_addr], 0 @@ -809,7 +811,7 @@ int_handler: mov al, CMD_PS1 out dx, al set_io [ebx + device.io_addr], P1_CURR - in al, dx ; get current page in cl + in al, dx ; get current page in cl mov cl, al set_io [ebx + device.io_addr], P1_COMMAND @@ -823,11 +825,11 @@ int_handler: cmp cl, ch je .rx_fail - movzx esi, ch ; we are using 256 byte pages - shl esi, 8 ; esi now holds the offset for current packet + movzx esi, ch ; we are using 256 byte pages + shl esi, 8 ; esi now holds the offset for current packet -; Get packet header in ecx - push ecx ; reserve 4 bytes on stack to put packet header in +; Write packet header to frame header size field + push ecx mov edi, esp mov cx, 4 call PIO_read @@ -839,8 +841,9 @@ int_handler: ; calculate packet length in ecx shr ecx, 16 - sub ecx, 4 ; CRC doesnt count as data byte - mov [esp + 8], ecx + sub ecx, 4 ; CRC doesnt count as data byte + mov edi, [esp+4] + mov [edi + NET_BUFF.length], ecx ; check if packet size is ok cmp ecx, ETH_ZLEN @@ -856,7 +859,7 @@ int_handler: ; update read and write pointers add esi, 4 - mov edi, [esp + 4] + add edi, NET_BUFF.data ; now check if we can read all data at once (if we cross the end boundary, we need to wrap back to the beginning) xor eax, eax @@ -894,7 +897,7 @@ int_handler: out dx, al ; now send the data to the kernel - jmp [Eth_input] + jmp [EthInput] .rx_fail_3: add esp, 4 diff --git a/drivers/ethernet/RTL8139.asm b/drivers/ethernet/RTL8139.asm index 72091cd7f7..02f4847813 100644 --- a/drivers/ethernet/RTL8139.asm +++ b/drivers/ethernet/RTL8139.asm @@ -404,8 +404,7 @@ unload: ; - Remove all allocated structures and buffers the card used or eax, -1 - -ret + ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -628,27 +627,26 @@ reset: ;; ;; ;; Transmit ;; ;; ;; -;; In: buffer pointer in [esp+4] ;; -;; size of buffer in [esp+8] ;; -;; pointer to device structure in ebx ;; +;; In: pointer to device structure in ebx ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -proc transmit stdcall bufferptr, buffersize +proc transmit stdcall bufferptr pushf cli - DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] - mov eax, [bufferptr] + mov esi, [bufferptr] + DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] + lea eax, [esi + NET_BUFF.data] DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ [eax+13]:2,[eax+12]:2 - cmp [buffersize], 1514 + cmp [esi + NET_BUFF.length], 1514 ja .fail - cmp [buffersize], 60 + cmp [esi + NET_BUFF.length], 60 jb .fail ; check if we own the current discriptor @@ -662,29 +660,30 @@ proc transmit stdcall bufferptr, buffersize jz .wait_to_send .send_packet: +; Set the buffer address + set_io [ebx + device.io_addr], REG_TSAD0 + mov [ebx + device.TX_DESC+ecx], esi + mov eax, esi + add eax, [eax + NET_BUFF.offset] + invoke GetPhysAddr + out dx, eax + +; And the size of the buffer + set_io [ebx + device.io_addr], REG_TSD0 + mov eax, [esi + NET_BUFF.length] + or eax, (ERTXTH shl BIT_ERTXTH) ; Early threshold + out dx, eax + ; get next descriptor inc [ebx + device.curr_tx_desc] and [ebx + device.curr_tx_desc], NUM_TX_DESC-1 ; Update stats inc [ebx + device.packets_tx] - mov eax, [buffersize] - add dword [ebx + device.bytes_tx], eax + mov ecx, [esi + NET_BUFF.length] + add dword [ebx + device.bytes_tx], ecx adc dword [ebx + device.bytes_tx+4], 0 -; Set the buffer address - set_io [ebx + device.io_addr], REG_TSAD0 - mov eax, [bufferptr] - mov [ebx + device.TX_DESC+ecx], eax - invoke GetPhysAddr - out dx, eax - -; And the size of the buffer - set_io [ebx + device.io_addr], REG_TSD0 - mov eax, [buffersize] - or eax, (ERTXTH shl BIT_ERTXTH) ; Early threshold - out dx, eax - DEBUGF 1, "Packet Sent!\n" popf xor eax, eax @@ -710,7 +709,7 @@ proc transmit stdcall bufferptr, buffersize .fail: DEBUGF 2, "transmit failed!\n" - invoke KernelFree, [bufferptr] + invoke NetFree, [bufferptr] popf or eax, -1 ret @@ -795,18 +794,21 @@ int_handler: DEBUGF 1, "Received %u bytes\n", ecx push ebx eax ecx - invoke KernelAlloc, ecx ; Allocate a buffer to put packet into + add ecx, NET_BUFF.data + invoke NetAlloc, ecx ; Allocate a buffer to put packet into pop ecx test eax, eax ; Test if we allocated succesfully jz .abort + mov [eax + NET_BUFF.length], ecx + mov [eax + NET_BUFF.device], ebx + mov [eax + NET_BUFF.offset], NET_BUFF.data - mov edi, eax ; Where we will copy too - + lea edi, [eax + NET_BUFF.data] ; Where we will copy too mov esi, [esp] ; The buffer we will copy from add esi, 4 ; Dont copy CRC - push dword .abort ; Kernel will return to this address after EthReceiver - push ecx edi ; Save buffer pointer and size, to pass to kernel + push .abort ; return addr for Eth_input + push eax ; buffer ptr for Eth_input .copy: shr ecx, 1 @@ -821,7 +823,7 @@ int_handler: rep movsd .nd: - jmp [Eth_input] ; Send it to kernel + jmp [EthInput] ; Send it to kernel .abort: pop eax ebx @@ -923,7 +925,7 @@ int_handler: .no_tok: DEBUGF 1, "free transmit buffer 0x%x\n", [ebx + device.TX_DESC+ecx]:8 push ecx ebx - invoke KernelFree, [ebx + device.TX_DESC+ecx] + invoke NetFree, [ebx + device.TX_DESC+ecx] pop ebx ecx mov [ebx + device.TX_DESC+ecx], 0 diff --git a/drivers/ethernet/RTL8169.asm b/drivers/ethernet/RTL8169.asm index d2750f76f2..e78955162c 100644 --- a/drivers/ethernet/RTL8169.asm +++ b/drivers/ethernet/RTL8169.asm @@ -175,10 +175,10 @@ include '../netdrv.inc' DSB_FSbit = 0x20000000 DSB_LSbit = 0x10000000 - RX_BUF_SIZE = 1536 ; Rx Buffer size + RX_BUF_SIZE = 1514 ; Rx Buffer size ; max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4) - MAX_ETH_FRAME_SIZE = 1536 + MAX_ETH_FRAME_SIZE = 1514 TX_FIFO_THRESH = 256 ; In bytes @@ -200,7 +200,7 @@ include '../netdrv.inc' ETH_HDR_LEN = 14 DEFAULT_MTU = 1500 - DEFAULT_RX_BUF_LEN = 1536 + DEFAULT_RX_BUF_LEN = 1514 ;ifdef JUMBO_FRAME_SUPPORT @@ -662,6 +662,9 @@ reset: DEBUGF 1,"resetting\n" call init_ring + test eax, eax + jnz .err + call hw_start ; clear packet/byte counters @@ -678,7 +681,10 @@ reset: xor eax, eax ret - + .err: + DEBUGF 2,"failed!\n" + or eax, -1 + ret @@ -800,9 +806,12 @@ init_ring: mov ecx, NUM_RX_DESC .loop: push ecx - invoke KernelAlloc, RX_BUF_SIZE + invoke NetAlloc, RX_BUF_SIZE+NET_BUFF.data + test eax, eax + jz .err mov dword [edi + rx_desc.buf_soft_addr], eax invoke GetPhysAddr + add eax, NET_BUFF.data mov dword [edi + rx_desc.buf_addr], eax mov [edi + rx_desc.status], DSB_OWNbit or RX_BUF_SIZE add edi, sizeof.rx_desc @@ -811,8 +820,13 @@ init_ring: jnz .loop or [edi - sizeof.rx_desc + rx_desc.status], DSB_EORbit + xor eax, eax ret + .err: + pop eax + or eax, -1 + ret align 4 hw_start: @@ -990,21 +1004,22 @@ write_mac: ; ;*************************************************************************** -proc transmit stdcall bufferptr, buffersize +proc transmit stdcall bufferptr pushf cli - DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] - mov eax, [bufferptr] + mov esi, [bufferptr] + DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] + lea eax, [esi + NET_BUFF.data] DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ [eax+13]:2,[eax+12]:2 - cmp [buffersize], 1514 + cmp [esi + NET_BUFF.length], 1514 ja .fail - cmp [buffersize], 60 + cmp [esi + NET_BUFF.length], 60 jb .fail ;---------------------------------- @@ -1026,15 +1041,16 @@ proc transmit stdcall bufferptr, buffersize ; Program the packet pointer mov eax, [bufferptr] + mov ecx, [eax + NET_BUFF.length] mov [esi + tx_desc.buf_soft_addr], eax + add eax, [eax + NET_BUFF.offset] invoke GetPhysAddr mov dword [esi + tx_desc.buf_addr], eax ;------------------------ ; Program the packet size - mov eax, [buffersize] - @@: + mov eax, ecx or eax, DSB_OWNbit or DSB_FSbit or DSB_LSbit cmp [ebx + device.cur_tx], NUM_TX_DESC - 1 jne @f @@ -1060,8 +1076,7 @@ proc transmit stdcall bufferptr, buffersize ; Update stats inc [ebx + device.packets_tx] - mov eax, [buffersize] - add dword [ebx + device.bytes_tx], eax + add dword [ebx + device.bytes_tx], ecx adc dword [ebx + device.bytes_tx + 4], 0 popf @@ -1072,7 +1087,7 @@ proc transmit stdcall bufferptr, buffersize DEBUGF 2,"Descriptor is still in use!\n" .fail: DEBUGF 2,"Transmit failed\n" - invoke KernelFree, [bufferptr] + invoke NetFree, [bufferptr] popf or eax, -1 ret @@ -1139,38 +1154,44 @@ int_handler: lea esi, [ebx + device.rx_ring + eax] DEBUGF 1,"RxDesc.status = 0x%x\n", [esi + rx_desc.status] - mov eax, [esi + rx_desc.status] - test eax, DSB_OWNbit ;;; - jnz .no_own + mov ecx, [esi + rx_desc.status] + test ecx, DSB_OWNbit ;;; + jnz .rx_return DEBUGF 1,"cur_rx = %u\n", [ebx + device.cur_rx] - test eax, SD_RxRES + test ecx, SD_RxRES jnz .rx_return ;;;;; RX error! push ebx push .check_more - and eax, 0x00001FFF - add eax, -4 ; we dont need CRC + and ecx, 0x00001FFF + add ecx, -4 ; we dont need CRC + DEBUGF 1,"data length = %u\n", ecx + mov eax, [esi + rx_desc.buf_soft_addr] push eax - DEBUGF 1,"data length = %u\n", ax + mov [eax + NET_BUFF.length], ecx + mov [eax + NET_BUFF.device], ebx + mov [eax + NET_BUFF.offset], NET_BUFF.data - ; Update stats +;------------- +; Update stats add dword [ebx + device.bytes_rx], eax adc dword [ebx + device.bytes_rx + 4], 0 inc [ebx + device.packets_rx] - pushd [esi + rx_desc.buf_soft_addr] +;---------------------- +; Allocate a new buffer - ; Allocate a new buffer - - invoke KernelAlloc, RX_BUF_SIZE + invoke NetAlloc, RX_BUF_SIZE+NET_BUFF.data mov [esi + rx_desc.buf_soft_addr], eax invoke GetPhysAddr + add eax, NET_BUFF.data mov dword [esi + rx_desc.buf_addr], eax - ; reset OWN bit +;--------------- +; re set OWN bit mov eax, DSB_OWNbit or RX_BUF_SIZE cmp [ebx + device.cur_rx], NUM_RX_DESC - 1 @@ -1179,15 +1200,15 @@ int_handler: @@: mov [esi + rx_desc.status], eax - ; Update rx ptr +;-------------- +; Update rx ptr inc [ebx + device.cur_rx] and [ebx + device.cur_rx], NUM_RX_DESC - 1 - jmp [Eth_input] + jmp [EthInput] .rx_return: - DEBUGF 1,"RX error!\n" - .no_own: + pop ax .no_rx: @@ -1196,30 +1217,31 @@ int_handler: test ax, ISB_TxOK or ISB_TxErr or ISB_TxDescUnavail jz .no_tx + push ax DEBUGF 1,"TX done!\n" - .txloop: - mov esi, [ebx + device.last_tx] - imul esi, sizeof.tx_desc - lea esi, [ebx + device.tx_ring + esi] + mov ecx, NUM_TX_DESC + lea esi, [ebx + device.tx_ring] + .txloop: cmp dword [esi + tx_desc.buf_soft_addr], 0 - je .no_tx + jz .maybenext test [esi + tx_desc.status], DSB_OWNbit - jnz .no_tx + jnz .maybenext - DEBUGF 1,"Freeing up TX desc: 0x%x\n", esi - DEBUGF 1,"buff: 0x%x\n", [esi + tx_desc.buf_soft_addr] - push eax - push dword [esi + tx_desc.buf_soft_addr] + push ecx + DEBUGF 1,"Freeing up TX desc: %x\n", esi + invoke NetFree, [esi + tx_desc.buf_soft_addr] + pop ecx and dword [esi + tx_desc.buf_soft_addr], 0 - invoke KernelFree - pop eax - inc [ebx + device.last_tx] - and [ebx + device.last_tx], NUM_TX_DESC-1 - jmp .txloop + .maybenext: + add esi, sizeof.tx_desc + dec ecx + jnz .txloop + + pop ax .no_tx: test ax, ISB_LinkChg @@ -1333,10 +1355,10 @@ dd 0x7cf00000, 0x28800000, 27, name_27 dd 0x7cf00000, 0x28a00000, 28, name_27 ; 8168C family. -dd 0x7cf00000, 0x3cb00000, 24, name_23 -dd 0x7cf00000, 0x3c900000, 23, name_23 +dd 0x7cf00000, 0x3cb00000, 24, name_18 +dd 0x7cf00000, 0x3c900000, 23, name_18 dd 0x7cf00000, 0x3c800000, 18, name_18 -dd 0x7c800000, 0x3c800000, 24, name_23 +dd 0x7c800000, 0x3c800000, 24, name_18 dd 0x7cf00000, 0x3c000000, 19, name_19 dd 0x7cf00000, 0x3c200000, 20, name_19 dd 0x7cf00000, 0x3c300000, 21, name_19 @@ -1401,7 +1423,7 @@ name_19 db "RTL8168c/8111c",0 ;name_20 db "RTL8168c/8111c",0 ;name_21 db "RTL8168c/8111c",0 ;name_22 db "RTL8168c/8111c",0 -name_23 db "RTL8168cp/8111cp",0 +;name_23 db "RTL8168cp/8111cp",0 ;name_24 db "RTL8168cp/8111cp",0 name_25 db "RTL8168d/8111d",0 ;name_26 db "RTL8168d/8111d",0 diff --git a/drivers/ethernet/dec21x4x.asm b/drivers/ethernet/dec21x4x.asm index e89fc5fd20..5b61c4b1f1 100644 --- a/drivers/ethernet/dec21x4x.asm +++ b/drivers/ethernet/dec21x4x.asm @@ -594,8 +594,6 @@ reset: @@: -;;; Find connected mii xceivers? 993-1043 - ; Reset the xcvr interface and turn on heartbeat. cmp [ebx + device.id], DC21041 jne @f @@ -869,19 +867,23 @@ init_ring: DEBUGF 1,"RX descriptor 0x%x\n", edi add edx, sizeof.desc mov [edi + desc.status], DES0_OWN - mov [edi + desc.length], 1536 + mov [edi + desc.length], 1514 push edx edi ecx - invoke KernelAlloc, 1536 + invoke NetAlloc, 1514+NET_BUFF.data pop ecx edi edx test eax, eax jz .out_of_mem mov [edi + RX_RING_SIZE*sizeof.desc], eax + push edx invoke GetPhysAddr + add eax, NET_BUFF.data + pop edx mov [edi + desc.buffer1], eax mov [edi + desc.buffer2], edx add edi, sizeof.desc dec ecx jnz .loop_rx_des + ; set last descriptor as LAST or [edi - sizeof.desc + desc.length], RDES1_RER ; EndOfRing pop [edi - sizeof.desc + desc.buffer2] ; point it to the first descriptor @@ -917,6 +919,7 @@ init_ring: mov [ebx + device.last_tx], eax mov [ebx + device.cur_rx], eax +; xor eax, eax ret .out_of_mem: @@ -1043,13 +1046,15 @@ create_setup_frame: DEBUGF 1,"Creating setup packet\n" - invoke KernelAlloc, 192 + invoke NetAlloc, 192 + NET_BUFF.data test eax, eax jz .err + mov [eax + NET_BUFF.device], ebx + mov [eax + NET_BUFF.length], 192 push eax - mov edi, eax + lea edi, [eax + NET_BUFF.data] xor eax, eax dec ax stosd @@ -1071,18 +1076,22 @@ create_setup_frame: DEBUGF 1, "attaching setup packet 0x%x to descriptor 0x%x\n", eax, edi mov [edi + TX_RING_SIZE*sizeof.desc], eax invoke GetPhysAddr + add eax, NET_BUFF.data mov [edi + desc.buffer1], eax - mov [edi + desc.length], TDES1_SET + 192 ; size must be EXACTLY 192 bytes + TDES1_IC + mov [edi + desc.length], TDES1_SET or 192 ; size must be EXACTLY 192 bytes + TDES1_IC mov [edi + desc.status], DES0_OWN DEBUGF 1, "descriptor 0x%x\n", edi ; go to next descriptor inc [ebx + device.cur_tx] + and [ebx + device.cur_tx], TX_RING_SIZE-1 + xor eax, eax ret .err: DEBUGF 2, "Out of memory!\n" + or eax, -1 ret @@ -1091,50 +1100,51 @@ create_setup_frame: ;; ;; ;; Transmit ;; ;; ;; -;; In: buffer pointer in [esp+4] ;; -;; size of buffer in [esp+8] ;; -;; pointer to device structure in ebx ;; +;; In: ebx = pointer to device structure ;; +;; Out: eax = 0 on success ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -proc transmit stdcall bufferptr, buffersize +proc transmit stdcall bufferptr pushf cli - DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] - mov eax, [bufferptr] + mov esi, [bufferptr] + DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] + lea eax, [esi + NET_BUFF.data] DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ [eax+13]:2,[eax+12]:2 - cmp [buffersize], 1514 + cmp [esi + NET_BUFF.length], 1514 ja .fail + cmp [esi + NET_BUFF.length], 60 + jb .fail mov eax, [ebx + device.cur_tx] mov edx, sizeof.desc mul edx - lea esi, [ebx + device.tx_ring + eax] - test [esi + desc.status], DES0_OWN + lea edi, [ebx + device.tx_ring + eax] + test [edi + desc.status], DES0_OWN jnz .fail - DEBUGF 1, "Descriptor is free\n" - mov eax, [bufferptr] - mov [esi + TX_RING_SIZE*sizeof.desc], eax + mov [edi + TX_RING_SIZE*sizeof.desc], eax + add eax, [eax + NET_BUFF.offset] invoke GetPhysAddr - mov [esi + desc.buffer1], eax + mov [edi + desc.buffer1], eax ; set packet size - mov eax, [esi + desc.length] + mov eax, [edi + desc.length] and eax, TDES1_TER ; preserve 'End of Ring' bit - or eax, [buffersize] ; set size + or eax, [esi + NET_BUFF.length] ; set size or eax, TDES1_FS or TDES1_LS or TDES1_IC ; first descr, last descr, interrupt on complete - mov [esi + desc.length], eax + mov [edi + desc.length], eax ; set descriptor status - mov [esi + desc.status], DES0_OWN ; say it is now owned by the 21x4x + mov [edi + desc.status], DES0_OWN ; say it is now owned by the 21x4x ; Check if transmitter is running set_io [ebx + device.io_addr], 0 @@ -1155,8 +1165,8 @@ proc transmit stdcall bufferptr, buffersize ; Update stats inc [ebx + device.packets_tx] - mov eax, [buffersize] - add dword [ebx + device.bytes_tx], eax + mov ecx, [esi + NET_BUFF.length] + add dword [ebx + device.bytes_tx], ecx adc dword [ebx + device.bytes_tx + 4], 0 ; go to next descriptor @@ -1169,8 +1179,8 @@ proc transmit stdcall bufferptr, buffersize ret .fail: - DEBUGF 2,"Transmit failed\n" - invoke KernelFree, [bufferptr] + DEBUGF 1,"Transmit failed\n" + invoke NetFree, [bufferptr] popf or eax, -1 ret @@ -1240,8 +1250,8 @@ int_handler: je .end_tx mov [eax + desc.buffer1], 0 - DEBUGF 1,"Free buffer 0x%x\n", [eax + TX_RING_SIZE*sizeof.desc] - invoke KernelFree, [eax + TX_RING_SIZE*sizeof.desc] + DEBUGF 1, "Free buffer 0x%x\n", [eax + TX_RING_SIZE*sizeof.desc] + invoke NetFree, [eax + TX_RING_SIZE*sizeof.desc] ; advance to next descriptor inc [ebx + device.last_tx] @@ -1254,7 +1264,6 @@ int_handler: ;---------------------------------- ; RX irq - test eax, CSR5_RI jz .not_rx push eax esi ecx @@ -1265,13 +1274,13 @@ int_handler: .rx_loop: pop ebx -; get current descriptor + ; get current descriptor mov eax, [ebx + device.cur_rx] mov edx, sizeof.desc mul edx lea edi, [ebx + device.rx_ring + eax] -; Check current RX descriptor status + ; now check status mov eax, [edi + desc.status] test eax, DES0_OWN @@ -1290,11 +1299,14 @@ int_handler: sub ecx, 4 ; throw away the CRC DEBUGF 1,"got %u bytes\n", ecx -; Push arguments for Eth_input (and some more...) +; Push arguments for EthInput (and some more...) push ebx push .rx_loop ; return addr - push ecx ; packet size - push dword[edi + RX_RING_SIZE*sizeof.desc] ; packet ptr + mov eax, dword[edi + RX_RING_SIZE*sizeof.desc] + push eax + mov [eax + NET_BUFF.length], ecx + mov [eax + NET_BUFF.device], ebx + mov [eax + NET_BUFF.offset], NET_BUFF.data ; update statistics inc [ebx + device.packets_rx] @@ -1303,10 +1315,12 @@ int_handler: ; Allocate new descriptor push edi ebx - invoke KernelAlloc, 1536 ; Allocate a buffer to put packet into + invoke NetAlloc, 1514 + NET_BUFF.data ; Allocate a buffer to put packet into pop ebx edi + jz .fail mov [edi + RX_RING_SIZE*sizeof.desc], eax invoke GetPhysAddr + add eax, NET_BUFF.data mov [edi + desc.buffer1], eax mov [edi + desc.status], DES0_OWN ; mark descriptor as being free @@ -1314,8 +1328,10 @@ int_handler: inc [ebx + device.cur_rx] ; next descriptor and [ebx + device.cur_rx], RX_RING_SIZE-1 - jmp [Eth_input] + jmp [EthInput] .end_rx: + .fail: + pop ecx esi eax .not_rx: pop edi esi ebx diff --git a/drivers/ethernet/forcedeth.asm b/drivers/ethernet/forcedeth.asm index 4fca2b5024..644e5d22f6 100644 --- a/drivers/ethernet/forcedeth.asm +++ b/drivers/ethernet/forcedeth.asm @@ -35,7 +35,7 @@ entry START MAX_DEVICES = 16 RBLEN = 0 ; Receive buffer size: 0=4K 1=8k 2=16k 3=32k 4=64k - ; FIXME: option 1 and 2 will not allocate buffer correctly causing data loss! + ; FIXME: option 1 and 2 may allocate a non contiguous buffer causing data loss! DEBUG = 1 __DEBUG__ = 1 @@ -1371,7 +1371,7 @@ align 4 init_ring: DEBUGF 1,"init rings\n" - push eax esi ecx + push esi ecx mov [ebx + device.cur_tx], 0 mov [ebx + device.last_tx], 0 @@ -1392,10 +1392,13 @@ init_ring: lea esi, [ebx + device.rx_ring] .rx_loop: push ecx esi - invoke KernelAlloc, 4096 shl RBLEN ; push/pop esi not needed, but just in case... + invoke NetAlloc, (4096 shl RBLEN) + NET_BUFF.data ; push/pop esi not needed, but just in case... pop esi + test eax, eax + jz .out_of_mem mov [esi + RX_RING*sizeof.RxDesc], eax invoke GetPhysAddr + add eax, NET_BUFF.data mov [esi + RxDesc.PacketBuffer], eax mov [esi + RxDesc.FlagLen], (4096 shl RBLEN or NV_RX_AVAIL) add esi, sizeof.RxDesc @@ -1403,8 +1406,14 @@ init_ring: dec ecx jnz .rx_loop - pop ecx esi eax + pop ecx esi + xor eax, eax + ret + + .out_of_mem: + add esp, 12 + or eax, -1 ret @@ -1781,41 +1790,42 @@ read_mac: ;; Transmit ;; ;; ;; ;; In: buffer pointer in [esp+4] ;; -;; size of buffer in [esp+8] ;; ;; pointer to device structure in ebx ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -proc transmit stdcall bufferptr, buffersize +proc transmit stdcall bufferptr pushf cli - DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] - mov eax, [bufferptr] + mov esi, [bufferptr] + DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] + lea eax, [esi + NET_BUFF.data] DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ [eax+13]:2,[eax+12]:2 - cmp [buffersize], 1514 + cmp [esi + NET_BUFF.length], 1514 ja .fail - cmp [buffersize], 60 + cmp [esi + NET_BUFF.length], 60 jb .fail ; get the descriptor address mov eax, [ebx + device.cur_tx] shl eax, 3 ; TX descriptor is 8 bytes. - lea esi, [ebx + device.tx_ring + eax] + lea edi, [ebx + device.tx_ring + eax] mov eax, [bufferptr] - mov [esi + TX_RING*sizeof.TxDesc], eax + mov [edi + TX_RING*sizeof.TxDesc], eax + add eax, [eax + NET_BUFF.offset] invoke GetPhysAddr ; Does not change esi/ebx :) - mov [esi + TxDesc.PacketBuffer], eax + mov [edi + TxDesc.PacketBuffer], eax - mov eax, [buffersize] - or eax, [ebx + device.txflags] - mov [esi + TxDesc.FlagLen], eax + mov ecx, [esi + NET_BUFF.length] + or ecx, [ebx + device.txflags] + mov [edi + TxDesc.FlagLen], ecx mov edi, [ebx + device.mmio_addr] mov eax, [ebx + device.desc_ver] @@ -1829,8 +1839,7 @@ proc transmit stdcall bufferptr, buffersize ; Update stats inc [ebx + device.packets_tx] - mov eax, [buffersize] - add dword[ebx + device.bytes_tx], eax + add dword[ebx + device.bytes_tx], ecx adc dword[ebx + device.bytes_tx + 4], 0 popf @@ -1839,7 +1848,7 @@ proc transmit stdcall bufferptr, buffersize .fail: DEBUGF 2,"Send failed\n" - invoke KernelFree, [bufferptr] + invoke NetFree, [bufferptr] popf or eax, -1 ret @@ -1896,33 +1905,33 @@ int_handler: mov cx, sizeof.RxDesc mul cx lea esi, [ebx + device.rx_ring + eax] - mov eax, [esi + RxDesc.FlagLen] + mov ecx, [esi + RxDesc.FlagLen] - test eax, NV_RX_AVAIL ; still owned by hardware + test ecx, NV_RX_AVAIL ; still owned by hardware jnz .no_rx cmp [ebx + device.desc_ver], DESC_VER_1 jne @f - test eax, NV_RX_DESCRIPTORVALID + test ecx, NV_RX_DESCRIPTORVALID jz .no_rx jmp .next @@: - test eax, NV_RX2_DESCRIPTORVALID + test ecx, NV_RX2_DESCRIPTORVALID jz .no_rx .next: cmp dword[ebx + device.desc_ver], DESC_VER_1 jne @f - and eax, LEN_MASK_V1 + and ecx, LEN_MASK_V1 jmp .next2 @@: - and eax, LEN_MASK_V2 + and ecx, LEN_MASK_V2 .next2: - DEBUGF 1,"Received %u bytes\n", eax + DEBUGF 1,"Received %u bytes\n", ecx ; Update stats - add dword[ebx + device.bytes_rx], eax + add dword[ebx + device.bytes_rx], ecx adc dword[ebx + device.bytes_rx + 4], 0 inc dword[ebx + device.packets_rx] @@ -1930,14 +1939,18 @@ int_handler: push ebx push .more_rx + mov eax, [esi + RX_RING*sizeof.RxDesc] push eax - push dword[esi + RX_RING*sizeof.RxDesc] + mov [eax + NET_BUFF.device], ebx + mov [eax + NET_BUFF.length], ecx + mov [eax + NET_BUFF.offset], NET_BUFF.data DEBUGF 1,"packet ptr=0x%x\n", [esi + RX_RING*sizeof.RxDesc] ; Allocate new buffer for this descriptor - invoke KernelAlloc, 4096 shl RBLEN + invoke NetAlloc, (4096 shl RBLEN) + NET_BUFF.data mov [esi + RX_RING*sizeof.RxDesc], eax invoke GetPhysAddr + add eax, NET_BUFF.data mov [esi + RxDesc.PacketBuffer], eax mov [esi + RxDesc.FlagLen], (4096 shl RBLEN or NV_RX_AVAIL) @@ -1945,7 +1958,7 @@ int_handler: inc [ebx + device.cur_rx] and [ebx + device.cur_rx], (RX_RING-1) - jmp [Eth_input] + jmp [EthInput] .no_rx: test eax, IRQ_RX_ERROR @@ -1999,7 +2012,7 @@ int_handler: DEBUGF 1,"Freeing buffer 0x%x\n", [esi + TX_RING*sizeof.TxDesc]:8 push dword[esi + TX_RING*sizeof.TxDesc] mov dword[esi + TX_RING*sizeof.TxDesc], 0 - invoke KernelFree + invoke NetFree inc [ebx + device.last_tx] and [ebx + device.last_tx], TX_RING - 1 diff --git a/drivers/ethernet/i8254x.asm b/drivers/ethernet/i8254x.asm index 5bd493e037..a91ff6bc28 100644 --- a/drivers/ethernet/i8254x.asm +++ b/drivers/ethernet/i8254x.asm @@ -472,7 +472,6 @@ unload: ; - Remove all allocated structures and buffers the card used or eax, -1 - ret @@ -560,8 +559,9 @@ init_rx: lea edi, [ebx + device.rx_desc] mov ecx, RX_RING_SIZE .loop: - push ecx edi - invoke KernelAlloc, MAX_PKT_SIZE + push ecx + push edi + invoke NetAlloc, MAX_PKT_SIZE+NET_BUFF.data test eax, eax jz .out_of_mem DEBUGF 1,"RX buffer: 0x%x\n", eax @@ -570,6 +570,7 @@ init_rx: push edi invoke GetPhysAddr pop edi + add eax, NET_BUFF.data mov [edi + RDESC.addr_l], eax mov [edi + RDESC.addr_h], 0 mov [edi + RDESC.status_l], 0 @@ -707,25 +708,27 @@ read_mac: ;; ;; ;; Transmit ;; ;; ;; -;; In: pointer to device structure in ebx ;; +;; In: ebx = pointer to device structure ;; +;; Out: eax = 0 on success ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -proc transmit stdcall bufferptr, buffersize +proc transmit stdcall bufferptr pushf cli - DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] - mov eax, [bufferptr] + mov esi, [bufferptr] + DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] + lea eax, [esi + NET_BUFF.data] DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ [eax+13]:2,[eax+12]:2 - cmp [buffersize], 1514 + cmp [esi + NET_BUFF.length], 1514 ja .fail - cmp [buffersize], 60 + cmp [esi + NET_BUFF.length], 60 jb .fail ; Program the descriptor (use legacy mode) @@ -733,12 +736,14 @@ proc transmit stdcall bufferptr, buffersize DEBUGF 1, "Using TX desc: %u\n", edi shl edi, 4 ; edi = edi * sizeof.TDESC lea edi, [ebx + device.tx_desc + edi] + mov eax, esi mov dword[edi + TX_RING_SIZE*sizeof.TDESC], eax ; Store the data location (for driver) + add eax, [eax + NET_BUFF.offset] invoke GetPhysAddr mov [edi + TDESC.addr_l], eax ; Data location (for hardware) mov [edi + TDESC.addr_h], 0 - mov ecx, [buffersize] + mov ecx, [esi + NET_BUFF.length] or ecx, TXDESC_EOP + TXDESC_IFCS + TXDESC_RS mov [edi + TDESC.length_cso_cmd], ecx mov [edi + TDESC.status], 0 @@ -753,7 +758,7 @@ proc transmit stdcall bufferptr, buffersize ; Update stats inc [ebx + device.packets_tx] - mov eax, [buffersize] + mov eax, [esi + NET_BUFF.length] add dword[ebx + device.bytes_tx], eax adc dword[ebx + device.bytes_tx + 4], 0 @@ -767,7 +772,7 @@ proc transmit stdcall bufferptr, buffersize call clean_tx DEBUGF 2,"Send failed\n" - invoke KernelFree, [bufferptr] + invoke NetFree, [bufferptr] popf or eax, -1 ret @@ -833,8 +838,11 @@ int_handler: push .retaddr movzx ecx, word[esi + 8] ; Get the packet length DEBUGF 1,"got %u bytes\n", ecx - push ecx - push dword[esi + RX_RING_SIZE*sizeof.RDESC] ; Get packet pointer + mov eax, [esi + RX_RING_SIZE*sizeof.RDESC] ; Get packet pointer + push eax + mov [eax + NET_BUFF.length], ecx + mov [eax + NET_BUFF.device], ebx + mov [eax + NET_BUFF.offset], NET_BUFF.data ; Update stats add dword[ebx + device.bytes_rx], ecx @@ -843,12 +851,13 @@ int_handler: ; Allocate new descriptor push esi - invoke KernelAlloc, MAX_PKT_SIZE + invoke NetAlloc, MAX_PKT_SIZE+NET_BUFF.data pop esi test eax, eax jz .out_of_mem mov dword[esi + RX_RING_SIZE*sizeof.RDESC], eax invoke GetPhysAddr + add eax, NET_BUFF.data mov [esi + RDESC.addr_l], eax mov [esi + RDESC.status_l], 0 mov [esi + RDESC.status_h], 0 @@ -862,7 +871,7 @@ int_handler: inc [ebx + device.cur_rx] and [ebx + device.cur_rx], RX_RING_SIZE-1 - jmp [Eth_input] + jmp [EthInput] .out_of_mem: DEBUGF 2,"Out of memory!\n" @@ -871,7 +880,7 @@ int_handler: inc [ebx + device.cur_rx] and [ebx + device.cur_rx], RX_RING_SIZE-1 - jmp [Eth_input] + jmp [EthInput] .no_rx: ;-------------- @@ -918,7 +927,7 @@ clean_tx: push ebx push dword[edi + TX_RING_SIZE*sizeof.TDESC] mov dword[edi + TX_RING_SIZE*sizeof.TDESC], 0 - invoke KernelFree + invoke NetFree pop ebx inc [ebx + device.last_tx] diff --git a/drivers/ethernet/i8255x.asm b/drivers/ethernet/i8255x.asm index c1982e4130..2aab5ef70a 100644 --- a/drivers/ethernet/i8255x.asm +++ b/drivers/ethernet/i8255x.asm @@ -18,8 +18,6 @@ ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TODO: use separate descriptors in memory instead of placing them in front of packets! - format PE DLL native entry START @@ -78,6 +76,8 @@ CmdTx = 0x0004 CmdTxFlex = 0x0008 Cmdsuspend = 0x4000 +CmdRxFlex = 0x0008 + reg_scb_status = 0 reg_scb_cmd = 2 reg_scb_ptr = 4 @@ -487,6 +487,8 @@ reset: ; Create RX and TX descriptors call create_ring + test eax, eax + jz .error ; RX start @@ -494,6 +496,7 @@ reset: set_io [ebx + device.io_addr], reg_scb_ptr mov eax, [ebx + device.rx_desc] invoke GetPhysAddr + add eax, NET_BUFF.data out dx, eax mov ax, INT_MASK + RX_START @@ -580,6 +583,10 @@ reset: xor eax, eax ; indicate that we have successfully reset the card ret + .error: + or eax, -1 + ret + align 4 create_ring: @@ -589,15 +596,18 @@ create_ring: ;--------------------- ; build rxfd structure - invoke KernelAlloc, 2000 + invoke NetAlloc, 2000 + test eax, eax + jz .out_of_mem mov [ebx + device.rx_desc], eax mov esi, eax invoke GetPhysAddr - mov [esi + rxfd.status], 0x0000 - mov [esi + rxfd.command], 0x0000 - mov [esi + rxfd.link], eax - mov [esi + rxfd.count], 0 - mov [esi + rxfd.size], 1528 + add eax, NET_BUFF.data + mov [esi + sizeof.NET_BUFF + rxfd.status], 0x0000 + mov [esi + sizeof.NET_BUFF + rxfd.command], 0x0000 + mov [esi + sizeof.NET_BUFF + rxfd.link], eax + mov [esi + sizeof.NET_BUFF + rxfd.count], 0 + mov [esi + sizeof.NET_BUFF + rxfd.size], 1528 ;----------------------- ; build txfd structure @@ -610,6 +620,8 @@ create_ring: invoke GetPhysAddr mov [ebx + device.txfd.desc_addr], eax + .out_of_mem: + ret @@ -622,33 +634,37 @@ create_ring: ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -proc transmit stdcall bufferptr, buffersize +proc transmit stdcall bufferptr pushf cli - DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] - mov eax, [bufferptr] + mov esi, [bufferptr] + DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] + lea eax, [esi + NET_BUFF.data] DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ [eax+13]:2,[eax+12]:2 - cmp [buffersize], 1514 + cmp [esi + NET_BUFF.length], 1514 ja .fail - cmp [buffersize], 60 + cmp [esi + NET_BUFF.length], 60 jb .fail ;;; TODO: check if current descriptor is in use ; fill in buffer address and size + mov eax, [bufferptr] mov [ebx + device.last_tx_buffer], eax + add eax, [eax + NET_BUFF.offset] invoke GetPhysAddr mov [ebx + device.txfd.buf_addr0], eax - mov ecx, [buffersize] + mov ecx, [bufferptr] + mov ecx, [ecx + NET_BUFF.length] mov [ebx + device.txfd.buf_size0], ecx mov [ebx + device.txfd.status], 0 - mov [ebx + device.txfd.command], Cmdsuspend + CmdTx + CmdTxFlex + 1 shl 15 ;;; EL bit + mov [ebx + device.txfd.command], Cmdsuspend + CmdTx + CmdTxFlex ;+ 1 shl 15 ;;; EL bit ; mov [txfd.count], 0x02208000 ;;;;;;;;;;; ; Inform device of the new/updated transmit descriptor @@ -666,7 +682,6 @@ proc transmit stdcall bufferptr, buffersize ; Update stats inc [ebx + device.packets_tx] - mov ecx, [buffersize] add dword[ebx + device.bytes_tx], ecx adc dword[ebx + device.bytes_tx + 4], 0 @@ -676,7 +691,7 @@ proc transmit stdcall bufferptr, buffersize ret .fail: - invoke KernelFree, [bufferptr] + invoke NetFree, [bufferptr] popf or eax, -1 ret @@ -738,19 +753,20 @@ int_handler: pop ebx mov esi, [ebx + device.rx_desc] - cmp [esi + rxfd.status], 0 ; we could also check bits C and OK (bit 15 and 13) + cmp [esi + sizeof.NET_BUFF + rxfd.status], 0 ; we could also check bits C and OK (bit 15 and 13) je .nodata - DEBUGF 1,"rxfd status=0x%x\n", [esi + rxfd.status]:4 + DEBUGF 1,"rxfd status=0x%x\n", [esi + sizeof.NET_BUFF + rxfd.status]:4 - movzx ecx, [esi + rxfd.count] + movzx ecx, [esi + sizeof.NET_BUFF + rxfd.count] and ecx, 0x3fff push ebx push .rx_loop - push ecx - add esi, rxfd.packet push esi + mov [esi + NET_BUFF.length], ecx + mov [esi + NET_BUFF.device], ebx + mov [esi + NET_BUFF.offset], NET_BUFF.data + rxfd.packet ; Update stats add dword [ebx + device.bytes_rx], ecx @@ -759,15 +775,16 @@ int_handler: ; allocate new descriptor - invoke KernelAlloc, 2000 + invoke NetAlloc, 2000 mov [ebx + device.rx_desc], eax mov esi, eax invoke GetPhysAddr - mov [esi + rxfd.status], 0x0000 - mov [esi + rxfd.command], 0xc000 ; End of list + Suspend - mov [esi + rxfd.link], eax - mov [esi + rxfd.count], 0 - mov [esi + rxfd.size], 1528 + add eax, NET_BUFF.data + mov [esi + sizeof.NET_BUFF + rxfd.status], 0x0000 + mov [esi + sizeof.NET_BUFF + rxfd.command], 0xc000 ; End of list + Suspend + mov [esi + sizeof.NET_BUFF + rxfd.link], eax + mov [esi + sizeof.NET_BUFF + rxfd.count], 0 + mov [esi + sizeof.NET_BUFF + rxfd.size], 1528 ; restart RX @@ -783,7 +800,7 @@ int_handler: call cmd_wait ; And give packet to kernel - jmp [Eth_input] + jmp [EthInput] .nodata: DEBUGF 1, "no more data\n" diff --git a/drivers/ethernet/mtd80x.asm b/drivers/ethernet/mtd80x.asm index ed55937e51..391ccc937c 100644 --- a/drivers/ethernet/mtd80x.asm +++ b/drivers/ethernet/mtd80x.asm @@ -473,8 +473,7 @@ unload: ; - Remove all allocated structures and buffers the card used or eax, -1 - -ret + ret ;------- @@ -627,6 +626,8 @@ reset: out dx, eax call init_ring + test eax, eax + jnz .err ; Initialize other registers. ; Configure the PCI bus bursts and FIFO thresholds. @@ -637,7 +638,7 @@ reset: jne @f or [ebx + device.bcrvalue], 0x200 ; set PROG bit or [ebx + device.crvalue], 0x02000000 ; set enhanced bit - @@: + @@: or [ebx + device.crvalue], RxEnable + TxThreshold + TxEnable call set_rx_mode @@ -676,13 +677,18 @@ reset: xor eax, eax ret + .err: + DEBUGF 2, "Error!\n" + or eax, -1 + ret + align 4 init_ring: - DEBUGF 1,"initializing rx and tx ring\n" + DEBUGF 1, "initializing rx and tx ring\n" ; Initialize all Rx descriptors lea esi, [ebx + device.rx_desc] @@ -690,7 +696,7 @@ init_ring: mov ecx, NUM_RX_DESC .rx_desc_loop: mov [esi + descriptor.status], RXOWN - mov [esi + descriptor.control], 1536 shl RBSShift + mov [esi + descriptor.control], 1514 shl RBSShift lea eax, [esi + sizeof.descriptor] mov [esi + descriptor.next_desc_logical], eax @@ -698,11 +704,14 @@ init_ring: invoke GetPhysAddr mov [esi + descriptor.next_desc], eax - invoke KernelAlloc, 1536 - pop esi - push esi + invoke NetAlloc, 1514+NET_BUFF.data + pop esi ecx + test eax, eax + jz .out_of_mem + push ecx esi mov [esi + descriptor.skbuff], eax invoke GetPgAddr + add eax, NET_BUFF.data pop esi ecx mov [esi + descriptor.buffer], eax @@ -746,10 +755,15 @@ init_ring: pop esi mov [esi - sizeof.descriptor + descriptor.next_desc], eax - set_io [ebx + device.io_addr], 0 - set_io [ebx + device.io_addr], TXLBA + set_io [ebx + device.io_addr], 0 + set_io [ebx + device.io_addr], TXLBA out dx, eax + xor eax, eax + ret + + .out_of_mem: + or eax, -1 ret @@ -924,25 +938,25 @@ getlinktype: ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -proc transmit stdcall bufferptr, buffersize +proc transmit stdcall bufferptr pushf cli - DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] - mov eax, [bufferptr] + mov esi, [bufferptr] + DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] + lea eax, [esi + NET_BUFF.data] DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ [eax+13]:2,[eax+12]:2 - cmp [buffersize], 1514 + cmp [esi + NET_BUFF.length], 1514 ja .fail - cmp [buffersize], 60 + cmp [esi + NET_BUFF.length], 60 jb .fail mov esi, [ebx + device.cur_tx] - test [esi + descriptor.status], TXOWN jnz .fail @@ -951,10 +965,12 @@ proc transmit stdcall bufferptr, buffersize mov eax, [bufferptr] mov [esi + descriptor.skbuff], eax + add eax, [eax + NET_BUFF.offset] invoke GetPhysAddr mov [esi + descriptor.buffer], eax - mov eax, [buffersize] + mov eax, [bufferptr] + mov eax, [eax + NET_BUFF.length] mov ecx, eax shl eax, PKTSShift ; packet size shl ecx, TBSShift @@ -965,8 +981,9 @@ proc transmit stdcall bufferptr, buffersize ; Update stats inc [ebx + device.packets_tx] - mov eax, [buffersize] - add dword[ebx + device.bytes_tx], eax + mov eax, [bufferptr] + mov ecx, [eax + NET_BUFF.length] + add dword[ebx + device.bytes_tx], ecx adc dword[ebx + device.bytes_tx + 4], 0 ; TX Poll @@ -982,7 +999,7 @@ proc transmit stdcall bufferptr, buffersize .fail: DEBUGF 2,"Transmit failed\n" - invoke KernelFree, [bufferptr] + invoke NetFree, [bufferptr] popf or eax, -1 ret @@ -1068,26 +1085,32 @@ int_handler: mov ecx, [esi + descriptor.status] shr ecx, FLNGShift sub ecx, 4 ; we dont need CRC - push ecx DEBUGF 1,"Received %u bytes\n", ecx + mov eax, [esi + descriptor.skbuff] + push eax + mov [eax + NET_BUFF.length], ecx + mov [eax + NET_BUFF.device], ebx + mov [eax + NET_BUFF.offset], NET_BUFF.data ; Update stats add dword[ebx + device.bytes_rx], ecx adc dword[ebx + device.bytes_rx + 4], 0 inc [ebx + device.packets_rx] - push [esi + descriptor.skbuff] - jmp [Eth_input] + jmp [EthInput] .rx_complete: pop ebx mov esi, [ebx + device.cur_rx] - mov [esi + descriptor.control], 1536 shl RBSShift + mov [esi + descriptor.control], 1514 shl RBSShift push esi - invoke KernelAlloc, 1536 + invoke NetAlloc, 1514+NET_BUFF.data pop esi +; test eax, eax +; jz .rx_loop mov [esi + descriptor.skbuff], eax - invoke GetPgAddr + invoke GetPhysAddr + add eax, NET_BUFF.data mov [esi + descriptor.buffer], eax mov [esi + descriptor.status], RXOWN @@ -1122,7 +1145,7 @@ int_handler: je .skip_this_one mov [esi + descriptor.skbuff], 0 DEBUGF 1,"freeing buffer: 0x%x\n", eax - invoke KernelFree, eax + invoke NetFree, eax .skip_this_one: mov esi, [esi + descriptor.next_desc_logical] loop .tx_loop diff --git a/drivers/ethernet/pcnet32.asm b/drivers/ethernet/pcnet32.asm index 979cd05772..bab9e5dca0 100644 --- a/drivers/ethernet/pcnet32.asm +++ b/drivers/ethernet/pcnet32.asm @@ -491,7 +491,7 @@ proc service_proc stdcall, ioctl:dword .destroy: ; todo: reset device into virgin state - + add eax, NET_BUFF.data dec [devices] .err: DEBUGF 2,"Error, removing all data !\n" @@ -521,9 +521,8 @@ unload: ; - call unregister function in kernel ; - Remove all allocated structures and buffers the card used - or eax,-1 - -ret + or eax, -1 + ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -868,6 +867,8 @@ reset: movsw call init_ring + test eax, eax + jnz .fail mov edx, [ebx + device.io_addr] ; init ring destroys edx @@ -923,6 +924,7 @@ reset: DEBUGF 1,"reset complete\n" xor eax, eax + .fail: ret @@ -938,10 +940,13 @@ init_ring: mov ecx, RX_RING_SIZE .rx_init: push ecx - invoke KernelAlloc, PKT_BUF_SZ + invoke NetAlloc, PKT_BUF_SZ+NET_BUFF.data pop ecx + test eax, eax + jz .out_of_mem mov [edi + descriptor.virtual], eax invoke GetPhysAddr + add eax, NET_BUFF.data mov [edi + descriptor.base], eax mov [edi + descriptor.length], - PKT_BUF_SZ mov [edi + descriptor.status], RXSTAT_OWN @@ -967,6 +972,13 @@ init_ring: mov [ebx + device.last_tx], 0 mov [ebx + device.cur_rx], 0 + xor eax, eax + ret + + .out_of_mem: + DEBUGF 2,"Out of memory!\n" + + or eax, -1 ret @@ -980,38 +992,40 @@ init_ring: ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -proc transmit stdcall bufferptr, buffersize +proc transmit stdcall bufferptr pushf cli - DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] - mov eax, [bufferptr] + mov esi, [bufferptr] + DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] + lea eax, [esi + NET_BUFF.data] DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ [eax+13]:2,[eax+12]:2 - cmp [buffersize], 1514 + cmp [esi + NET_BUFF.length], 1514 ja .fail - cmp [buffersize], 60 + cmp [esi + NET_BUFF.length], 60 jb .fail ; check descriptor lea edi, [ebx + device.tx_ring] - movzx eax, [ebx + device.cur_tx] - shl eax, 4 - add edi, eax + movzx ecx, [ebx + device.cur_tx] + shl ecx, 4 + add edi, ecx test [edi + descriptor.status], TXCTL_OWN jnz .fail ; descriptor is free, use it - mov eax, [bufferptr] - mov [edi + descriptor.virtual], eax + mov [edi + descriptor.virtual], esi + mov eax, esi + add eax, [eax + NET_BUFF.offset] invoke GetPhysAddr mov [edi + descriptor.base], eax ; set length - mov eax, [buffersize] + mov eax, [esi + NET_BUFF.length] neg eax mov [edi + descriptor.length], ax ; put to transfer queue @@ -1030,7 +1044,7 @@ proc transmit stdcall bufferptr, buffersize ; Update stats inc [ebx + device.packets_tx] - mov eax, [buffersize] + mov eax, [esi + NET_BUFF.length] add dword[ebx + device.bytes_tx], eax adc dword[ebx + device.bytes_tx + 4], 0 @@ -1041,7 +1055,7 @@ proc transmit stdcall bufferptr, buffersize .fail: DEBUGF 2, "Send failed\n" - invoke KernelFree, [bufferptr] + invoke NetFree, [bufferptr] popf or eax, -1 ret @@ -1124,8 +1138,11 @@ int_handler: push ebx push .rx_loop ; return address - push ecx ; packet size - push [edi + descriptor.virtual] ; packet address + mov eax, [edi + descriptor.virtual] + push eax ; packet address + mov [eax + NET_BUFF.length], ecx + mov [eax + NET_BUFF.device], ebx + mov [eax + NET_BUFF.offset], NET_BUFF.data ; Update stats add dword[ebx + device.bytes_rx], ecx @@ -1133,16 +1150,27 @@ int_handler: inc [ebx + device.packets_rx] ; now allocate a new buffer - invoke KernelAlloc, PKT_BUF_SZ ; Allocate a buffer for the next packet + invoke NetAlloc, PKT_BUF_SZ+NET_BUFF.data ; Allocate a buffer for the next packet + test eax, eax + jz .out_of_mem mov [edi + descriptor.virtual], eax ; set virtual address invoke GetPhysAddr + add eax, NET_BUFF.data mov [edi + descriptor.base], eax ; and physical address mov [edi + descriptor.status], RXSTAT_OWN ; give it back to PCnet controller inc [ebx + device.cur_rx] ; set next receive descriptor and [ebx + device.cur_rx], RX_RING_SIZE - 1 - jmp [Eth_input] + jmp [EthInput] + + .out_of_mem: + DEBUGF 2,"Out of memory!\n" + + inc [ebx + device.cur_rx] ; set next receive descriptor + and [ebx + device.cur_rx], RX_RING_SIZE - 1 + + jmp [EthInput] .not_receive: pop ax @@ -1167,7 +1195,7 @@ int_handler: DEBUGF 1,"Removing packet %x from memory\n", eax - invoke KernelFree, eax + invoke NetFree, eax inc [ebx + device.last_tx] and [ebx + device.last_tx], TX_RING_SIZE - 1 diff --git a/drivers/ethernet/rhine.asm b/drivers/ethernet/rhine.asm index 39686adece..ccf33595d5 100644 --- a/drivers/ethernet/rhine.asm +++ b/drivers/ethernet/rhine.asm @@ -346,7 +346,7 @@ NIC_LB_NONE = 0x00 NIC_LB_INTERNAL = 0x01 NIC_LB_PHY = 0x02 ; MII or Internal-10BaseT loopback -PKT_BUF_SZ = 1536 ; Size of each temporary Rx buffer. +PKT_BUF_SZ = 1514 PCI_REG_MODE3 = 0x53 MODE3_MIION = 0x04 ; in PCI_REG_MOD3 OF PCI space @@ -929,11 +929,7 @@ reset: DEBUGF 1,"Attaching int handler to irq %x\n", eax:1 invoke AttachIntHandler, eax, int_handler, ebx test eax, eax - jnz @f - DEBUGF 2,"Could not attach int handler!\n" - or eax, -1 - ret - @@: + jz .err ; Soft reset the chip. set_io [ebx + device.io_addr], 0 @@ -945,6 +941,8 @@ reset: ; Initialize rings call init_ring + test eax, eax + jnz .err ; Set Multicast call set_rx_mode @@ -968,7 +966,6 @@ reset: out dx, al ; Set Fulldupex - call QueryAuto test eax, eax ; full duplex? jz @f @@ -1007,6 +1004,11 @@ reset: xor eax, eax ret + .err: + DEBUGF 2,"Error!\n" + or eax, -1 + ret + align 4 @@ -1073,10 +1075,13 @@ init_ring: mov [edi + rx_head.status], RX_SBITS_OWN_BIT mov [edi + rx_head.control], PKT_BUF_SZ push ecx - invoke KernelAlloc, PKT_BUF_SZ + invoke NetAlloc, PKT_BUF_SZ+NET_BUFF.data pop ecx + test eax, eax + jz .out_of_mem mov [edi + rx_head.buff_addr_virt], eax invoke GetPhysAddr + add eax, NET_BUFF.data mov [edi + rx_head.buff_addr], eax ; buffer ptr mov [edi + rx_head.next_desc], esi ; next head add edi, sizeof.rx_head @@ -1120,6 +1125,12 @@ init_ring: mov [ebx + device.cur_tx], ax mov [ebx + device.last_tx], ax + xor eax, eax + ret + + .out_of_mem: + add esp, 4 + or eax, -1 ret @@ -1349,8 +1360,8 @@ set_rx_mode: out dx, eax set_io [ebx + device.io_addr], byRCR - mov al, 0x6C ;rx_mode = 0x0C; - out dx, al ;outb(0x60 /* thresh */ | rx_mode, byRCR ); + mov al, 0x6C ; thresh or rx_mode + out dx, al ret @@ -1393,26 +1404,26 @@ read_mac: ;; Transmit ;; ;; ;; ;; In: buffer pointer in [esp+4] ;; -;; size of buffer in [esp+8] ;; ;; pointer to device structure in ebx ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; align 4 -proc transmit stdcall bufferptr, buffersize +proc transmit stdcall bufferptr pushf cli - DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] - mov eax, [bufferptr] + mov esi, [bufferptr] + DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] + lea eax, [esi + NET_BUFF.data] DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ [eax+13]:2,[eax+12]:2 - cmp [buffersize], 1514 + cmp [esi + NET_BUFF.length], 1514 ja .fail - cmp [buffersize], 60 + cmp [esi + NET_BUFF.length], 60 jb .fail movzx eax, [ebx + device.cur_tx] @@ -1424,11 +1435,12 @@ proc transmit stdcall bufferptr, buffersize cmp [edi + tx_head.buff_addr_virt], 0 jne .fail - mov eax, [bufferptr] + mov eax, esi mov [edi + tx_head.buff_addr_virt], eax + add eax, [eax + NET_BUFF.offset] invoke GetPhysAddr mov [edi + tx_head.buff_addr], eax - mov ecx, [buffersize] + mov ecx, [esi + NET_BUFF.length] and ecx, TX_CBITS_TX_BUF_SIZE or ecx, 0x00E08000 mov [edi + tx_head.control], ecx @@ -1447,7 +1459,7 @@ proc transmit stdcall bufferptr, buffersize ; Update stats inc [ebx + device.packets_tx] - mov ecx, [buffersize] + mov ecx, [esi + NET_BUFF.length] add dword [ebx + device.bytes_tx], ecx adc dword [ebx + device.bytes_tx + 4], 0 @@ -1458,7 +1470,7 @@ proc transmit stdcall bufferptr, buffersize .fail: DEBUGF 2,"Transmit failed\n" - invoke KernelFree, [bufferptr] + invoke NetFree, [bufferptr] popf or eax, -1 ret @@ -1481,7 +1493,6 @@ int_handler: DEBUGF 1,"INT\n" ; Find pointer of device which made IRQ occur - mov ecx, [devices] test ecx, ecx jz .nothing @@ -1506,9 +1517,7 @@ int_handler: ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver) - .got_it: - DEBUGF 1, "status=0x%x\n", ax push ax @@ -1521,7 +1530,6 @@ int_handler: pop ebx ; Get the current descriptor pointer - movzx eax, [ebx + device.cur_rx] mov ecx, sizeof.rx_head mul ecx @@ -1529,57 +1537,51 @@ int_handler: add edi, eax ; Check it's status - test [edi + rx_head.status], RX_SBITS_OWN_BIT - jnz .not_bit_own + jnz .not_RX DEBUGF 1, "Packet status = 0x%x\n", [edi + rx_head.status] ; TODO: check error bits ; get length - mov ecx, [edi + rx_head.status] and ecx, RX_SBITS_FRAME_LENGTH shr ecx, 16 - sub ecx, 4 ; We dont want CRC + sub ecx, 4 ; We dont want CRC ; Update stats - add dword [ebx + device.bytes_rx], ecx adc dword [ebx + device.bytes_rx + 4], 0 inc [ebx + device.packets_rx] -; Push packet size and pointer, kernel will need it.. - +; Push packet pointer, kernel will need it.. push ebx - push .more_RX ; return ptr - - push ecx ; full packet size - push [edi + rx_head.buff_addr_virt] + push .more_RX ; return ptr + mov eax, [edi + rx_head.buff_addr_virt] + push eax + mov [eax + NET_BUFF.length], ecx + mov [eax + NET_BUFF.device], ebx + mov [eax + NET_BUFF.offset], NET_BUFF.data ; reset the RX descriptor - push edi - invoke KernelAlloc, PKT_BUF_SZ + invoke NetAlloc, PKT_BUF_SZ+NET_BUFF.data pop edi mov [edi + rx_head.buff_addr_virt], eax invoke GetPhysAddr + add eax, NET_BUFF.data mov [edi + rx_head.buff_addr], eax mov [edi + rx_head.status], RX_SBITS_OWN_BIT ; Use next descriptor next time - inc [ebx + device.cur_rx] and [ebx + device.cur_rx], RX_RING_SIZE - 1 ; At last, send packet to kernel + jmp [EthInput] - jmp [Eth_input] - - .not_bit_own: .not_RX: - pop ax test ax, IntrTxDone @@ -1602,7 +1604,7 @@ int_handler: push [edi + tx_head.buff_addr_virt] mov [edi + tx_head.buff_addr_virt], 0 - invoke KernelFree + invoke NetFree inc [ebx + device.last_tx] and [ebx + device.last_tx], TX_RING_SIZE - 1 @@ -1613,12 +1615,12 @@ int_handler: ; On Rhine-II, Bit 3 indicates Tx descriptor write-back race. if 0 - cmp [ebx + device.chip_id], 0x3065 ;if (tp->chip_id == 0x3065) + cmp [ebx + device.chip_id], 0x3065 jne @f push ax xor eax, eax set_io [ebx + device.io_addr], IntrStatus2 - in al, dx ; intr_status |= inb(nic->ioaddr + IntrStatus2) << 16; + in al, dx shl eax, 16 pop ax @@: diff --git a/drivers/ethernet/sis900.asm b/drivers/ethernet/sis900.asm index 01aa9a6544..d684f90fba 100644 --- a/drivers/ethernet/sis900.asm +++ b/drivers/ethernet/sis900.asm @@ -414,8 +414,7 @@ unload: ; - Remove all allocated structures and buffers the card used or eax, -1 - -ret + ret ;*************************************************************************** ; @@ -612,12 +611,13 @@ reset: mov dword [esi + 4], RX_BUFF_SZ ; size push ecx esi - invoke KernelAlloc, RX_BUFF_SZ + invoke NetAlloc, RX_BUFF_SZ+NET_BUFF.data pop esi ecx test eax, eax jz .fail mov dword [esi + 12], eax ; address invoke GetPhysAddr + add eax, NET_BUFF.data mov dword [esi + 8], eax ; real address add esi, 16 dec ecx @@ -1006,21 +1006,22 @@ write_mac: ;*************************************************************************** align 4 -proc transmit stdcall bufferptr, buffersize +proc transmit stdcall bufferptr pushf cli - DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] - mov eax, [bufferptr] + mov esi, [bufferptr] + DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] + lea eax, [esi + NET_BUFF.data] DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ [eax+13]:2,[eax+12]:2 - cmp [buffersize], 1514 + cmp [esi + NET_BUFF.length], 1514 ja .fail - cmp [buffersize], 60 + cmp [esi + NET_BUFF.length], 60 jb .fail movzx ecx, [ebx + device.cur_tx] @@ -1030,12 +1031,13 @@ proc transmit stdcall bufferptr, buffersize test dword[ecx + 4], 0x80000000 ; card owns descriptor ? jnz .fail - mov eax, [bufferptr] + mov eax, esi mov dword[ecx + 12], eax + add eax, [eax + NET_BUFF.offset] invoke GetPhysAddr mov dword[ecx + 8], eax ; buffer address - mov eax, [buffersize] + mov eax, [esi + NET_BUFF.length] and eax, DSIZE or eax, 0x80000000 ; card owns descriptor mov dword[ecx + 4], eax ; status field @@ -1050,7 +1052,7 @@ proc transmit stdcall bufferptr, buffersize and [ebx + device.cur_tx], NUM_TX_DESC-1 ; update stats - mov ecx, [buffersize] + mov ecx, [esi + NET_BUFF.length] inc [ebx + device.packets_tx] add dword [ebx + device.bytes_tx], ecx adc dword [ebx + device.bytes_tx + 4], 0 @@ -1062,7 +1064,7 @@ proc transmit stdcall bufferptr, buffersize .fail: DEBUGF 2,"Transmit failed\n" - invoke KernelFree, [bufferptr] + invoke NetFree, [bufferptr] popf or eax, -1 ret @@ -1151,16 +1153,19 @@ int_handler: adc dword [ebx + device.bytes_rx + 4], 0 push ebx - push .return - push ecx ; packet size - pushd [ebx + device.rxd + eax + 12] ; packet ptr + push .return ; return addr + mov eax, [ebx + device.rxd + eax + 12] + push eax ; packet ptr + mov [eax + NET_BUFF.length], ecx + mov [eax + NET_BUFF.device], ebx + mov [eax + NET_BUFF.offset], NET_BUFF.data DEBUGF 1, "Packet received OK\n" - jmp [Eth_input] + jmp [EthInput] .return: pop ebx ; Reset status, allow ethernet card access to descriptor - invoke KernelAlloc, RX_BUFF_SZ + invoke NetAlloc, RX_BUFF_SZ + NET_BUFF.data test eax, eax jz .fail movzx ecx, [ebx + device.cur_rx] @@ -1168,6 +1173,7 @@ int_handler: lea ecx, [ebx + device.rxd + ecx] mov dword [ecx + 12], eax invoke GetPhysAddr + add eax, NET_BUFF.data mov dword [ecx + 8], eax mov dword [ecx + 4], RX_BUFF_SZ @@ -1204,7 +1210,7 @@ int_handler: DEBUGF 1, "Freeing packet = %x\n", [ecx + 12]:8 push dword[ecx + 12] mov dword[ecx + 12], 0 - invoke KernelFree + invoke NetFree inc [ebx + device.last_tx] and [ebx + device.last_tx], NUM_TX_DESC-1 diff --git a/drivers/imports.inc b/drivers/imports.inc index 07abf8185c..7a30344eef 100644 --- a/drivers/imports.inc +++ b/drivers/imports.inc @@ -104,7 +104,8 @@ kernel_export \ NetUnRegDev,\ NetPtrToNum,\ NetLinkChanged,\ - Eth_input,\ - IPv4_input,\ + NetAlloc,\ + NetFree,\ + EthInput,\ \ GetPCIList diff --git a/drivers/netdrv.inc b/drivers/netdrv.inc index 813e76ec6b..f115d1ce67 100644 --- a/drivers/netdrv.inc +++ b/drivers/netdrv.inc @@ -122,6 +122,19 @@ struct NET_DEVICE ends +struct NET_BUFF + + NextPtr dd ? ; pointer to next frame in list + PrevPtr dd ? ; pointer to previous frame in list + device dd ? ; ptr to NET_DEVICE structure + type dd ? ; data type (e.g. Ethernet) + length dd ? ; data length + offset dd ? ; offset to actual data (24 bytes for default frame) + data rb 0 + +ends + + struct ETH_DEVICE NET_DEVICE mac dp ? diff --git a/drivers/peimport.inc b/drivers/peimport.inc index 4e21d7c4d6..d0daf21da9 100644 --- a/drivers/peimport.inc +++ b/drivers/peimport.inc @@ -155,8 +155,9 @@ import core,\ NetUnRegDev,\ NetPtrToNum,\ NetLinkChanged,\ - Eth_input,\ - IPv4_input,\ + EthInput,\ + NetAlloc,\ + NetFree,\ \ GetPCIList end data diff --git a/kernel/trunk/core/exports.inc b/kernel/trunk/core/exports.inc index 825833f2f4..17625dc15d 100644 --- a/kernel/trunk/core/exports.inc +++ b/kernel/trunk/core/exports.inc @@ -122,7 +122,9 @@ __exports: NET_remove_device, 'NetUnRegDev', \ NET_ptr_to_num, 'NetPtrToNum', \ NET_link_changed, 'NetLinkChanged', \ - ETH_input, 'Eth_input', \ + ETH_input, 'EthInput', \ + NET_BUFF_alloc, 'NetAlloc', \ + NET_BUFF_free, 'NetFree', \ \ get_pcidev_list, 'GetPCIList', \ \ diff --git a/kernel/trunk/network/ARP.inc b/kernel/trunk/network/ARP.inc index 9c7ef93ddd..d203599820 100644 --- a/kernel/trunk/network/ARP.inc +++ b/kernel/trunk/network/ARP.inc @@ -293,13 +293,10 @@ ARP_input: DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: IP address conflict detected!\n" .exit: - call NET_packet_free - add esp, 4 ; pop (balance stack) - DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: exiting\n" + call NET_BUFF_free ret - ;--------------------------------------------------------------------------- ; ; ARP_output_request @@ -347,7 +344,7 @@ ARP_output_request: movsd ; popd [edi] ; DestIP - push edx eax + push eax call [ebx + NET_DEVICE.transmit] ret diff --git a/kernel/trunk/network/IPv4.inc b/kernel/trunk/network/IPv4.inc index 60d2b4b7b1..cc67432505 100644 --- a/kernel/trunk/network/IPv4.inc +++ b/kernel/trunk/network/IPv4.inc @@ -225,10 +225,10 @@ macro IPv4_checksum ptr { align 4 IPv4_input: ; TODO: add IPv4 raw sockets support - DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input, packet from: %u.%u.%u.%u ",\ + DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: packet from %u.%u.%u.%u ",\ [edx + IPv4_header.SourceAddress + 0]:1,[edx + IPv4_header.SourceAddress + 1]:1,\ [edx + IPv4_header.SourceAddress + 2]:1,[edx + IPv4_header.SourceAddress + 3]:1 - DEBUGF DEBUG_NETWORK_VERBOSE, "to: %u.%u.%u.%u\n",\ + DEBUGF DEBUG_NETWORK_VERBOSE, "to %u.%u.%u.%u\n",\ [edx + IPv4_header.DestinationAddress + 0]:1,[edx + IPv4_header.DestinationAddress + 1]:1,\ [edx + IPv4_header.DestinationAddress + 2]:1,[edx + IPv4_header.DestinationAddress + 3]:1 @@ -323,8 +323,7 @@ IPv4_input: ; TODO: add IPv4 .dump: DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: dumping\n" inc [IPv4_packets_dumped] ; FIXME: use correct interface - call NET_packet_free - add esp, 4 ; pop (balance stack) + call NET_BUFF_free ret @@ -371,7 +370,6 @@ IPv4_input: ; TODO: add IPv4 mov [eax + IPv4_FRAGMENT_entry.PrevPtr], edi mov [eax + IPv4_FRAGMENT_entry.Owner], ebx - add esp, 4 ret @@ -405,7 +403,6 @@ IPv4_input: ; TODO: add IPv4 mov [eax + IPv4_FRAGMENT_entry.PrevPtr], -1 mov [eax + IPv4_FRAGMENT_entry.Owner], ebx - add esp, 4 ; balance stack and exit ret @@ -506,7 +503,7 @@ IPv4_input: ; TODO: add IPv4 push [edx + IPv4_FRAGMENT_entry.NextPtr] ; Set edx to the next pointer push edx ; Push pointer to fragment onto stack DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Next Fragment: 0x%x\n", edx - call NET_packet_free ; free the previous fragment buffer (this uses the value from stack) + call NET_BUFF_free ; free the previous fragment buffer (this uses the value from stack) pop edx ebx eax cmp edx, -1 ; Check if it is last fragment in chain jne .rebuild_packet_loop @@ -654,7 +651,7 @@ IPv4_output: ret .loopback: - mov dword [esp + 2], eax ; change source IP to dest IP + mov dword [esp], eax ; set source IP to dest IP mov ecx, [esp + 10] add ecx, sizeof.IPv4_header mov edi, AF_INET4 @@ -749,7 +746,6 @@ IPv4_output_raw: ; ; ; IN: dword [esp] = pointer to buffer containing ipv4 packet to be fragmented -; dword [esp+4] = buffer size ; esi = pointer to ip header in that buffer ; ecx = max size of fragments ; @@ -857,9 +853,7 @@ IPv4_fragment: add esp, 12 + 4 + 6 .err2: DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: dumping\n" - call NET_packet_free - add esp, 4 - + call NET_BUFF_free ret diff --git a/kernel/trunk/network/IPv6.inc b/kernel/trunk/network/IPv6.inc index 45c854d4ad..4919318d4f 100644 --- a/kernel/trunk/network/IPv6.inc +++ b/kernel/trunk/network/IPv6.inc @@ -147,9 +147,7 @@ IPv6_input: .dump: DEBUGF DEBUG_NETWORK_VERBOSE, "IPv6_input - dumping\n" - call kernel_free - add esp, 4 - + call NET_BUFF_free ret .dump_options: diff --git a/kernel/trunk/network/PPPoE.inc b/kernel/trunk/network/PPPoE.inc index ff11bd29b1..206fa1a789 100644 --- a/kernel/trunk/network/PPPoE.inc +++ b/kernel/trunk/network/PPPoE.inc @@ -106,8 +106,7 @@ PPPoE_discovery_input: popa DEBUGF DEBUG_NETWORK_VERBOSE, 'PPPoE_discovery_input: dumping\n' - call NET_packet_free - add esp, 4 + call NET_BUFF_free ret @@ -232,13 +231,11 @@ PPPoE_session_input: .dump: DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_input: dumping\n" - call NET_packet_free - add esp, 4 + call NET_BUFF_free ret - ;----------------------------------------------------------------- ; ; PPPoE_output diff --git a/kernel/trunk/network/ethernet.inc b/kernel/trunk/network/ethernet.inc index 1f82168931..843c4e6bf5 100644 --- a/kernel/trunk/network/ethernet.inc +++ b/kernel/trunk/network/ethernet.inc @@ -33,30 +33,25 @@ struct ETH_DEVICE NET_DEVICE ends -struct ETH_queue_entry - - device dd ? - packet dd ? - size dd ? - -ends - iglobal align 4 - ETH_BROADCAST dp 0xffffffffffff + ETH_BROADCAST dp 0xffffffffffff + + ETH_frame_queued dd 0 ; Number of queued frames + + ETH_frame_head dd ETH_frame_head ; Pointer to next frame in the linked list + ETH_frame_tail dd ETH_frame_head ; Pointer to last frame in the linked list + endg uglobal align 4 ETH_input_event dd ? - ETH_queue rd (ETH_QUEUE_SIZE*sizeof.ETH_queue_entry + sizeof.queue)/4 endg macro ETH_init { - init_queue ETH_queue - movi ebx, 1 mov ecx, ETH_process_input call new_sys_threads @@ -72,23 +67,36 @@ macro ETH_init { ; ETH_input ; ; This function is called by ethernet drivers, -; It pushes the received ethernet packets onto the eth_in_queue +; It pushes the received ethernet packets onto the ethernet input queue +; +; IN: [esp] = Pointer to buffer ; -; IN: [esp] = Pointer to buffer -; [esp+4] = size of buffer -; ebx = pointer to eth_device ; OUT: / ; ;----------------------------------------------------------------- align 4 ETH_input: - push ebx - mov esi, esp + pop eax + pushf + cli - add_to_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .fail - add esp, sizeof.ETH_queue_entry + cmp [ETH_frame_queued], ETH_QUEUE_SIZE + jae .full + inc [ETH_frame_queued] +; Add frame to the end of the linked list + mov [eax + NET_BUFF.NextPtr], ETH_frame_head + + mov ebx, [ETH_frame_tail] + mov [eax + NET_BUFF.PrevPtr], ebx + + mov [ETH_frame_tail], eax + mov [ebx + NET_BUFF.NextPtr], eax + + popf + +; Now queue an event to process it xor edx, edx mov eax, [ETH_input_event] mov ebx, [eax + EVENT.id] @@ -97,13 +105,11 @@ ETH_input: ret - .fail: + .full: DEBUGF DEBUG_NETWORK_ERROR, "ETH incoming queue is full, discarding packet!\n" - - pop ebx - call NET_packet_free - add esp, 4 - + popf + push eax + call NET_BUFF_free ret @@ -116,29 +122,46 @@ ETH_process_input: mov ecx, MANUAL_DESTROY call create_event mov [ETH_input_event], eax - + pushf .wait: + popf mov eax, [ETH_input_event] mov ebx, [eax + EVENT.id] call wait_event .loop: - get_from_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .wait + pushf + cli + cmp [ETH_frame_queued], 0 + je .wait - mov eax, [esi + ETH_queue_entry.packet] - mov ecx, [esi + ETH_queue_entry.size] - mov ebx, [esi + ETH_queue_entry.device] + dec [ETH_frame_queued] - pushd .loop ; return address - push ecx eax + mov esi, [ETH_frame_head] + mov ebx, [esi + NET_BUFF.NextPtr] + + mov [ETH_frame_head], ebx + mov [ebx + NET_BUFF.PrevPtr], ETH_frame_head + + popf + + mov eax, [esi + NET_BUFF.offset] + add eax, esi + mov ecx, [esi + NET_BUFF.length] + mov ebx, [esi + NET_BUFF.device] + + pushd .loop ; return address for protocol handler + push esi ; keep pointer to NET_BUFF on stack DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: size=%u\n", ecx sub ecx, sizeof.ETH_header jb .dump +; Set registers for protocol handlers lea edx, [eax + sizeof.ETH_header] mov ax, [eax + ETH_header.Type] +; Place protocol handlers here cmp ax, ETHER_PROTO_IPv4 je IPv4_input @@ -158,8 +181,7 @@ ETH_process_input: .dump: DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: dumping\n" - call NET_packet_free - add esp, 4 + call NET_BUFF_free ret ;----------------------------------------------------------------- @@ -171,11 +193,10 @@ ETH_process_input: ; ecx = payload size ; edx = pointer to destination mac ; -; OUT: eax = start of ethernet frame / 0 on error +; OUT: eax = start of net frame / 0 on error ; ebx = device ptr ; ecx = payload size -; edx = ethernet frame size -; edi = start of ethernet payload +; edi = start of payload ; ;----------------------------------------------------------------- align 4 @@ -189,11 +210,14 @@ ETH_output: push ecx push ax edx - add ecx, sizeof.ETH_header - stdcall kernel_alloc, ecx + add ecx, sizeof.ETH_header + NET_BUFF.data + stdcall NET_BUFF_alloc, ecx test eax, eax jz .out_of_ram - mov edi, eax + mov [eax + NET_BUFF.type], NET_BUFF_ETH + mov [eax + NET_BUFF.device], ebx + mov [eax + NET_BUFF.offset], NET_BUFF.data + lea edi, [eax + NET_BUFF.data] pop esi movsd @@ -204,13 +228,14 @@ ETH_output: pop ax stosw - lea eax, [edi - sizeof.ETH_header] ; Set eax to buffer start + lea eax, [edi - sizeof.ETH_header - NET_BUFF.data] ; Set eax to buffer start pop ecx - lea edx, [ecx + sizeof.ETH_header] ; Set edx to complete buffer size + lea edx, [ecx + sizeof.ETH_header] ; Set edx to complete buffer size cmp edx, ETH_FRAME_MINIMUM jbe .adjust_size .done: + mov [eax + NET_BUFF.length], edx DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: ptr=%x size=%u\n", eax, edx ret @@ -272,7 +297,7 @@ ETH_api: .read_mac: movzx ebx, word [eax + ETH_DEVICE.mac] mov eax, dword [eax + ETH_DEVICE.mac + 2] - mov [esp+20+4], ebx ; TODO: fix this ugly code + mov [esp+20+4], ebx ; FIXME ret diff --git a/kernel/trunk/network/icmp.inc b/kernel/trunk/network/icmp.inc index 3e39bccc70..151c59917a 100644 --- a/kernel/trunk/network/icmp.inc +++ b/kernel/trunk/network/icmp.inc @@ -131,7 +131,6 @@ macro ICMP_init { ; and insert packets into sockets when needed ; ; IN: Pointer to buffer in [esp] -; size of buffer in [esp+4] ; ebx = pointer to device struct ; ecx = ICMP Packet size ; esi = ptr to ICMP Packet data @@ -143,10 +142,9 @@ macro ICMP_init { align 4 ICMP_input: - DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input:\n" - -; First, check the checksum (altough some implementations ignore it) + DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input\n" +; Check the checksum push esi ecx push [esi + ICMP_header.Checksum] mov [esi + ICMP_header.Checksum], 0 @@ -155,100 +153,34 @@ ICMP_input: call checksum_2 pop si cmp dx, si - pop ecx edx + pop ecx esi jne .checksum_mismatch -; Check packet type + DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: Checksum OK\n" - cmp [edx + ICMP_header.Type], ICMP_ECHO ; Is this an echo request? - jne .check_sockets - -; Update stats (and validate device ptr) +; Ualidate device ptr + mov eax, edi call NET_ptr_to_num4 cmp edi, -1 je .dump + +; Update stats inc [ICMP_PACKETS_RX + edi] -; We well re-use the packet so we can create the response as fast as possible -; Notice: this only works on pure ethernet - - DEBUGF DEBUG_NETWORK_VERBOSE, "got echo request\n" - mov [edx + ICMP_header.Type], ICMP_ECHOREPLY ; Change Packet type to reply - - mov esi, [esp] ; Start of buffer - cmp ebx, LOOPBACK_DEVICE - je .loopback - -; FIXME: dont assume device is an ethernet device! - -; exchange dest and source address in IP header -; exchange dest and source MAC in ETH header - push dword [esi + ETH_header.DstMAC] - push dword [esi + ETH_header.SrcMAC] - pop dword [esi + ETH_header.DstMAC] - pop dword [esi + ETH_header.SrcMAC] - push word [esi + ETH_header.DstMAC + 4] - push word [esi + ETH_header.SrcMAC + 4] - pop word [esi + ETH_header.DstMAC + 4] - pop word [esi + ETH_header.SrcMAC + 4] - add esi, sizeof.ETH_header-4 - - .loopback: - add esi, 4 - push [esi + IPv4_header.SourceAddress] - push [esi + IPv4_header.DestinationAddress] - pop [esi + IPv4_header.SourceAddress] - pop [esi + IPv4_header.DestinationAddress] - -; Recalculate ip header checksum - movzx ecx, [esi + IPv4_header.VersionAndIHL] ; Calculate IP Header length by using IHL field - and ecx, 0x0f - shl cx, 2 - mov edi, ecx ; IP header length - mov eax, edx ; ICMP packet start addr - - push esi ; Calculate the IP checksum - xor edx, edx ; - call checksum_1 ; - call checksum_2 ; - pop esi ; - mov [esi + IPv4_header.HeaderChecksum], dx ; - -; Recalculate ICMP CheckSum - movzx ecx, [esi + IPv4_header.TotalLength] ; Find length of IP Packet - xchg ch, cl ; - sub ecx, edi ; IP packet length - IP header length = ICMP packet length - - mov esi, eax ; Calculate ICMP checksum - xor edx, edx ; - call checksum_1 ; - call checksum_2 ; - mov [eax + ICMP_header.Checksum], dx ; - -; Transmit the packet (notice that packet ptr and packet size have been on stack since start of the procedure!) - call [ebx + NET_DEVICE.transmit] - test eax, eax - jnz @f - call NET_ptr_to_num4 - inc [ICMP_PACKETS_TX + edi] - @@: - ret - - - - - .check_sockets: - ; Look for an open ICMP socket +; Is this an echo request? + cmp [esi + ICMP_header.Type], ICMP_ECHO + je .echo_request +; Look for an open ICMP socket pusha mov ecx, socket_mutex call mutex_lock popa - mov esi, [edi] ; ipv4 source address + mov edx, [eax] ; ipv4 source address mov eax, net_sockets .try_more: -; mov , [edx + ICMP_header.Identifier] +; mov , [esi + ICMP_header.Identifier] .next_socket: mov eax, [eax + SOCKET.NextPtr] or eax, eax @@ -260,18 +192,12 @@ ICMP_input: cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP jne .next_socket - cmp [eax + IP_SOCKET.RemoteIP], esi + cmp [eax + IP_SOCKET.RemoteIP], edx jne .next_socket ; cmp [eax + ICMP_SOCKET.Identifier], ; jne .next_socket -; Update stats (and validate device ptr) - call NET_ptr_to_num4 - cmp edi, -1 - je .dump_ - inc [ICMP_PACKETS_RX + edi] - pusha mov ecx, socket_mutex call mutex_unlock @@ -284,11 +210,82 @@ ICMP_input: call mutex_lock popa - mov esi, edx jmp SOCKET_input - .dump_: + + .echo_request: + +; We'll reuse the packet so we can create the response as fast as possible + DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP echo request\n" + +; Change Packet type to reply + mov [esi + ICMP_header.Type], ICMP_ECHOREPLY + + mov eax, [esp] + lea esi, [eax + NET_BUFF.data] + +; Check frame type + cmp [eax + NET_BUFF.type], NET_BUFF_ETH + jne .not_ethernet + +; exchange dest and source MAC in ETH header + push dword [esi + ETH_header.DstMAC] + push dword [esi + ETH_header.SrcMAC] + pop dword [esi + ETH_header.DstMAC] + pop dword [esi + ETH_header.SrcMAC] + push word [esi + ETH_header.DstMAC + 4] + push word [esi + ETH_header.SrcMAC + 4] + pop word [esi + ETH_header.DstMAC + 4] + pop word [esi + ETH_header.SrcMAC + 4] + add esi, sizeof.ETH_header + + .not_ethernet: +; Exchange dest and source address in IP header + push [esi + IPv4_header.SourceAddress] + push [esi + IPv4_header.DestinationAddress] + pop [esi + IPv4_header.SourceAddress] + pop [esi + IPv4_header.DestinationAddress] + +; Calculate IP header length + movzx ecx, [esi + IPv4_header.VersionAndIHL] + and ecx, 0x0f + shl cx, 2 + mov edi, ecx ; put it in edi for later + +; Calculate IP checksum + mov eax, esi + mov [eax + IPv4_header.HeaderChecksum], 0 + xor edx, edx + call checksum_1 + call checksum_2 + mov [eax + IPv4_header.HeaderChecksum], dx + +; Calculate ICMP packet length + movzx ecx, [eax + IPv4_header.TotalLength] + xchg ch, cl + sub ecx, edi ; IP packet length - IP header length = ICMP packet length + +; Calculate ICMP checkSum + mov eax, esi + mov [esi + ICMP_header.Checksum], 0 + xor edx, edx + call checksum_1 + call checksum_2 + mov [eax + ICMP_header.Checksum], dx + +; Transmit the frame + DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP transmitting reply\n" + call [ebx + NET_DEVICE.transmit] + test eax, eax + jnz @f + DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP transmit failed\n" + call NET_ptr_to_num4 + inc [ICMP_PACKETS_TX + edi] + @@: + ret + + .dump_: pusha mov ecx, socket_mutex call mutex_unlock @@ -297,16 +294,12 @@ ICMP_input: DEBUGF DEBUG_NETWORK_ERROR, "ICMP_input: no socket found\n" jmp .dump - .checksum_mismatch: DEBUGF DEBUG_NETWORK_ERROR, "ICMP_input: checksum mismatch\n" .dump: DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: dumping\n" - - call NET_packet_free - add esp, 4 ; pop (balance stack) - + call NET_BUFF_free ret @@ -400,7 +393,6 @@ ICMP_output_raw: jz .exit pop esi - push edx push eax push edi ecx @@ -426,7 +418,6 @@ ICMP_output_raw: ret .exit: DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n" - add esp, 4 ret diff --git a/kernel/trunk/network/loopback.inc b/kernel/trunk/network/loopback.inc index e392f59f77..f0147cc020 100644 --- a/kernel/trunk/network/loopback.inc +++ b/kernel/trunk/network/loopback.inc @@ -66,54 +66,56 @@ local .fail ; LOOP_input ; ; IN: [esp+4] = Pointer to buffer -; [esp+8] = size of buffer ; ; OUT: / ; ;----------------------------------------------------------------- align 4 LOOP_input: - pop ebx - pop eax - pop ecx - push ebx - push ecx - push eax + mov eax, [esp+4] +; Update stats inc [LOOPBACK_DEVICE.packets_rx] + + mov ecx, [eax + NET_BUFF.length] add dword[LOOPBACK_DEVICE.bytes_rx], ecx adc dword[LOOPBACK_DEVICE.bytes_rx + 4], 0 - DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_input: size=%u\n", ecx - lea edx, [eax + 4] - mov eax, dword[eax] - mov ebx, LOOPBACK_DEVICE + DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_input: ptr=%x size=%u\n", eax, ecx +; Reverse buffptr and returnaddr on stack + pop edx edi + push edx edi + +; Set registers for protocol handlers + lea edx, [eax + NET_BUFF.data] + mov ebx, [eax + NET_BUFF.device] + mov eax, [eax + NET_BUFF.type] + +; Place protocol handlers here cmp eax, AF_INET4 je IPv4_input - DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_input: Unknown packet type=%x\n", ax + DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_input: Unknown packet type=%x\n", eax .dump: DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_input: dumping\n" - call NET_packet_free - add esp, 4 + call NET_BUFF_free ret + ;----------------------------------------------------------------- ; ; LOOP_output ; -; IN: -; ecx = packet size +; IN: ecx = packet size ; edi = address family ; -; OUT: edi = 0 on error, pointer to buffer otherwise -; eax = buffer start +; OUT: eax = start of net frame / 0 on error ; ebx = to device structure ; ecx = unchanged (packet size of embedded data) -; edx = size of complete buffer +; edi = start of payload ; ;----------------------------------------------------------------- align 4 @@ -121,35 +123,38 @@ LOOP_output: DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_output\n" - push ecx - push edi - - add ecx, 4 cmp ecx, [LOOPBACK_DEVICE.mtu] - ja .out_of_ram - stdcall kernel_alloc, ecx + ja .too_large + + push ecx edi + stdcall NET_BUFF_alloc, ecx test eax, eax jz .out_of_ram - mov edi, eax - pop eax - stosd - lea eax, [edi - 4] ; Set eax to buffer start - pop ecx - lea edx, [ecx + 4] ; Set edx to complete buffer size + pop edi + mov [eax + NET_BUFF.type], edi mov ebx, LOOPBACK_DEVICE + mov [eax + NET_BUFF.device], ebx + pop ecx + mov [eax + NET_BUFF.length], ecx + lea edi, [eax + NET_BUFF.data] inc [LOOPBACK_DEVICE.packets_tx] add dword[LOOPBACK_DEVICE.bytes_tx], ecx adc dword[LOOPBACK_DEVICE.bytes_tx + 4], 0 - DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_output: ptr=%x size=%u\n", eax, edx + DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_output: ptr=%x size=%u\n", eax, ecx + ret + + .too_large: + DEBUGF DEBUG_NETWORK_ERROR, "LOOP_output: packet is too large\n" + xor eax, eax ret .out_of_ram: DEBUGF DEBUG_NETWORK_ERROR, "LOOP_output: out of memory\n" add esp, 4+4 - xor edi, edi + xor eax, eax ret diff --git a/kernel/trunk/network/socket.inc b/kernel/trunk/network/socket.inc index 374534b27c..f32e8c8a13 100644 --- a/kernel/trunk/network/socket.inc +++ b/kernel/trunk/network/socket.inc @@ -179,8 +179,8 @@ ends struct socket_queue_entry data_ptr dd ? - buf_ptr dd ? data_size dd ? + buf_ptr dd ? ends @@ -822,7 +822,7 @@ SOCKET_receive_dgram: rep movsd .nd: - call NET_packet_free + call NET_BUFF_free pop ecx eax ; return number of bytes copied to application xor ebx, ebx ret @@ -1441,7 +1441,6 @@ SOCKET_check_port: ; ecx = data size ; esi = ptr to data ; [esp] = ptr to buf -; [esp + 4] = buf size ; ; OUT: / ; @@ -1451,7 +1450,7 @@ SOCKET_input: DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_input: socket=%x, data=%x size=%u\n", eax, esi, ecx - mov [esp+4], ecx + push ecx push esi mov esi, esp @@ -1475,16 +1474,13 @@ SOCKET_input: call mutex_unlock popa - call NET_packet_free - add esp, 8 - + call NET_BUFF_free ret ;-------------------------- ; -; IN: eax = ptr to ring struct (just a buffer of the right size) -; OUT: eax = unchanged / 0 on error +; eax = ptr to ring struct (just a buffer of the right size) ; align 4 SOCKET_ring_create: diff --git a/kernel/trunk/network/stack.inc b/kernel/trunk/network/stack.inc index 77f913539b..49c1bf06ae 100644 --- a/kernel/trunk/network/stack.inc +++ b/kernel/trunk/network/stack.inc @@ -155,6 +155,10 @@ NET_LINK_IEEE802.11 = 3 ; IEEE 802.11 (WiFi) NET_HWACC_TCP_IPv4_IN = 1 shl 0 NET_HWACC_TCP_IPv4_OUT = 1 shl 1 +; Network frame types +NET_BUFF_LOOPBACK = 0 +NET_BUFF_ETH = 1 + struct NET_DEVICE device_type dd ? ; Type field @@ -175,6 +179,18 @@ struct NET_DEVICE ends +struct NET_BUFF + + NextPtr dd ? ; pointer to next frame in list + PrevPtr dd ? ; pointer to previous frame in list + device dd ? ; ptr to NET_DEVICE structure + type dd ? ; encapsulation type: e.g. Ethernet + length dd ? ; size of encapsulated data + offset dd ? ; offset to actual data (24 bytes for default frame) + data rb 0 + +ends + ; Exactly as it says.. macro pseudo_random reg { @@ -327,7 +343,13 @@ stack_handler: align 4 -NET_packet_free: +NET_BUFF_alloc: + add dword[esp+4], NET_BUFF.data + jmp kernel_alloc + + +align 4 +NET_BUFF_free: and dword[esp+4], not 0xfff jmp kernel_free @@ -482,8 +504,10 @@ NET_ptr_to_num: align 4 NET_ptr_to_num4: ; Todo, place number in device structure so we only need to verify? - push ecx + test ebx, ebx + jz .fail + push ecx mov ecx, NET_DEVICES_MAX mov edi, NET_DRV_LIST .loop: @@ -493,8 +517,9 @@ NET_ptr_to_num4: ; Todo, place number in device structure so we o dec ecx jnz .loop - or edi, -1 pop ecx + .fail: + or edi, -1 ret .found: diff --git a/kernel/trunk/network/tcp.inc b/kernel/trunk/network/tcp.inc index 8971e027fa..7fda239010 100644 --- a/kernel/trunk/network/tcp.inc +++ b/kernel/trunk/network/tcp.inc @@ -124,9 +124,8 @@ struct TCP_queue_entry segment_ptr dd ? segment_size dd ? device_ptr dd ? - - buffer_ptr dd ? timestamp dd ? + buffer_ptr dd ? ends diff --git a/kernel/trunk/network/tcp_input.inc b/kernel/trunk/network/tcp_input.inc index 5bfc0de242..9a363d191c 100644 --- a/kernel/trunk/network/tcp_input.inc +++ b/kernel/trunk/network/tcp_input.inc @@ -23,7 +23,6 @@ $Revision$ ; Add a segment to the incoming TCP queue ; ; IN: [esp] = ptr to buffer -; [esp+4] = buffer size (dont care) ; ebx = ptr to device struct ; ecx = segment size ; esi = ptr to TCP segment @@ -37,10 +36,8 @@ align 4 TCP_input: ; record the current time - mov eax, [timer_ticks] ; in 1/100 seconds - mov [esp + 4], eax - - push ebx ecx esi edi ; mind the order + push [timer_ticks] ; in 1/100 seconds + push ebx ecx esi edi ; mind the order (see TCP_queue_entry struct) mov esi, esp add_to_queue TCP_queue, TCP_QUEUE_SIZE, sizeof.TCP_queue_entry, .fail @@ -64,14 +61,11 @@ TCP_input: inc [TCP_segments_missed + edi] add esp, sizeof.TCP_queue_entry - 8 - call NET_packet_free - add esp, 4 - + call NET_BUFF_free ret - align 4 proc TCP_process_input @@ -1595,7 +1589,7 @@ align 4 .done: DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: dumping\n" - call NET_packet_free + call NET_BUFF_free jmp .loop @@ -1714,7 +1708,7 @@ align 4 .drop_no_socket: DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Drop (no socket)\n" - call NET_packet_free + call NET_BUFF_free jmp .loop endp diff --git a/kernel/trunk/network/tcp_output.inc b/kernel/trunk/network/tcp_output.inc index c24f708014..0acbb4dcf8 100644 --- a/kernel/trunk/network/tcp_output.inc +++ b/kernel/trunk/network/tcp_output.inc @@ -522,7 +522,6 @@ endl pop esi ; headersize add esp, esi ; remove it from stack - push edx ; packet size for send proc push eax ; packet ptr for send proc mov edx, edi ; begin of data @@ -537,7 +536,7 @@ endl ; ecx = buffer size ; edi = ptr to buffer - mov eax, [esp + 16] ; get socket ptr + mov eax, [esp + 12] ; get socket ptr push edx push [eax + TCP_SOCKET.SND_NXT] ; we'll need this for timing the transmission @@ -552,7 +551,7 @@ endl pop edi pop esi ; begin of data pop ecx ; full packet size - mov eax, [esp + 12] ; socket ptr + mov eax, [esp + 8] ; socket ptr ;---------------------------------- ; initialize retransmit timer (400) diff --git a/kernel/trunk/network/tcp_subr.inc b/kernel/trunk/network/tcp_subr.inc index 70ecdf1144..96e5b0b43d 100644 --- a/kernel/trunk/network/tcp_subr.inc +++ b/kernel/trunk/network/tcp_subr.inc @@ -292,7 +292,7 @@ TCP_respond: call IPv4_output jz .error pop esi cx - push edx eax + push eax ;----------------------------------------------- ; Fill in the TCP header by using the socket ptr @@ -376,7 +376,7 @@ TCP_respond_segment: jz .error pop esi cx - push edx eax + push eax ;--------------------------------------------------- ; Fill in the TCP header by using a received segment diff --git a/kernel/trunk/network/udp.inc b/kernel/trunk/network/udp.inc index 9219366b60..3df4d8d9b8 100644 --- a/kernel/trunk/network/udp.inc +++ b/kernel/trunk/network/udp.inc @@ -154,7 +154,7 @@ UDP_input: .next_socket: mov eax, [eax + SOCKET.NextPtr] or eax, eax - jz .dump_ + jz .unlock_dump cmp [eax + SOCKET.Domain], AF_INET4 jne .next_socket @@ -213,30 +213,25 @@ UDP_input: mov [eax + UDP_SOCKET.RemotePort], cx jmp .updatesock - .dump_: - + .unlock_dump: pusha mov ecx, socket_mutex call mutex_unlock popa DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: no socket found\n" - jmp .dump .checksum_mismatch: DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: checksum mismatch\n" .dump: - call NET_packet_free - add esp, 4 ; pop (balance stack) - DEBUGF DEBUG_NETWORK_VERBOSE,"UDP_input: dumping\n" - + DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: dumping\n" + call NET_BUFF_free ret - ;----------------------------------------------------------------- ; ; UDP_output @@ -260,7 +255,7 @@ UDP_output: mov dx, [eax + UDP_SOCKET.LocalPort] DEBUGF DEBUG_NETWORK_VERBOSE, "local port=%x\n", dx - sub esp, 8 ; Data ptr and data size will be placed here + sub esp, 4 ; Data ptr will be placed here push edx esi mov edx, [eax + IP_SOCKET.LocalIP] mov eax, [eax + IP_SOCKET.RemoteIP] @@ -269,7 +264,6 @@ UDP_output: call IPv4_output jz .fail mov [esp + 8], eax ; pointer to buffer start - mov [esp + 8 + 4], edx ; buffer size mov [edi + UDP_header.Length], cx rol [edi + UDP_header.Length], 8