Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 5521 → Rev 5522

/drivers/ethernet/3c59x.asm
289,9 → 289,7
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
call set_active_port
 
call create_rx_ring
test eax, eax
jnz .err
 
call rx_reset
call tx_reset
 
816,13 → 817,15
mov ecx, 6
rep stosd
 
xor eax, eax
ret
 
.err:
DEBUGF 2,"reset failed\n"
or eax, -1
ret
 
 
 
 
 
align 4
start_device:
DEBUGF 1,"Starting the device\n"
902,6 → 905,7
 
; Set link state to unknown
mov [ebx + device.state], ETH_LINK_UNKNOWN
xor eax, eax
 
ret
 
997,10 → 1001,13
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,10 → 1021,15
dec ecx
jnz .loop
 
xor eax, eax
ret
 
.out_of_mem:
or eax, -1
ret
 
 
 
;---------------------------------------------------------------------------
; Function
; try_link_detect
1039,15 → 1051,14
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 ;
push eax
mov [eax + NET_BUFF.length], 20
 
mov edi, eax
 
lea edi, [eax + NET_BUFF.data]
lea esi, [ebx + device.mac]
movsw
movsd
1092,10 → 1103,12
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
 
; wait for reset to complete
mov esi, 2000
invoke Sleep ; 2s
invoke Sleep ; 2s FIXME
mov eax, [esp]
call mdio_read ; returns with window #4
test ah, 0x80
1407,14 → 1420,15
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
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
;; 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
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
 
.fail:
DEBUGF 2,"Send failed\n"
invoke KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
2190,38 → 2209,38
;; 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
 
; 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,7 → 2338,7
out dx, ax
 
.finish:
mov [ebx + device.curr_tx], esi
mov [ebx + device.curr_tx], edi
popf
xor eax, eax
ret
2325,7 → 2345,7
 
.fail:
DEBUGF 2,"Send failed\n"
invoke KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
2493,7 → 2513,7
 
.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
.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
jnz .dma_loop
 
; registrate the received packet to kernel
jmp Eth_input
jmp [EthInput]
 
; discard the top frame received
.discard_frame:
2678,8 → 2701,11
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
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
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
 
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:
/drivers/ethernet/R6040.asm
137,7 → 137,7
MAC_SM = 0xAC ; MAC status machine
MAC_ID = 0xBE ; Identifier register
 
MAX_BUF_SIZE = 0x600 ; 1536
MAX_BUF_SIZE = 1514
 
MBCR_DEFAULT = 0x012A ; MAC Bus Control Register
MCAST_MAX = 3 ; Max number multicast addresses to filter
396,12 → 396,11
;
; - Stop the device
; - Detach int handler
; - Remove device from local list (RTL8139_LIST)
; - Remove device from local list (device_list)
; - call unregister function in kernel
; - Remove all allocated structures and buffers the card used
 
or eax,-1
 
ret
 
 
452,6 → 451,7
cmp ax, 0xFFFF
jne @f
DEBUGF 2, "Failed to detect an attached PHY!\n"
.err:
mov eax, -1
ret
@@:
462,6 → 462,8
; Initialize and alloc RX/TX buffers
call init_txbufs
call init_rxbufs
test eax, eax
jnz .err
 
; Read the PHY ID
mov [ebx + device.phy_mode], MCR0_FD
662,19 → 664,19
 
.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,10 → 685,15
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
 
 
 
align 4
phy_mode_chk:
 
734,21 → 741,22
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
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
.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
 
; 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,15 → 802,18
 
.wait_to_send:
DEBUGF 1,"Waiting for TX buffer\n"
 
invoke GetTimerTicks ; returns in eax
lea edx, [eax + 100]
.l2:
mov esi, [bufferptr]
test [edi + x_head.status], DSC_OWNER_MAC
jz .do_send
popf
mov esi, 10
invoke Sleep
invoke GetTimerTicks
pushf
cli
cmp edx, eax
jb .l2
 
808,7 → 820,7
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
and ecx, 0xFFF
sub ecx, 4 ; Do not count the CRC
 
DEBUGF 1,"packet ptr=0x%x size=%u\n", [edx + x_head.skb_ptr], ecx
 
; Update stats
add dword[ebx + device.bytes_rx], ecx
adc dword[ebx + device.bytes_rx + 4], 0
inc dword[ebx + device.packets_rx]
 
