fix in ARPcfg application

added pci ids of dec21x4x cards to netcfg
bugfixes in dex21x4x driver, pcnet32 driver, rtl8139 driver and sis900 driver
new network program (ICMP) to ping computers, uses new RAW socket code (experimental)

git-svn-id: svn://kolibrios.org@1541 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2010-07-30 21:54:27 +00:00
parent 500fea459a
commit 8a7ebf6b32
12 changed files with 745 additions and 435 deletions

View File

@ -147,8 +147,6 @@ START: ; start of execution
; DATA AREA
IM_END:
name db 'ARP manager',0
title db '# IP-address MAC-address Status TTL',0
@ -166,6 +164,8 @@ ARP_ENTRY:
include_debug_strings ; ALWAYS present in data section
IM_END:
I_PARAM rb 1024
I_END:

View File

@ -0,0 +1,319 @@
use32
org 0x0
; standard header
db 'MENUET01' ; signature
dd 1 ; header version
dd start ; entry point
dd I_END ; initialized size
dd mem ; required memory
dd mem ; stack pointer
dd 0 ; parameters
dd 0 ; path
BUFFERSIZE equ 1500
; useful includes
include '../macros.inc'
purge mov,add,sub
include '../proc32.inc'
include '../dll.inc'
include '../network.inc'
; ICMP types & codes
ICMP_ECHOREPLY equ 0 ; echo reply message
ICMP_UNREACH equ 3
ICMP_UNREACH_NET equ 0 ; bad net
ICMP_UNREACH_HOST equ 1 ; bad host
ICMP_UNREACH_PROTOCOL equ 2 ; bad protocol
ICMP_UNREACH_PORT equ 3 ; bad port
ICMP_UNREACH_NEEDFRAG equ 4 ; IP_DF caused drop
ICMP_UNREACH_SRCFAIL equ 5 ; src route failed
ICMP_UNREACH_NET_UNKNOWN equ 6 ; unknown net
ICMP_UNREACH_HOST_UNKNOWN equ 7 ; unknown host
ICMP_UNREACH_ISOLATED equ 8 ; src host isolated
ICMP_UNREACH_NET_PROHIB equ 9 ; prohibited access
ICMP_UNREACH_HOST_PROHIB equ 10 ; ditto
ICMP_UNREACH_TOSNET equ 11 ; bad tos for net
ICMP_UNREACH_TOSHOST equ 12 ; bad tos for host
ICMP_UNREACH_FILTER_PROHIB equ 13 ; admin prohib
ICMP_UNREACH_HOST_PRECEDENCE equ 14 ; host prec vio.
ICMP_UNREACH_PRECEDENCE_CUTOFF equ 15 ; prec cutoff
ICMP_SOURCEQUENCH equ 4 ; Packet lost, slow down
ICMP_REDIRECT equ 5 ; shorter route, codes:
ICMP_REDIRECT_NET equ 0 ; for network
ICMP_REDIRECT_HOST equ 1 ; for host
ICMP_REDIRECT_TOSNET equ 2 ; for tos and net
ICMP_REDIRECT_TOSHOST equ 3 ; for tos and host
ICMP_ALTHOSTADDR equ 6 ; alternate host address
ICMP_ECHO equ 8 ; echo service
ICMP_ROUTERADVERT equ 9 ; router advertisement
ICMP_ROUTERADVERT_NORMAL equ 0 ; normal advertisement
ICMP_ROUTERADVERT_NOROUTE_COMMON equ 16 ; selective routing
ICMP_ROUTERSOLICIT equ 10 ; router solicitation
ICMP_TIMXCEED equ 11 ; time exceeded, code:
ICMP_TIMXCEED_INTRANS equ 0 ; ttl==0 in transit
ICMP_TIMXCEED_REASS equ 1 ; ttl==0 in reass
ICMP_PARAMPROB equ 12 ; ip header bad
ICMP_PARAMPROB_ERRATPTR equ 0 ; error at param ptr
ICMP_PARAMPROB_OPTABSENT equ 1 ; req. opt. absent
ICMP_PARAMPROB_LENGTH equ 2 ; bad length
ICMP_TSTAMP equ 13 ; timestamp request
ICMP_TSTAMPREPLY equ 14 ; timestamp reply
ICMP_IREQ equ 15 ; information request
ICMP_IREQREPLY equ 16 ; information reply
ICMP_MASKREQ equ 17 ; address mask request
ICMP_MASKREPLY equ 18 ; address mask reply
ICMP_TRACEROUTE equ 30 ; traceroute
ICMP_DATACONVERR equ 31 ; data conversion error
ICMP_MOBILE_REDIRECT equ 32 ; mobile host redirect
ICMP_IPV6_WHEREAREYOU equ 33 ; IPv6 where-are-you
ICMP_IPV6_IAMHERE equ 34 ; IPv6 i-am-here
ICMP_MOBILE_REGREQUEST equ 35 ; mobile registration req
ICMP_MOBILE_REGREPLY equ 36 ; mobile registreation reply
ICMP_SKIP equ 39 ; SKIP
ICMP_PHOTURIS equ 40 ; Photuris
ICMP_PHOTURIS_UNKNOWN_INDEX equ 1 ; unknown sec index
ICMP_PHOTURIS_AUTH_FAILED equ 2 ; auth failed
ICMP_PHOTURIS_DECRYPT_FAILED equ 3 ; decrypt failed
virtual at 0
ICMP_Packet:
.Type db ?
.Code db ?
.Checksum dw ?
.Identifier dw ?
.SequenceNumber dw ?
.Data:
end virtual
; entry point
start:
; load libraries
stdcall dll.Load, @IMPORT
test eax, eax
jnz exit
; initialize console
push 1
call [con_start]
push title
push 25
push 80
push 25
push 80
call [con_init]
; main loop
push str1
call [con_write_asciiz]
main:
; write prompt
push str2
call [con_write_asciiz]
; read string
mov esi, s
push 256
push esi
call [con_gets]
; check for exit
test eax, eax
jz done
cmp byte [esi], 10
jz done
; delete terminating '\n'
push esi
@@:
lodsb
test al, al
jnz @b
mov byte [esi-2], al
pop esi
; resolve name
push esp ; reserve stack place
push esp ; fourth parameter
push 0 ; third parameter
push 0 ; second parameter
push esi ; first parameter
call [getaddrinfo]
pop esi
; test for error
test eax, eax
jnz fail
; convert IP address to decimal notation
mov eax, [esi+addrinfo.ai_addr]
mov eax, [eax+sockaddr_in.sin_addr]
mov [sockaddr1.ip], eax
push eax
call [inet_ntoa]
; write result
mov [ip_ptr], eax
push eax
; free allocated memory
push esi
call [freeaddrinfo]
push str4
call [con_write_asciiz]
mcall socket, AF_INET4, SOCK_RAW, IPPROTO_ICMP
cmp eax, -1
jz fail2
mov [socketnum], eax
mcall connect, [socketnum], sockaddr1, 18
mcall 40, 1 shl 7 ; + 7
; call [con_cls]
mov [count], 4
mainloop:
push str3
call [con_write_asciiz]
push [ip_ptr]
call [con_write_asciiz]
mcall 26,9
mov [time_reference], eax
mcall send, [socketnum], icmp_packet, icmp_packet.length, 0
mcall 23, 300 ; 3 seconds time-out
mcall 26,9
neg [time_reference]
add [time_reference], eax
mcall recv, [socketnum], buffer_ptr, BUFFERSIZE, 0
cmp eax, -1
je .no_response
; validate the packet
lea esi, [buffer_ptr + ICMP_Packet.Data]
mov edi, icmp_packet.data
mov ecx, 32/4
repe cmpsd
jne .miscomp
push [time_reference]
push str7
call [con_printf]
jmp continue
.miscomp:
sub edi, icmp_packet.data
push edi
push str9
call [con_printf]
jmp continue
.no_response:
push str8
call [con_write_asciiz]
continue:
dec [count]
jz done
mcall 5, 100 ; wait a second
inc [icmp_packet.id]
jmp mainloop
done:
push str10
call [con_write_asciiz]
call [con_getch2]
push 1
call [con_exit]
exit:
mcall -1
fail:
push str5
call [con_write_asciiz]
jmp done
fail2:
push str6
call [con_write_asciiz]
jmp done
; data
title db 'ICMP - test application',0
str1 db 'ICMP test application v0.1',10,' for KolibriOS # 1540 or later. ',10,10,0
str2 db '> ',0
str3 db 'Ping to: ',0
str4 db 10,0
str5 db 'Name resolution failed.',10,10,0
str6 db 'Could not open socket',10,10,0
str7 db ' time= %u0ms',10,0
str8 db ' timeout!',10,0
str9 db ' miscompare at offset %u',10,0
str10 db 10,10,'Press any key to exit',0
sockaddr1:
dw AF_INET4
.port dw 0
.ip dd 0
rb 10
time_reference dd ?
ip_ptr dd ?
count dd ?
; import
align 4
@IMPORT:
library network, 'network.obj', console, 'console.obj'
import network, \
getaddrinfo, 'getaddrinfo', \
freeaddrinfo, 'freeaddrinfo', \
inet_ntoa, 'inet_ntoa'
import console, \
con_start, 'START', \
con_init, 'con_init', \
con_write_asciiz, 'con_write_asciiz', \
con_printf, 'con_printf', \
con_exit, 'con_exit', \
con_gets, 'con_gets',\
con_cls, 'con_cls',\
con_getch2, 'con_getch2',\
con_set_cursor_pos, 'con_set_cursor_pos'
socketnum dd ?
icmp_packet: db 8 ; type
db 0 ; code
dw 0 ;
.id dw 0x0000 ; identifier
.seq dw 0x0001 ; sequence number
.data db 'abcdefghijklmnopqrstuvwxyz012345678'
.length = $ - icmp_packet
I_END:
buffer_ptr rb BUFFERSIZE
s rb 256
align 4
rb 4096 ; stack
mem:

