forked from KolibriOS/kolibrios
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:
parent
500fea459a
commit
8a7ebf6b32
@ -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:
|
||||
|
319
kernel/branches/net/applications/icmp_test/icmp.asm
Normal file
319
kernel/branches/net/applications/icmp_test/icmp.asm
Normal 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:
|
@ -135,4 +135,9 @@ dd 0x08001516
|
||||
dd 0x08911516
|
||||
dd 0x0
|
||||
|
||||
db 'dec21x4x',0
|
||||
dd 0x000901011
|
||||
dd 0x001901011
|
||||
dd 0x0
|
||||
|
||||
dd 0x0 ; driverlist end
|
@ -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
|
@ -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'
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -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
|
||||
|
||||
@ -57,8 +74,8 @@ virtual at ebx
|
||||
.access_write_rap dd ?
|
||||
.access_reset dd ?
|
||||
|
||||
; The following fields up to .tx_ring_phys inclusive form
|
||||
; initialization block for hardware; do not modify (must be 4-aligned)
|
||||
; The following fields up to .tx_ring_phys inclusive form
|
||||
; initialization block for hardware; do not modify (must be 4-aligned)
|
||||
|
||||
.private:
|
||||
.mode_ dw ?
|
||||
@ -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
|
||||
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,9 +635,13 @@ 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
|
||||
; First, we must try to use Word operations
|
||||
call switch_to_wio
|
||||
set_io 0
|
||||
call wio_reset
|
||||
@ -655,22 +652,23 @@ probe:
|
||||
jne .try_dwio
|
||||
|
||||
; Try Word I/O
|
||||
mov ax , 88
|
||||
add edx, WIO_RAP
|
||||
out dx , ax
|
||||
mov ax, 88
|
||||
set_io WIO_RAP
|
||||
out dx, ax
|
||||
nop
|
||||
nop
|
||||
in ax , dx
|
||||
sub edx, WIO_RAP
|
||||
cmp ax , 88
|
||||
in ax, dx
|
||||
set_io 0
|
||||
cmp ax, 88
|
||||
jne .try_dwio
|
||||
|
||||
DEBUGF 1,"Using WIO\n"
|
||||
DEBUGF 1,"Using WIO\n"
|
||||
|
||||
call switch_to_wio
|
||||
|
||||
jmp .L1
|
||||
|
||||
; If WIO fails, try to use DWIO
|
||||
.try_dwio:
|
||||
call dwio_reset
|
||||
|
||||
@ -683,27 +681,27 @@ probe:
|
||||
; Try Dword I/O
|
||||
set_io DWIO_RAP
|
||||
mov eax, 88
|
||||
out dx , eax
|
||||
out dx, eax
|
||||
nop
|
||||
nop
|
||||
in eax, dx
|
||||
set_io 0
|
||||
and eax, 0xffff
|
||||
cmp eax, 88
|
||||
cmp ax, 88
|
||||
jne .no_dev
|
||||
|
||||
DEBUGF 1,"Using DWIO\n"
|
||||
DEBUGF 1,"Using DWIO\n"
|
||||
|
||||
call switch_to_dwio
|
||||
|
||||
jmp .L1
|
||||
|
||||
; If both methods fail, something is wrong!
|
||||
.no_dev:
|
||||
DEBUGF 1,"PCnet device not found!\n"
|
||||
mov eax, 1
|
||||
DEBUGF 1,"PCnet device not found!\n"
|
||||
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
|
||||
@ -749,7 +748,7 @@ probe:
|
||||
cmp eax, 0x2627
|
||||
je .L9
|
||||
|
||||
DEBUGF 1,"Invalid chip rev\n"
|
||||
DEBUGF 1,"Invalid chip rev\n"
|
||||
jmp .no_dev
|
||||
.L2:
|
||||
mov [device.name], device_l2
|
||||
@ -788,19 +787,17 @@ probe:
|
||||
; mov [device.fdx], 1
|
||||
mov [device.mii], 1
|
||||
.L10:
|
||||
DEBUGF 1,"device name: %s\n",[device.name]
|
||||
DEBUGF 1,"device name: %s\n",[device.name]
|
||||
|
||||
cmp [device.fset], 1
|
||||
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)
|
||||
@ -818,16 +814,15 @@ probe:
|
||||
mov dword [device.filter+4], 0
|
||||
|
||||
mov eax, IMR
|
||||
mov ecx, CSR_IMR ; Write interrupt mask
|
||||
mov ecx, CSR_IMR ; Write interrupt mask
|
||||
call [device.access_write_csr]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
align 4
|
||||
reset:
|
||||
|
||||
DEBUGF 1,"Resetting PCnet device: %x\n", ebx
|
||||
|
||||
; attach int handler
|
||||
|
||||
movzx eax, [device.irq_line]
|
||||
@ -845,10 +840,10 @@ reset:
|
||||
|
||||
; Switch to dword operations
|
||||
|
||||
DEBUGF 1,"Switching to 32-bit mode\n"
|
||||
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
|
||||
@ -858,28 +853,31 @@ reset:
|
||||
set_io 0
|
||||
set_io DWIO_RAP
|
||||
mov eax, 88
|
||||
out dx , eax
|
||||
out dx, eax
|
||||
nop
|
||||
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]
|
||||
|
||||
@ -940,7 +938,7 @@ reset:
|
||||
test [device.options], PORT_ASEL
|
||||
jz .L9
|
||||
mov ecx, BCR_MIICTL
|
||||
DEBUGF 1,"ASEL, enable auto-negotiation\n"
|
||||
DEBUGF 1,"ASEL, enable auto-negotiation\n"
|
||||
call [device.access_read_bcr]
|
||||
and eax, not 0x98
|
||||
or eax, 0x20
|
||||
@ -968,41 +966,41 @@ 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
|
||||
call [device.access_write_csr]
|
||||
pop eax
|
||||
shr eax,16
|
||||
mov ecx,2
|
||||
shr eax, 16
|
||||
mov ecx, 2
|
||||
call [device.access_write_csr]
|
||||
|
||||
mov ecx,4
|
||||
mov eax,0x0915
|
||||
mov ecx, 4
|
||||
mov eax, 0x0915
|
||||
call [device.access_write_csr]
|
||||
|
||||
mov ecx,0
|
||||
mov eax,1
|
||||
xor ecx, ecx
|
||||
mov eax, 1
|
||||
call [device.access_write_csr]
|
||||
|
||||
mov [device.tx_full],0
|
||||
mov [device.cur_rx],0
|
||||
mov [device.cur_tx],0
|
||||
mov [device.dirty_rx],0
|
||||
mov [device.dirty_tx],0
|
||||
mov [device.tx_full], 0
|
||||
mov [device.cur_rx], 0
|
||||
mov [device.cur_tx], 0
|
||||
mov [device.dirty_rx], 0
|
||||
mov [device.dirty_tx], 0
|
||||
|
||||
mov ecx,100
|
||||
mov ecx, 100
|
||||
.L11:
|
||||
push ecx
|
||||
xor ecx, ecx
|
||||
call [device.access_read_csr]
|
||||
pop ecx
|
||||
test ax,0x100
|
||||
push esi
|
||||
mov esi, 100
|
||||
call Sleep
|
||||
pop esi
|
||||
test ax, 0x100
|
||||
jnz .L12
|
||||
loop .L11
|
||||
.L12:
|
||||
@ -1046,7 +1044,7 @@ reset:
|
||||
|
||||
align 4
|
||||
transmit:
|
||||
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8]
|
||||
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [esp+4], [esp+8]
|
||||
mov eax, [esp+4]
|
||||
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,\
|
||||
@ -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,7 +1167,11 @@ int_handler:
|
||||
test ax, CSR_RINT
|
||||
jz @f
|
||||
|
||||
.receiver_test_loop:
|
||||
push ax
|
||||
|
||||
DEBUGF 1,"packet received!\n"
|
||||
|
||||
.receiver_test_loop:
|
||||
movzx eax, [device.cur_rx]
|
||||
; and eax, RX_RING_MOD_MASK
|
||||
mov edi, eax
|
||||
@ -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
|
||||
@ -1518,11 +1534,11 @@ dwio_reset:
|
||||
|
||||
|
||||
; End of code
|
||||
align 4 ; Place all initialised data here
|
||||
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
|
||||
|
@ -1275,7 +1275,7 @@ transmit:
|
||||
add dword [device.bytes_tx], ecx
|
||||
adc dword [device.bytes_tx+4], 0
|
||||
|
||||
ret
|
||||
ret 8
|
||||
|
||||
|
||||
; End of code
|
||||
|
@ -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
|
||||
|
||||
|
||||
;--------------------------------------------------------
|
||||
;
|
||||
;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user