; Push packet size and pointer, kernel will need it..
push ebx
; Push packet ptr and return addr for Eth_input
push .more_RX
mov eax, [edx + x_head.skb_ptr]
push eax
mov [eax + NET_BUFF.length], ecx
mov [eax + NET_BUFF.device], ebx
mov [eax + NET_BUFF.offset], NET_BUFF.data
 
push ecx
push [edx + x_head.skb_ptr]
 
DEBUGF 1,"packet ptr=0x%x\n", [edx + x_head.skb_ptr]
 
; reset the RX descriptor
; reset the RX descriptor (alloc new buffer)
push edx
invoke KernelAlloc, MAX_BUF_SIZE
invoke NetAlloc, MAX_BUF_SIZE+NET_BUFF.data
pop edx
mov [edx + x_head.skb_ptr], eax
invoke GetPhysAddr
add eax, NET_BUFF.data
mov [edx + x_head.buf], eax
mov [edx + x_head.status], DSC_OWNER_MAC
 
918,11 → 933,10
and [ebx + device.cur_rx], RX_RING_SIZE - 1
 
; At last, send packet to kernel
jmp [Eth_input]
jmp [EthInput]
 
 
.no_RX:
 
test word[esp], TX_FINISH
jz .no_TX
 
941,7 → 955,7
 
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
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
/drivers/ethernet/RTL8029.asm
665,17 → 665,18
;***************************************************************************
; Function
; transmit
; buffer in [esp+4], size in [esp+8], pointer to device struct in ebx
; buffer in [esp+4], pointer to device struct in ebx
;***************************************************************************
 
proc transmit stdcall buffer_ptr, buffer_size
proc transmit stdcall buffer_ptr
 
pushf
cli
 
mov esi, [buffer_ptr]
mov ecx, [buffer_size]
mov ecx, [esi + NET_BUFF.length]
DEBUGF 1, "Transmitting packet, buffer:%x, size:%u\n", esi, ecx
lea eax, [esi + NET_BUFF.data]
DEBUGF 1, "To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
[esi+0]:2,[esi+1]:2,[esi+2]:2,[esi+3]:2,[esi+4]:2,[esi+5]:2,[esi+6]:2,[esi+7]:2,[esi+8]:2,[esi+9]:2,[esi+10]:2,[esi+11]:2,[esi+13]:2,[esi+12]:2
 
686,9 → 687,10
 
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,11 → 716,10
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
725,7 → 726,7
 
.err:
DEBUGF 2, "Transmit error!\n"
invoke KernelFree, [buffer_ptr]
invoke NetFree, [buffer_ptr]
popf
or eax, -1
ret
785,14 → 786,15
jz .no_rx ; FIXME: Only PIO mode supported for now
 
; allocate a buffer
invoke KernelAlloc, ETH_FRAME_LEN
invoke NetAlloc, ETH_FRAME_LEN+NET_BUFF.data
test eax, eax
jz .rx_fail_2
 
; Push return address and packet ptr to stack
pushd .no_rx
pushd 0 ; Reserve some space for the packet size
push eax
mov [eax + NET_BUFF.device], ebx
mov [eax + NET_BUFF.offset], NET_BUFF.data
 
; read offset for current packet from device
set_io [ebx + device.io_addr], 0
826,8 → 828,8
movzx esi, ch ; we are using 256 byte pages
shl esi, 8 ; esi now holds the offset for current packet
 
; Get packet header in ecx
push ecx ; reserve 4 bytes on stack to put packet header in
; Write packet header to frame header size field
push ecx
mov edi, esp
mov cx, 4
call PIO_read
840,7 → 842,8
; calculate packet length in ecx
shr ecx, 16
sub ecx, 4 ; CRC doesnt count as data byte
mov [esp + 8], ecx
mov edi, [esp+4]
mov [edi + NET_BUFF.length], ecx
 
; check if packet size is ok
cmp ecx, ETH_ZLEN
856,7 → 859,7
 
; 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
out dx, al
 
; now send the data to the kernel
jmp [Eth_input]
jmp [EthInput]
 
.rx_fail_3:
add esp, 4
/drivers/ethernet/RTL8139.asm
404,7 → 404,6
; - Remove all allocated structures and buffers the card used
 
or eax, -1
 
ret
 
 
628,27 → 627,26
;; ;;
;; 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
jz .wait_to_send
 