View File

@ -135,4 +135,9 @@ dd 0x08001516
dd 0x08911516
dd 0x0
db 'dec21x4x',0
dd 0x000901011
dd 0x001901011
dd 0x0
dd 0x0 ; driverlist end

View File

@ -1,157 +0,0 @@
;-----------------------------------------------------------------------------
proc mem.Alloc size ;/////////////////////////////////////////////////////////
;-----------------------------------------------------------------------------
push ebx ecx
mov eax,[size]
lea ecx,[eax+4+4095]
and ecx,not 4095
mcall 68,12
add ecx,-4
mov [eax],ecx
add eax,4
pop ecx ebx
ret
endp
;-----------------------------------------------------------------------------
proc mem.ReAlloc mptr,size;///////////////////////////////////////////////////
;-----------------------------------------------------------------------------
push ebx ecx esi edi eax
mov eax,[mptr]
mov ebx,[size]
or eax,eax
jz @f
lea ecx,[ebx+4+4095]
and ecx,not 4095
add ecx,-4
cmp ecx,[eax-4]
je .exit
@@: mov eax,ebx
call mem.Alloc
xchg eax,[esp]
or eax,eax
jz .exit
mov esi,eax
xchg eax,[esp]
mov edi,eax
mov ecx,[esi-4]
cmp ecx,[edi-4]
jbe @f
mov ecx,[edi-4]
@@: add ecx,3
shr ecx,2
cld
rep movsd
xchg eax,[esp]
call mem.Free
.exit:
pop eax edi esi ecx ebx
ret
endp
;-----------------------------------------------------------------------------
proc mem.Free mptr ;//////////////////////////////////////////////////////////
;-----------------------------------------------------------------------------
mov eax,[mptr]
or eax,eax
jz @f
push ebx ecx
lea ecx,[eax-4]
mcall 68,13
pop ecx ebx
@@: ret
endp
proc dll.Load, import_table:dword
mov esi,[import_table]
.next_lib: mov edx,[esi]
or edx,edx
jz .exit
push esi
mov esi,[esi+4]
mov edi,s_libdir.fname
@@: lodsb
stosb
or al,al
jnz @b
mcall 68,19,s_libdir
or eax,eax
jz .fail
stdcall dll.Link,eax,edx
stdcall dll.Init,[eax+4]
pop esi
add esi,8
jmp .next_lib
.exit: xor eax,eax
ret
.fail: add esp,4
xor eax,eax
inc eax
ret
endp
proc dll.Link, exp:dword,imp:dword
push eax
mov esi,[imp]
test esi,esi
jz .done
.next: lodsd
test eax,eax
jz .done
stdcall dll.GetProcAddress,[exp],eax
or eax,eax
jz @f
mov [esi-4],eax
jmp .next
@@: mov dword[esp],0
.done: pop eax
ret
endp
proc dll.Init, dllentry:dword
pushad
mov eax,mem.Alloc
mov ebx,mem.Free
mov ecx,mem.ReAlloc
mov edx,dll.Load
stdcall [dllentry]
popad
ret
endp
proc dll.GetProcAddress, exp:dword,sz_name:dword
mov edx,[exp]
xor eax,eax
.next: or edx,edx
jz .end
cmp dword[edx],0
jz .end
stdcall strcmp,[edx],[sz_name]
test eax,eax
jz .ok
add edx,8
jmp .next
.ok: mov eax,[edx+4]
.end: ret
endp
proc strcmp, str1:dword,str2:dword
push esi edi
mov esi,[str1]
mov edi,[str2]
xor eax,eax
@@: lodsb
scasb
jne .fail
or al,al
jnz @b
jmp .ok
.fail: or eax,-1
.ok: pop edi esi
ret
endp
s_libdir:
db '/sys/lib/'
.fname rb 32

