/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 |