.send_packet:
; 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
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
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, [buffersize]
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 ecx, [esi + NET_BUFF.length]
add dword [ebx + device.bytes_tx], ecx
adc dword [ebx + device.bytes_tx+4], 0
 
DEBUGF 1, "Packet Sent!\n"
popf
xor eax, eax
710,7 → 709,7
 
.fail:
DEBUGF 2, "transmit failed!\n"
invoke KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
795,18 → 794,21
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
rep movsd
.nd:
 
jmp [Eth_input] ; Send it to kernel
jmp [EthInput] ; Send it to kernel
 
.abort:
pop eax ebx
923,7 → 925,7
.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
 
/drivers/ethernet/RTL8169.asm
175,10 → 175,10
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
 
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
DEBUGF 1,"resetting\n"
 
call init_ring
test eax, eax
jnz .err
 
call hw_start
 
; clear packet/byte counters
678,10 → 681,13
xor eax, eax
ret
 
.err:
DEBUGF 2,"failed!\n"
or eax, -1
ret
 
 
 
 
align 4
PHY_config:
 
800,9 → 806,12
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
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
;
;***************************************************************************
 
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,7 → 1041,9
; 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
 
1033,8 → 1050,7
;------------------------
; 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
; 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
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,22 → 1154,27
lea esi, [ebx + device.rx_ring + eax]
 
DEBUGF 1,"RxDesc.status = 0x%x\n", [esi + rx_desc.status]
mov eax, [esi + rx_desc.status]
test eax, DSB_OWNbit ;;;
jnz .no_own
mov ecx, [esi + rx_desc.status]
test ecx, DSB_OWNbit ;;;
jnz .rx_return
 
DEBUGF 1,"cur_rx = %u\n", [ebx + device.cur_rx]
 
test eax, SD_RxRES
test ecx, SD_RxRES
jnz .rx_return ;;;;; RX error!
 
push ebx
push .check_more
and eax, 0x00001FFF
add eax, -4 ; we dont need CRC
and ecx, 0x00001FFF
add ecx, -4 ; we dont need CRC
DEBUGF 1,"data length = %u\n", ecx
mov eax, [esi + rx_desc.buf_soft_addr]
push eax
DEBUGF 1,"data length = %u\n", ax
mov [eax + NET_BUFF.length], ecx
mov [eax + NET_BUFF.device], ebx
mov [eax + NET_BUFF.offset], NET_BUFF.data
 
;-------------
; Update stats
 
add dword [ebx + device.bytes_rx], eax
1161,15 → 1181,16
adc dword [ebx + device.bytes_rx + 4], 0
inc [ebx + device.packets_rx]
 
pushd [esi + rx_desc.buf_soft_addr]
 
;----------------------
; Allocate a new buffer
 
invoke KernelAlloc, RX_BUF_SIZE
invoke NetAlloc, RX_BUF_SIZE+NET_BUFF.data
mov [esi + rx_desc.buf_soft_addr], eax
invoke GetPhysAddr
add eax, NET_BUFF.data
mov dword [esi + rx_desc.buf_addr], eax
 
;---------------
; reset OWN bit
 
mov eax, DSB_OWNbit or RX_BUF_SIZE
1179,15 → 1200,15
@@:
mov [esi + rx_desc.status], eax
 
;--------------
; Update rx ptr
 
inc [ebx + device.cur_rx]
and [ebx + device.cur_rx], NUM_RX_DESC - 1
 
jmp [Eth_input]
jmp [EthInput]
.rx_return:
DEBUGF 1,"RX error!\n"
.no_own:
 
pop ax
.no_rx:
 
1196,30 → 1217,31
 
test ax, ISB_TxOK or ISB_TxErr or ISB_TxDescUnavail
jz .no_tx
push ax
 
DEBUGF 1,"TX done!\n"
 
mov ecx, NUM_TX_DESC
lea esi, [ebx + device.tx_ring]
.txloop:
mov esi, [ebx + device.last_tx]
imul esi, sizeof.tx_desc
lea esi, [ebx + device.tx_ring + esi]
 
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, 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_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
/drivers/ethernet/dec21x4x.asm
594,8 → 594,6
@@:
 
 
;;; 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
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
mov [ebx + device.last_tx], eax
mov [ebx + device.cur_rx], eax
 
; xor eax, eax
ret
 
.out_of_mem:
1043,13 → 1046,15
 
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
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
;; ;;
;; 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
 
; 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
ret
 