View File

@ -15,7 +15,7 @@ BUFFERSIZE equ 1500
include '../macros.inc'
purge mov,add,sub
include '../proc32.inc'
include 'dll.inc'
include '../dll.inc'
include '../network.inc'

View File

@ -308,12 +308,7 @@ proc service_proc stdcall, ioctl:dword
cmp [devices], MAX_DEVICES ; First check if the driver can handle one more card
jge .fail
push edx
stdcall KernelAlloc, device.size ; Allocate the buffer for eth_device structure
pop edx
test eax, eax
jz .fail
mov ebx, eax ; ebx is always used as a pointer to the structure (in driver, but also in kernel code)
allocate_and_clear ebx, device.size, .fail ; Allocate the buffer for device structure
; Fill in the direct call addresses into the struct
@ -619,20 +614,21 @@ reset:
mov eax, [device.rx_buffer]
call GetPgAddr
set_io 0
; set_io 0
set_io REG_RBSTART
out dx , eax
; enable interrupts
mov eax, INTERRUPT_MASK
set_io REG_IMR
out dx , ax
; Read MAC address
call read_mac
; enable interrupts
set_io 0
set_io REG_IMR
mov eax, INTERRUPT_MASK
out dx , ax
; Set the mtu, kernel will be able to send now
mov [device.mtu], 1514
@ -724,7 +720,7 @@ transmit:
.fail:
DEBUGF 1,"failed!\n"
or eax, -1
stdcall KernelFree, [esp+4]
ret 8
@ -890,6 +886,8 @@ int_handler:
test ax, ISR_TER
jz @f
DEBUGF 1,"Transmit error\n"
; push ax
; cmp [device.curr_tx_desc], 4
; jz .notxd
@ -1114,85 +1112,6 @@ read_mac:
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Read eeprom (type 93c46 and 93c56) ;;
;; ;;
;; In: word to be read in al (6bit in case of 93c46 and 8bit otherwise) ;;
;; pointer to device structure in ebx ;;
;; ;;
;; OUT: word read in ax ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 4
read_eeprom:
DEBUGF 2,"Reading eeprom, "
set_io 0
push ebx
movzx ebx, al
set_io REG_RXCONFIG
in al, dx
test al, (1 shl BIT_9356SEL)
jz .type_93c46
; and bl, 01111111b ; don't care first bit
or bx, EE_93C56_READ_CMD ; it contains start bit
mov cx, EE_93C56_CMD_LENGTH-1 ; cmd_loop counter
jmp .read_eeprom
.type_93c46:
and bl, 00111111b
or bx, EE_93C46_READ_CMD ; it contains start bit
mov cx, EE_93C46_CMD_LENGTH-1 ; cmd_loop counter
.read_eeprom:
set_io REG_9346CR
; mov al, (1 shl BIT_93C46_EEM1)
; out dx, al
mov al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EECS) ; wake up the eeprom
out dx, al
.cmd_loop:
mov al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EECS)
bt bx, cx
jnc .zero_bit
or al, (1 shl BIT_93C46_EEDI)
.zero_bit:
out dx, al
; push eax
; in eax, dx ; eeprom delay
; pop eax
or al, (1 shl BIT_93C46_EESK)
out dx, al
; in eax, dx ; eeprom delay
dec cx
jns .cmd_loop
; in eax, dx ; eeprom delay
mov al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EECS)
out dx, al
mov cl, 0xf
.read_loop:
shl ebx, 1
mov al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EECS) or (1 shl BIT_93C46_EESK)
out dx, al
; in eax, dx ; eeprom delay
in al, dx
and al, (1 shl BIT_93C46_EEDO)
jz .dont_set
inc ebx
.dont_set:
mov al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EECS)
out dx, al
; in eax, dx ; eeprom delay
dec cl
jns .read_loop
xor al, al
out dx, al
mov ax, bx
pop ebx
ret
; End of code
section '.data' data readable writable align 16 ; place all uninitialized data place here