.fail:
DEBUGF 2,"Transmit failed\n"
invoke KernelFree, [bufferptr]
DEBUGF 1,"Transmit failed\n"
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
1241,7 → 1251,7
 
mov [eax + desc.buffer1], 0
DEBUGF 1,"Free buffer 0x%x\n", [eax + TX_RING_SIZE*sizeof.desc]
invoke KernelFree, [eax + TX_RING_SIZE*sizeof.desc]
invoke NetFree, [eax + TX_RING_SIZE*sizeof.desc]
 
; advance to next descriptor
inc [ebx + device.last_tx]
1254,7 → 1264,6
 
;----------------------------------
; RX irq
 
test eax, CSR5_RI
jz .not_rx
push eax esi ecx
1271,7 → 1280,7
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
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
 
; 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
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
/drivers/ethernet/forcedeth.asm
35,7 → 35,7
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
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
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,14 → 1406,20
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
 
 
 
 
 
; Input: none
; Output: none
align 4
1781,41 → 1790,42
;; 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
 
; 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
 
.fail:
DEBUGF 2,"Send failed\n"
invoke KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
1896,33 → 1905,33
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
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
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
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
/drivers/ethernet/i8254x.asm
472,7 → 472,6
; - Remove all allocated structures and buffers the card used
 
or eax, -1
 
ret
 
 
560,8 → 559,9
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
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
;; ;;
;; 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
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
 
; 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
call clean_tx
 
DEBUGF 2,"Send failed\n"
invoke KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
833,8 → 838,11
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
 
; 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
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
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
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]
/drivers/ethernet/i8255x.asm
18,9 → 18,7
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
; TODO: use separate descriptors in memory instead of placing them in front of packets!
 
 
format PE DLL native
entry START
 
78,6 → 76,8
CmdTxFlex = 0x0008
Cmdsuspend = 0x4000
 
CmdRxFlex = 0x0008
 
reg_scb_status = 0
reg_scb_cmd = 2
reg_scb_ptr = 4
487,6 → 487,8
; Create RX and TX descriptors
 
call create_ring
test eax, eax
jz .error
 
; RX start
 
494,6 → 496,7
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,7 → 583,11
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
;---------------------
; 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
invoke GetPhysAddr
mov [ebx + device.txfd.desc_addr], eax
 
.out_of_mem:
 
ret
 
 
622,33 → 634,37
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
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
 
; 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
ret
 
.fail:
invoke KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
738,19 → 753,20
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
 
; 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
call cmd_wait
 
; And give packet to kernel
jmp [Eth_input]
jmp [EthInput]
 
.nodata:
DEBUGF 1, "no more data\n"
/drivers/ethernet/mtd80x.asm
473,7 → 473,6
; - Remove all allocated structures and buffers the card used
 
or eax, -1
 
ret
 
 
627,6 → 626,8
out dx, eax
 
call init_ring
test eax, eax
jnz .err
 
; Initialize other registers.
; Configure the PCI bus bursts and FIFO thresholds.
676,9 → 677,14
xor eax, eax
ret
 
.err:
DEBUGF 2, "Error!\n"
or eax, -1
ret
 
 
 
 
align 4
init_ring:
 
690,7 → 696,7
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
invoke GetPhysAddr
mov [esi + descriptor.next_desc], eax
 
invoke KernelAlloc, 1536
pop esi
push esi
invoke NetAlloc, 1514+NET_BUFF.data
pop esi ecx
test eax, eax
jz .out_of_mem
push ecx esi
mov [esi + descriptor.skbuff], eax
invoke GetPgAddr
add eax, NET_BUFF.data
pop esi ecx
mov [esi + descriptor.buffer], eax
 
750,9 → 759,14
set_io [ebx + device.io_addr], TXLBA
out dx, eax
 
xor eax, eax
ret
 
.out_of_mem:
or eax, -1
ret
 
 
align 4
set_rx_mode:
 
924,25 → 938,25
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
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
 
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
 
; 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
 
.fail:
DEBUGF 2,"Transmit failed\n"
invoke KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
1068,8 → 1085,12
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
1076,18 → 1097,20
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
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
/drivers/ethernet/pcnet32.asm
491,7 → 491,7
 
.destroy:
; todo: reset device into virgin state
 
add eax, NET_BUFF.data
dec [devices]
.err:
DEBUGF 2,"Error, removing all data !\n"
522,7 → 522,6
; - Remove all allocated structures and buffers the card used
 
or eax,-1
 
ret
 
 
868,6 → 867,8
movsw
 
call init_ring
test eax, eax
jnz .fail
 
mov edx, [ebx + device.io_addr] ; init ring destroys edx
 
923,6 → 924,7
 
DEBUGF 1,"reset complete\n"
xor eax, eax
.fail:
ret
 
 
938,10 → 940,13
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,11 → 972,18
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
 
 
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Transmit ;;
980,38 → 992,40
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
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
 
; 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
 
.fail:
DEBUGF 2, "Send failed\n"
invoke KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
1124,8 → 1138,11
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,9 → 1150,12
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
 
1142,8 → 1162,16
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
 
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
/drivers/ethernet/rhine.asm
346,7 → 346,7
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
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
 
; Initialize rings
call init_ring
test eax, eax
jnz .err
 
; Set Multicast
call set_rx_mode
968,7 → 966,6
out dx, al
 
; Set Fulldupex
 
call QueryAuto
test eax, eax ; full duplex?
jz @f
1007,8 → 1004,13
xor eax, eax
ret
 
.err:
DEBUGF 2,"Error!\n"
or eax, -1
ret
 
 
 
align 4
unload:
 
1073,10 → 1075,13
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,9 → 1125,15
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
 
 
align 4
QueryAuto:
 
1349,8 → 1360,8
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
;; 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
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
 
; 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
 
.fail:
DEBUGF 2,"Transmit failed\n"
invoke KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
1481,7 → 1493,6
DEBUGF 1,"INT\n"
 
; Find pointer of device which made IRQ occur
 
mov ecx, [devices]
test ecx, ecx
jz .nothing
1506,9 → 1517,7
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
pop ebx
 
; Get the current descriptor pointer
 
movzx eax, [ebx + device.cur_rx]
mov ecx, sizeof.rx_head
mul ecx
1529,9 → 1537,8
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]
 
1538,7 → 1545,6
; TODO: check error bits
 
; get length
 
mov ecx, [edi + rx_head.status]
and ecx, RX_SBITS_FRAME_LENGTH
shr ecx, 16
1545,41 → 1551,37
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
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
 
push ecx ; full packet size
push [edi + rx_head.buff_addr_virt]
 
; 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
 
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
 
; 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
@@:
/drivers/ethernet/sis900.asm
414,7 → 414,6
; - Remove all allocated structures and buffers the card used
 
or eax, -1
 
ret
 
;***************************************************************************
612,12 → 611,13
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
;***************************************************************************
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
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
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
 
.fail:
DEBUGF 2,"Transmit failed\n"
invoke KernelFree, [bufferptr]
invoke NetFree, [bufferptr]
popf
or eax, -1
ret
1151,16 → 1153,19
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
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
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
/drivers/imports.inc
104,7 → 104,8
NetUnRegDev,\
NetPtrToNum,\
NetLinkChanged,\
Eth_input,\
IPv4_input,\
NetAlloc,\
NetFree,\
EthInput,\
\
GetPCIList
/drivers/netdrv.inc
122,6 → 122,19
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 ?
/drivers/peimport.inc
155,8 → 155,9
NetUnRegDev,\
NetPtrToNum,\
NetLinkChanged,\
Eth_input,\
IPv4_input,\
EthInput,\
NetAlloc,\
NetFree,\
\
GetPCIList
end data
/kernel/trunk/core/exports.inc
122,7 → 122,9
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', \
\
/kernel/trunk/network/ARP.inc
293,13 → 293,10
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
movsd ;
popd [edi] ; DestIP
 
push edx eax
push eax
call [ebx + NET_DEVICE.transmit]
ret
 
/kernel/trunk/network/IPv4.inc
225,10 → 225,10
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
.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
mov [eax + IPv4_FRAGMENT_entry.PrevPtr], edi
mov [eax + IPv4_FRAGMENT_entry.Owner], ebx
 
add esp, 4
ret
 
 
405,7 → 403,6
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
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
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
;
;
; 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
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
 
 
/kernel/trunk/network/IPv6.inc
147,9 → 147,7
 
.dump:
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv6_input - dumping\n"
call kernel_free
add esp, 4
 
call NET_BUFF_free
ret
 
.dump_options:
/kernel/trunk/network/PPPoE.inc
106,8 → 106,7
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
 