View File

@ -994,16 +994,14 @@ transmit:
DEBUGF 1,"transmit ok\n"
xor eax, eax
call Kernelfree
add esp, 4
ret
stdcall KernelFree, [esp+4]
ret 8
.fail:
DEBUGF 1,"transmit failed\n"
or eax, -1
call Kernelfree
add esp, 4
ret
stdcall KernelFree, [esp+4]
ret 8
;;;;;;;;;;;;;;;;;;;;;;;

View File

@ -23,6 +23,10 @@ format MS COFF
__DEBUG__ equ 1
__DEBUG_LEVEL__ equ 1
TX_RING_SIZE equ 4
RX_RING_SIZE equ 4
PKT_BUF_SZ equ 1544
include 'proc32.inc'
include 'imports.inc'
@ -33,6 +37,19 @@ public START
public service_proc
public version
struc buf_head {
.base dd ?
.length dw ?
.status dw ?
.msg_length dw ?
.misc dw ?
.reserved dd ?
.size:
}
virtual at 0
buf_head buf_head
end virtual
virtual at ebx
@ -68,8 +85,10 @@ virtual at ebx
.filter dq ?
.rx_ring_phys dd ?
.tx_ring_phys dd ?
.rx_ring dd ?
.tx_ring dd ?
.rx_ring rb RX_RING_SIZE * buf_head.size
.tx_ring rb TX_RING_SIZE * buf_head.size
.cur_rx db ?
.cur_tx db ?
.dirty_rx dd ?
@ -88,20 +107,6 @@ virtual at ebx
end virtual
struc buf_head {
.base dd ?
.length dw ?
.status dw ?
.msg_length dw ?
.misc dw ?
.reserved dd ?
.size:
}
virtual at 0
buf_head buf_head
end virtual
struc rx_desc_2 { ; Swstyle 2
@ -147,9 +152,6 @@ virtual at 0
rx_desc rx_desc_2
end virtual
; PCI Bus defines
PORT_AUI equ 0x00
PORT_10BT equ 0x01
PORT_GPSI equ 0x02
@ -164,17 +166,12 @@ end virtual
LOG_TX_BUFFERS equ 2
LOG_RX_BUFFERS equ 2
TX_RING_SIZE equ 4
TX_RING_MOD_MASK equ (TX_RING_SIZE-1)
TX_RING_LEN_BITS equ (LOG_TX_BUFFERS shl 12)
RX_RING_SIZE equ 4
RX_RING_MOD_MASK equ (RX_RING_SIZE-1)
RX_RING_LEN_BITS equ (LOG_RX_BUFFERS shl 4)
PKT_BUF_SZ equ 1544
PKT_BUF_SZ_NEG equ 0xf9f8
WIO_RDP equ 0x10
WIO_RAP equ 0x12
WIO_RESET equ 0x14
@ -518,19 +515,8 @@ proc service_proc stdcall, ioctl:dword
DEBUGF 1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
[device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4
;;; allocate_and_clear [device.tx_buffer], (RX_RING_SIZE * PKT_BUF_SZ), .err
allocate_and_clear [device.tx_buffer], (RX_RING_SIZE * PKT_BUF_SZ), .err
allocate_and_clear [device.rx_buffer], (TX_RING_SIZE * PKT_BUF_SZ), .err
allocate_and_clear [device.rx_ring], (RX_RING_SIZE * buf_head.size), .err
mov eax, [device.rx_ring]
call GetPgAddr
mov [device.rx_ring_phys], eax
allocate_and_clear [device.tx_ring], (TX_RING_SIZE * buf_head.size), .err
mov eax, [device.tx_ring]
call GetPgAddr
mov [device.tx_ring_phys], eax
; Ok, the eth_device structure is ready, let's probe the device
; Because initialization fires IRQ, IRQ handler must be aware of this device
@ -569,7 +555,7 @@ proc service_proc stdcall, ioctl:dword
.err:
DEBUGF 1,"Error, removing all data !\n"
stdcall KernelFree, [device.rx_buffer]
;;; stdcall KernelFree, [device.tx_buffer]
stdcall KernelFree, [device.tx_buffer]
stdcall KernelFree, ebx
.fail:
@ -610,26 +596,33 @@ ret
align 4
probe:
; make the device a bus master
make_bus_master [device.pci_bus], [device.pci_dev]
; first, fill in some of the structure variables
; create the RX-ring
mov edi, [device.rx_ring]
lea edi, [device.rx_ring]
mov ecx, RX_RING_SIZE
mov eax, [device.rx_buffer]
call GetPgAddr
.rx_init:
mov [edi + buf_head.base], eax
mov [edi + buf_head.length], PKT_BUF_SZ_NEG
mov [edi + buf_head.length], - PKT_BUF_SZ
mov [edi + buf_head.status], 0x8000
and dword [edi + buf_head.msg_length], 0
and dword [edi + buf_head.reserved], 0
add eax, PKT_BUF_SZ
; inc eax
add edi, buf_head.size
loop .rx_init
mov edi, [device.tx_ring]
lea eax, [device.rx_ring]
GetRealAddr
mov [device.rx_ring_phys], eax
; create the Tx-ring
lea edi, [device.tx_ring]
mov ecx, TX_RING_SIZE
mov eax, [device.tx_buffer]
call GetPgAddr
@ -642,6 +635,10 @@ probe:
add edi, buf_head.size
loop .tx_init
lea eax, [device.tx_ring]
GetRealAddr
mov [device.tx_ring_phys], eax
mov [device.tlen_rlen], (TX_RING_LEN_BITS or RX_RING_LEN_BITS)
; First, we must try to use Word operations
@ -656,12 +653,12 @@ probe:
; Try Word I/O
mov ax, 88
add edx, WIO_RAP
set_io WIO_RAP
out dx, ax
nop
nop
in ax, dx
sub edx, WIO_RAP
set_io 0
cmp ax, 88
jne .try_dwio
@ -671,6 +668,7 @@ probe:
jmp .L1
; If WIO fails, try to use DWIO
.try_dwio:
call dwio_reset
@ -688,8 +686,7 @@ probe:
nop
in eax, dx
set_io 0
and eax, 0xffff
cmp eax, 88
cmp ax, 88
jne .no_dev
DEBUGF 1,"Using DWIO\n"
@ -698,12 +695,13 @@ probe:
jmp .L1
; If both methods fail, something is wrong!
.no_dev:
DEBUGF 1,"PCnet device not found!\n"
mov eax, 1
mov eax, -1
ret
.L1:
.L1:
mov ecx, CSR_CHIPID0
call [device.access_read_csr]
mov esi, eax
@ -722,7 +720,8 @@ probe:
and eax, 0xffff
mov [device.chip_version], eax
DEBUGF 1,"chip version ok\n"
DEBUGF 1,"chip version: %x\n", eax
mov [device.fdx], 0
mov [device.mii], 0
mov [device.fset], 0
@ -794,13 +793,11 @@ probe:
jne .L11
mov ecx, BCR_BUSCTL
call [device.access_read_bcr]
or eax, 0x800
or ax, 0x800
call [device.access_write_bcr]
mov ecx, CSR_DMACTL
call [device.access_read_csr]
; and eax, 0xc00
; or eax, 0xc00
mov eax, 0xc00
call [device.access_write_csr]
@ -808,8 +805,7 @@ probe:
mov [device.ltint],1
.L11:
DEBUGF 1,"PCI done\n"
mov eax, PORT_ASEL
mov eax, PORT_ASEL ; Auto-select
mov [device.options], eax
mov [device.mode_], word 0x0003
mov [device.tlen_rlen], word (TX_RING_LEN_BITS or RX_RING_LEN_BITS)
@ -822,12 +818,11 @@ probe:
call [device.access_write_csr]
align 4
reset:
DEBUGF 1,"Resetting PCnet device: %x\n", ebx
; attach int handler
movzx eax, [device.irq_line]
@ -848,7 +843,7 @@ reset:
DEBUGF 1,"Switching to 32-bit mode\n"
mov ecx, DWIO_RDP
mov eax, 0
xor eax, eax
call wio_write_csr
call switch_to_dwio
@ -863,23 +858,26 @@ reset:
nop
in eax, dx
set_io 0
and eax, 0xffff
cmp eax, 88
cmp ax, 88
je .yes_dwio
call switch_to_wio ; it seem to have failed, reset device again and use wio
call switch_to_wio ; it seems to have failed, reset device again and use wio
set_io 0
call [device.access_reset]
.yes_dwio:
set_io 0
mov ecx, BCR_SSTYLE ; Select Software style 2 ;;;
mov eax, 2
call [device.access_write_bcr]
; set/reset autoselect bit
mov ecx, BCR_MISCCFG
call [device.access_read_bcr]
and eax,not 2
test [device.options], PORT_ASEL
jz .L1
or eax, 2
jnz .L1
and eax, not 2
.L1:
call [device.access_write_bcr]
@ -968,11 +966,7 @@ reset:
movsw
lea eax, [device.private]
mov ecx, eax
and ecx, 0xFFF ; KolibriOS PAGE SIZE
call GetPgAddr
add eax, ecx
GetRealAddr
push eax
and eax, 0xffff
mov ecx, 1
@ -986,7 +980,7 @@ reset:
mov eax, 0x0915
call [device.access_write_csr]
mov ecx,0
xor ecx, ecx
mov eax, 1
call [device.access_write_csr]
@ -1002,6 +996,10 @@ reset:
xor ecx, ecx
call [device.access_read_csr]
pop ecx
push esi
mov esi, 100
call Sleep
pop esi
test ax, 0x100
jnz .L12
loop .L11
@ -1063,7 +1061,9 @@ transmit:
imul edi, eax, PKT_BUF_SZ
shl eax, 4
add edi, [device.tx_buffer]
add eax, [device.tx_ring]
lea eax, [eax + device.tx_ring]
test byte [eax + buf_head.status + 1], 80h
jnz .nospace
@ -1104,17 +1104,15 @@ transmit:
adc dword [device.bytes_tx + 4], 0
DEBUGF 2," - Done!\n"
call Kernelfree
add esp, 4
ret
stdcall KernelFree, [esp+4]
ret 8
.nospace:
DEBUGF 1, 'ERROR: no free transmit descriptors\n'
; todo: maybe somehow notify the kernel about the error?
call Kernelfree
add esp, 4
ret
stdcall KernelFree, [esp+4]
ret 8
@ -1127,7 +1125,7 @@ transmit:
align 4
int_handler:
DEBUGF 1,"IRQ %x ", eax:2 ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO
DEBUGF 1,"IRQ=%x ", eax:2 ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO
; find pointer of device wich made IRQ occur
@ -1137,7 +1135,6 @@ int_handler:
jz .abort
.nextdevice:
mov ebx, [esi]
DEBUGF 1,"device=%x? ", ebx
set_io 0
push ecx
@ -1154,7 +1151,7 @@ int_handler:
ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver
.got_it:
DEBUGF 1,"yes, reason=%x ", ax
DEBUGF 1,"csr=%x\n", ax
;-------------------------------------------------------
; Possible reasons:
; initialization done - ignore
@ -1170,6 +1167,10 @@ int_handler:
test ax, CSR_RINT
jz @f
push ax
DEBUGF 1,"packet received!\n"
.receiver_test_loop:
movzx eax, [device.cur_rx]
; and eax, RX_RING_MOD_MASK
@ -1179,7 +1180,7 @@ int_handler:
add esi, [device.rx_buffer] ; esi now points to rx buffer
shl edi, 4 ; desc * 16 (16 is size of one ring entry)
add edi, [device.rx_ring] ; edi now points to current rx ring entry
lea edi, [edi + device.rx_ring] ; edi now points to current rx ring entry
mov cx , [edi + buf_head.status]
@ -1234,9 +1235,25 @@ int_handler:
jmp EthReceiver ; Send the copied packet to kernel
.abort:
DEBUGF 1,"done \n"
pop ax
@@:
test ax, IMR_TINT
jz @f
DEBUGF 1,"Transmit OK!\n"
@@:
test ax, IMR_MISS
jz @f
DEBUGF 1,"We missed a frame! (RX ring full?)\n"
@@:
DEBUGF 1,"done\n"
ret
@ -1253,10 +1270,9 @@ write_mac: ; in: mac pushed onto stack (as 3 words)
DEBUGF 1,"Writing MAC: %x-%x-%x-%x-%x-%x",[esp+0]:2,[esp+1]:2,[esp+2]:2,[esp+3]:2,[esp+4]:2,[esp+5]:2
mov edx, [device.io_addr]
add edx, 2
set_io 0
; set_io 2
xor eax, eax
mov ecx, CSR_PAR0
@@:
pop ax
@ -1279,8 +1295,8 @@ write_mac: ; in: mac pushed onto stack (as 3 words)
read_mac:
DEBUGF 1,"Reading MAC"
mov edx, [device.io_addr]
add edx, 6
set_io 0
set_io 6
@@:
dec dx
dec dx
@ -1522,7 +1538,7 @@ align 4 ; Place all initialised data here
devices dd 0
version dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
my_service db 'PCnet32',0 ; max 16 chars include zero
my_service db 'PCnet',0 ; max 16 chars include zero
device_l2 db "PCnet/PCI 79C970",0
device_l4 db "PCnet/PCI II 79C970A",0

View File

@ -1275,7 +1275,7 @@ transmit:
add dword [device.bytes_tx], ecx
adc dword [device.bytes_tx+4], 0
ret
ret 8
; End of code

View File

@ -653,6 +653,94 @@ IPv4_output:
ret
;------------------------------------------------------------------
;
; IPv4_output_raw
;
; IN: eax = socket ptr
; ecx = data length
; esi = data ptr
;
; OUT: /
;
;------------------------------------------------------------------
align 4
IPv4_output_raw:
DEBUGF 1,"IPv4_output_raw: size=%u ptr=%x socket=%x\n", ecx, esi, eax
cmp ecx, 1480 ;;;;;
jg .too_large
sub esp, 8
push esi eax
call ARP_IP_to_MAC
test eax, 0xffff0000 ; error bits
jnz .arp_error
.continue:
push ebx ; push the mac
push ax
call IPv4_dest_to_dev
inc [IP_PACKETS_TX+edi]
mov ebx, [NET_DRV_LIST+edi]
lea eax, [ebx + ETH_DEVICE.mac]
mov edx, esp
mov ecx, [esp + 6+4]
add ecx, IPv4_Packet.DataOrOptional
mov di, ETHER_IPv4
call ETH_output
jz .error
add esp, 6 ; pop the mac
mov dword[esp+4+4], edx
mov dword[esp+4+4+4], eax
pop eax esi
;; todo: check socket options if we should add header, or just compute checksum
push edi ecx
rep movsb
pop ecx edi
; [edi + IPv4_Packet.VersionAndIHL] ; IPv4, normal length (no Optional header)
; [edi + IPv4_Packet.TypeOfService] ; nothing special, just plain ip packet
; [edi + IPv4_Packet.TotalLength]
; [edi + IPv4_Packet.TotalLength] ; internet byte order
; [edi + IPv4_Packet.FlagsAndFragmentOffset]
mov [edi + IPv4_Packet.HeaderChecksum], 0
; [edi + IPv4_Packet.TimeToLive] ; ttl shl 8 + protocol
; [edi + IPv4_Packet.Protocol]
; [edi + IPv4_Packet.Identification] ; fragment id
; [edi + IPv4_Packet.SourceAddress]
; [edi + IPv4_Packet.DestinationAddress]
IPv4_checksum edi ;;;; todo: checksum for IP packet with options!
add edi, IPv4_Packet.DataOrOptional
DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx
call [ebx + NET_DEVICE.transmit]
ret
.error:
add esp, 6
.arp_error:
add esp, 8+4+4
.too_large:
DEBUGF 1,"IPv4_output_raw: Failed\n"
sub edi, edi
ret
;--------------------------------------------------------
;
;

View File

@ -132,24 +132,24 @@ macro ICMP_init {
;
; IN: Pointer to buffer in [esp]
; size of buffer in [esp+4]
; pointer to device struct in ebx
; ICMP Packet size in ecx
; pointer to ICMP Packet data in edx
; ebx = pointer to device struct
; ecx = ICMP Packet size
; edx = ptr to ICMP Packet data
; esi = ipv4 source address
; edi = ipv4 dest address
; OUT: /
;
;-----------------------------------------------------------------
align 4
ICMP_input:
;;; TODO: works only on pure ethernet right now !
;;; TODO: check checksum!
DEBUGF 1,"ICMP_Handler - start\n"
DEBUGF 1,"ICMP_input - start\n"
cmp byte [edx + ICMP_Packet.Type], ICMP_ECHO ; Is this an echo request?
jne .check_sockets
;;; TODO: check checksum!
DEBUGF 1,"ICMP_Handler - echo request\n"
DEBUGF 1,"ICMP_input - echo request\n"
mov byte [edx + ICMP_Packet.Type], ICMP_ECHOREPLY ; Change Packet type to reply
mov word [edx + ICMP_Packet.Checksum], 0 ; Set checksum to 0, needed to calculate new checksum
@ -211,43 +211,47 @@ ICMP_input:
.check_sockets:
; TODO: validate the header & checksum.
; Look for an open ICMP socket
; esi = sender ip
mov esi, net_sockets
mov ebx, net_sockets
.try_more:
mov ax , [edx + ICMP_Packet.Identifier]
; mov ax , [edx + ICMP_Packet.Identifier]
.next_socket:
mov esi, [esi + SOCKET.NextPtr]
or esi, esi
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .dump
cmp [esi + SOCKET.Type], IP_PROTO_ICMP
jne .next_socket
cmp [esi + ICMP_SOCKET.Identifier], ax
cmp [ebx + SOCKET.Domain], AF_INET4
jne .next_socket
call IPv4_dest_to_dev
cmp edi,-1
je .dump
inc [ICMP_PACKETS_RX+edi]
cmp [ebx + SOCKET.Type], SOCK_RAW
jne .next_socket
DEBUGF 1,"Found valid ICMP packet for socket %x\n", esi
cmp [ebx + SOCKET.Protocol], IP_PROTO_ICMP
jne .next_socket
lea ebx, [esi + SOCKET.lock]
cmp [ebx + IP_SOCKET.RemoteIP], esi
jne .next_socket
; cmp [esi + ICMP_SOCKET.Identifier], ax
; jne .next_socket
; call IPv4_dest_to_dev
; cmp edi,-1
; je .dump
; inc [ICMP_PACKETS_RX+edi]
DEBUGF 1,"Found valid ICMP packet for socket %x\n", ebx
mov eax, ebx
add ebx, SOCKET.lock
call wait_mutex
; Now, assign data to socket. We have socket address in esi.
; We have ICMP Packet in edx
; number of bytes in ecx
mov eax, esi
pop esi
add esp, 4
sub edx, esi
mov edi, edx
mov esi, edx
jmp SOCKET_input
.dump:
DEBUGF 1,"ICMP_Handler - dumping\n"
@ -278,6 +282,8 @@ ICMP_output:
push esi edi edx
mov ebx, [eax + IP_SOCKET.LocalIP]
mov eax, [eax + IP_SOCKET.RemoteIP]
add ecx, ICMP_Packet.Data
mov di , IP_PROTO_ICMP SHL 8 + 128 ; TTL
shr edx, 16
@ -325,6 +331,57 @@ ICMP_output:
;-----------------------------------------------------------------
;
; ICMP_output
;
; IN: eax = socket ptr
; ecx = data length
; esi = data offset
;
;-----------------------------------------------------------------
align 4
ICMP_output_raw:
DEBUGF 1,"Creating ICMP Packet for socket %x, data ptr=%x\n", eax, edx
push edx
mov di, IP_PROTO_ICMP SHL 8 + 128 ; TTL
shr edx, 16
mov ebx, [eax + IP_SOCKET.LocalIP]
mov eax, [eax + IP_SOCKET.RemoteIP]
call IPv4_output
jz .exit
pop esi
push edx
push eax
push edi ecx
DEBUGF 1,"copying %u bytes from %x to %x\n", ecx, esi, edi
rep movsb
pop ecx edi
mov [edi + ICMP_Packet.Checksum], 0
mov esi, edi
xor edx, edx
call checksum_1
call checksum_2
mov [edi + ICMP_Packet.Checksum], dx
DEBUGF 1,"Sending ICMP Packet\n"
call [ebx + NET_DEVICE.transmit]
ret
.exit:
DEBUGF 1,"Creating ICMP Packet failed\n"
add esp, 4
ret
;-----------------------------------------------------------------
;
; ICMP_API

View File

@ -317,6 +317,9 @@ SOCKET_open:
cmp edx, IP_PROTO_TCP
je .tcp
cmp edx, SOCK_RAW
je .raw
.no_inet4:
ret
@ -340,7 +343,36 @@ SOCKET_open:
pop eax
mov [eax + SOCKET.snd_proc], SOCKET_send_udp
mov [eax + SOCKET.rcv_proc], SOCKET_receive_udp
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
ret
.raw:
; test esi, esi
; jz .ip
cmp esi, IP_PROTO_ICMP
je .icmp
ret
; .ip:
; push eax
; init_queue (eax + SOCKET_QUEUE_LOCATION)
; pop eax
;
; mov [eax + SOCKET.snd_proc], SOCKET_send_ip
; mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
;
; ret
.icmp:
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION)
pop eax
mov [eax + SOCKET.snd_proc], SOCKET_send_icmp
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
ret
@ -426,7 +458,7 @@ SOCKET_bind:
align 4
SOCKET_connect:
DEBUGF 1,"socket_connect: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi
DEBUGF 1,"SOCKET_connect: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi
call SOCKET_num_to_ptr
jz s_error
@ -447,6 +479,9 @@ SOCKET_connect:
cmp [eax + SOCKET.Type], IP_PROTO_TCP
je .tcp
cmp [eax + SOCKET.Type], SOCK_RAW
je .raw
jmp s_error
.udp:
@ -497,6 +532,13 @@ SOCKET_connect:
mov dword [esp+32], 0 ; success!
ret
.raw:
push dword [edx + 4]
pop dword [eax + IP_SOCKET.RemoteIP]
mov dword [esp+32], 0 ; success!
ret
;-----------------------------------------------------------------
;
@ -510,7 +552,7 @@ SOCKET_connect:
align 4
SOCKET_listen:
DEBUGF 1,"Socket_listen: socknum: %u backlog: %u\n", ecx, edx
DEBUGF 1,"SOCKET_listen: socknum: %u backlog: %u\n", ecx, edx
call SOCKET_num_to_ptr
jz s_error
@ -550,7 +592,7 @@ SOCKET_listen:
align 4
SOCKET_accept:
DEBUGF 1,"Socket_accept: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi
DEBUGF 1,"SOCKET_accept: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi
call SOCKET_num_to_ptr
jz s_error
@ -601,7 +643,7 @@ SOCKET_accept:
align 4
SOCKET_close:
DEBUGF 1,"socket_close: socknum: %u\n", ecx
DEBUGF 1,"SOCKET_close: socknum: %u\n", ecx
call SOCKET_num_to_ptr
jz s_error
@ -658,11 +700,10 @@ SOCKET_receive:
jmp [eax + SOCKET.rcv_proc]
align 4
SOCKET_receive_udp:
SOCKET_receive_dgram:
DEBUGF 1,"type: UDP\n"
DEBUGF 1,"SOCKET_receive: DGRAM\n"
mov ebx, esi
mov edi, edx ; addr to buffer
@ -705,7 +746,7 @@ SOCKET_receive_udp:
align 4
SOCKET_receive_tcp:
DEBUGF 1,"type: TCP\n"
DEBUGF 1,"SOCKET_receive: TCP\n"
mov ecx, esi
mov edi, edx
@ -733,7 +774,7 @@ SOCKET_receive_tcp:
align 4
SOCKET_send:
DEBUGF 1,"SOCKET_send: socknum: %u sockaddr: %x, length: %u, flags: %x, ", ecx, edx, esi, edi
DEBUGF 1,"SOCKET_send: socknum: %u data ptr: %x, length: %u, flags: %x, ", ecx, edx, esi, edi
call SOCKET_num_to_ptr
jz s_error
@ -741,11 +782,10 @@ SOCKET_send:
jmp [eax + SOCKET.snd_proc]
align 4
SOCKET_send_udp:
DEBUGF 1,"type: UDP\n"
DEBUGF 1,"SOCKET_send: UDP\n"
mov ecx, esi
mov esi, edx
@ -759,7 +799,7 @@ SOCKET_send_udp:
align 4
SOCKET_send_tcp:
DEBUGF 1,"type: TCP\n"
DEBUGF 1,"SOCKET_send: TCP\n"
push eax
mov ecx, esi
@ -774,6 +814,31 @@ SOCKET_send_tcp:
ret
;align 4
;SOCKET_send_ip:
;
; DEBUGF 1,"type: IP\n"
;
; mov ecx, esi
; mov esi, edx
;
; call IPv4_output_raw
;
; mov dword [esp+32], eax
; ret
align 4
SOCKET_send_icmp:
DEBUGF 1,"SOCKET_send: ICMP\n"
mov ecx, esi
call ICMP_output_raw
mov dword [esp+32], 0
ret
;-----------------------------------------------------------------
@ -991,13 +1056,13 @@ SOCKET_input:
add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, socket_queue_entry.size, SOCKET_input.full
DEBUGF 1,"Queued packet successfully\n"
DEBUGF 1,"SOCKET_input: queued packet successfully\n"
add esp, socket_queue_entry.size
mov [eax + SOCKET.lock], 0
jmp SOCKET_notify_owner
.full:
DEBUGF 2,"Socket %x is full!\n", eax
DEBUGF 2,"SOCKET_input: socket %x is full!\n", eax
mov [eax + SOCKET.lock], 0
call kernel_free
add esp, 8
@ -1049,7 +1114,7 @@ SOCKET_ring_write:
.copy:
mov edi, [eax + RING_BUFFER.write_ptr]
DEBUGF 2,"Copying %u bytes from %x to %x\n", ecx, esi, edi
DEBUGF 2,"SOCKET_ring_write: %u bytes from %x to %x\n", ecx, esi, edi
push ecx
shr ecx, 1
@ -1087,7 +1152,7 @@ SOCKET_ring_write:
jmp .copy
.full:
DEBUGF 2,"Ring buffer is full!\n"
DEBUGF 2,"SOCKET_ring_write: ring buffer is full!\n"
xor ecx, ecx
ret
@ -1116,7 +1181,7 @@ SOCKET_ring_read:
.copy:
mov esi, [eax + RING_BUFFER.read_ptr]
DEBUGF 2,"Copying %u bytes from %x to %x\n", ecx, esi, edi
DEBUGF 2,"SOCKET_ring_read: %u bytes from %x to %x\n", ecx, esi, edi
push ecx
shr ecx, 1
jnc .nb
@ -1334,7 +1399,7 @@ SOCKET_free:
lea ebx, [eax + SOCKET.lock]
call wait_mutex
DEBUGF 1, "freeing socket..\n"
DEBUGF 1, "SOCKET_free: freeing socket..\n"
cmp [eax + SOCKET.Domain], AF_INET4
jnz .no_tcp
@ -1352,7 +1417,7 @@ SOCKET_free:
mov ebx, [eax + SOCKET.NextPtr]
mov eax, [eax + SOCKET.PrevPtr]
DEBUGF 1, "linking socket %x to socket %x\n", eax, ebx
DEBUGF 1, "SOCKET_free: linking socket %x to socket %x\n", eax, ebx
test eax, eax
jz @f
@ -1367,7 +1432,7 @@ SOCKET_free:
call kernel_free
pop ebx
DEBUGF 1, "socket is gone!\n"
DEBUGF 1, "SOCKET_free: success!\n"
.error:
ret