.dump:
DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_input: dumping\n"
call NET_packet_free
add esp, 4
call NET_BUFF_free
ret
 
 
 
 
;-----------------------------------------------------------------
;
; PPPoE_output
/kernel/trunk/network/ethernet.inc
33,30 → 33,25
 
ends
 
struct ETH_queue_entry
iglobal
align 4
 
device dd ?
packet dd ?
size dd ?
ETH_BROADCAST dp 0xffffffffffff
 
ends
ETH_frame_queued dd 0 ; Number of queued frames
 
iglobal
align 4
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
 
ETH_BROADCAST dp 0xffffffffffff
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,11 → 67,10
; ETH_input
;
; This function is called by ethernet drivers,
; It pushes the received ethernet packets onto the eth_in_queue
; It pushes the received ethernet packets onto the ethernet input queue
;
; IN: [esp] = Pointer to buffer
; [esp+4] = size of buffer
; ebx = pointer to eth_device
;
; OUT: /
;
;-----------------------------------------------------------------
83,12 → 77,26
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
 
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
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
 
.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
; 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
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
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
 
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
.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
 
 
/kernel/trunk/network/icmp.inc
131,7 → 131,6
; 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
align 4
ICMP_input:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input:\n"
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input\n"
 
; First, check the checksum (altough some implementations ignore it)
 
; Check the checksum
push esi ecx
push [esi + ICMP_header.Checksum]
mov [esi + ICMP_header.Checksum], 0
155,100 → 153,34
call checksum_2
pop si
cmp dx, si
pop ecx edx
pop ecx esi
jne .checksum_mismatch
 
; Check packet type
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: Checksum OK\n"
 
cmp [edx + ICMP_header.Type], ICMP_ECHO ; Is this an echo request?
jne .check_sockets
 
; Update stats (and validate device ptr)
; Ualidate device ptr
mov eax, edi
call NET_ptr_to_num4
cmp edi, -1
je .dump
 
; Update stats
inc [ICMP_PACKETS_RX + edi]
 
; We well re-use the packet so we can create the response as fast as possible
; Notice: this only works on pure ethernet
; Is this an echo request?
cmp [esi + ICMP_header.Type], ICMP_ECHO
je .echo_request
 
DEBUGF DEBUG_NETWORK_VERBOSE, "got echo request\n"
mov [edx + ICMP_header.Type], ICMP_ECHOREPLY ; Change Packet type to reply
 
mov esi, [esp] ; Start of buffer
cmp ebx, LOOPBACK_DEVICE
je .loopback
 
; FIXME: dont assume device is an ethernet device!
 
; exchange dest and source address in IP header
; exchange dest and source MAC in ETH header
push dword [esi + ETH_header.DstMAC]
push dword [esi + ETH_header.SrcMAC]
pop dword [esi + ETH_header.DstMAC]
pop dword [esi + ETH_header.SrcMAC]
push word [esi + ETH_header.DstMAC + 4]
push word [esi + ETH_header.SrcMAC + 4]
pop word [esi + ETH_header.DstMAC + 4]
pop word [esi + ETH_header.SrcMAC + 4]
add esi, sizeof.ETH_header-4
 
.loopback:
add esi, 4
push [esi + IPv4_header.SourceAddress]
push [esi + IPv4_header.DestinationAddress]
pop [esi + IPv4_header.SourceAddress]
pop [esi + IPv4_header.DestinationAddress]
 
; Recalculate ip header checksum
movzx ecx, [esi + IPv4_header.VersionAndIHL] ; Calculate IP Header length by using IHL field
and ecx, 0x0f
shl cx, 2
mov edi, ecx ; IP header length
mov eax, edx ; ICMP packet start addr
 
push esi ; Calculate the IP checksum
xor edx, edx ;
call checksum_1 ;
call checksum_2 ;
pop esi ;
mov [esi + IPv4_header.HeaderChecksum], dx ;
 
; Recalculate ICMP CheckSum
movzx ecx, [esi + IPv4_header.TotalLength] ; Find length of IP Packet
xchg ch, cl ;
sub ecx, edi ; IP packet length - IP header length = ICMP packet length
 
mov esi, eax ; Calculate ICMP checksum
xor edx, edx ;
call checksum_1 ;
call checksum_2 ;
mov [eax + ICMP_header.Checksum], dx ;
 
; Transmit the packet (notice that packet ptr and packet size have been on stack since start of the procedure!)
call [ebx + NET_DEVICE.transmit]
test eax, eax
jnz @f
call NET_ptr_to_num4
inc [ICMP_PACKETS_TX + edi]
@@:
ret
 
 
 
 
.check_sockets:
; Look for an open ICMP socket
 
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
mov esi, [edi] ; ipv4 source address
mov edx, [eax] ; ipv4 source address
mov eax, net_sockets
.try_more:
; mov , [edx + ICMP_header.Identifier]
; mov , [esi + ICMP_header.Identifier]
.next_socket:
mov eax, [eax + SOCKET.NextPtr]
or eax, eax
260,18 → 192,12
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
call mutex_lock
popa
 
mov esi, edx
jmp SOCKET_input
 
 
 
.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
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
jz .exit
 
pop esi
push edx
push eax
 
push edi ecx
426,7 → 418,6
ret
.exit:
DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
add esp, 4
ret
 
 
/kernel/trunk/network/loopback.inc
66,7 → 66,6
; LOOP_input
;
; IN: [esp+4] = Pointer to buffer
; [esp+8] = size of buffer
;
; OUT: /
;
73,47 → 72,50
;-----------------------------------------------------------------
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
 
DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_output\n"
 
push ecx
push edi
cmp ecx, [LOOPBACK_DEVICE.mtu]
ja .too_large
 
add ecx, 4
cmp ecx, [LOOPBACK_DEVICE.mtu]
ja .out_of_ram
stdcall kernel_alloc, ecx
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 edi
mov [eax + NET_BUFF.type], edi
mov ebx, LOOPBACK_DEVICE
mov [eax + NET_BUFF.device], ebx
pop ecx
lea edx, [ecx + 4] ; Set edx to complete buffer size
mov ebx, LOOPBACK_DEVICE
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
 
 
/kernel/trunk/network/socket.inc
179,8 → 179,8
struct socket_queue_entry
 
data_ptr dd ?
data_size dd ?
buf_ptr dd ?
data_size dd ?
 
ends
 
822,7 → 822,7
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
; ecx = data size
; esi = ptr to data
; [esp] = ptr to buf
; [esp + 4] = buf size
;
; OUT: /
;
1451,7 → 1450,7
 
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
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:
/kernel/trunk/network/stack.inc
155,6 → 155,10
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,7 → 179,19
 
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 {
add reg, [esp]
327,7 → 343,13
 
 
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
align 4
NET_ptr_to_num4: ; Todo, place number in device structure so we only need to verify?
 
test ebx, ebx
jz .fail
 
push ecx
 
mov ecx, NET_DEVICES_MAX
mov edi, NET_DRV_LIST
.loop:
493,8 → 517,9
dec ecx
jnz .loop
 
pop ecx
.fail:
or edi, -1
pop ecx
ret
 
.found:
/kernel/trunk/network/tcp.inc
124,9 → 124,8
segment_ptr dd ?
segment_size dd ?
device_ptr dd ?
 
timestamp dd ?
buffer_ptr dd ?
timestamp dd ?
 
ends
 
/kernel/trunk/network/tcp_input.inc
23,7 → 23,6
; 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
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
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
.done:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: dumping\n"
 
call NET_packet_free
call NET_BUFF_free
jmp .loop
 
 
1714,7 → 1708,7
.drop_no_socket:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Drop (no socket)\n"
 
call NET_packet_free
call NET_BUFF_free
jmp .loop
 
endp
/kernel/trunk/network/tcp_output.inc
522,7 → 522,6
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
; 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
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)
/kernel/trunk/network/tcp_subr.inc
292,7 → 292,7
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
jz .error
pop esi cx
 
push edx eax
push eax
 
;---------------------------------------------------
; Fill in the TCP header by using a received segment
/kernel/trunk/network/udp.inc
154,7 → 154,7
.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,8 → 213,7
mov [eax + UDP_SOCKET.RemotePort], cx
jmp .updatesock
 
.dump_:
 
.unlock_dump:
pusha
mov ecx, socket_mutex
call mutex_unlock
221,7 → 220,6
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: no socket found\n"
 
jmp .dump
 
.checksum_mismatch:
228,15 → 226,12
DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: checksum mismatch\n"
 
.dump:
call NET_packet_free
add esp, 4 ; pop (balance stack)
DEBUGF DEBUG_NETWORK_VERBOSE,"UDP_input: dumping\n"
 
call NET_BUFF_free
ret
 
 
 
 
;-----------------------------------------------------------------
;
; UDP_output
260,7 → 255,7
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
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