acpi:update

git-svn-id: svn://kolibrios.org@3589 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2013-06-02 10:40:22 +00:00
parent 996be4829b
commit 8dd796543b
39 changed files with 2891 additions and 13605 deletions

View File

@ -222,7 +222,7 @@ struct ehci_controller
; ------------------------------ hardware fields ------------------------------ ; ------------------------------ hardware fields ------------------------------
FrameList rd 1024 FrameList rd 1024
; Entry n corresponds to the head of the frame list to be executed in ; Entry n corresponds to the head of the frame list to be executed in
; the frames n,n+1024,n+2048,n+3096,... ; the frames n,n+1024,n+2048,n+3072,...
; The first bit of each entry is Terminate bit, 1 = the frame is empty. ; The first bit of each entry is Terminate bit, 1 = the frame is empty.
; Bits 1-2 are Type field, one of EHCI_TYPE_* constants. ; Bits 1-2 are Type field, one of EHCI_TYPE_* constants.
; Bits 3-4 must be zero. ; Bits 3-4 must be zero.

View File

@ -126,7 +126,7 @@ struct uhci_controller
; ------------------------------ hardware fields ------------------------------ ; ------------------------------ hardware fields ------------------------------
FrameList rd 1024 FrameList rd 1024
; Entry n corresponds to the head of the frame list to be executed in ; Entry n corresponds to the head of the frame list to be executed in
; the frames n,n+1024,n+2048,n+3096,... ; the frames n,n+1024,n+2048,n+3072,...
; The first bit of each entry is Terminate bit, 1 = the frame is empty. ; The first bit of each entry is Terminate bit, 1 = the frame is empty.
; The second bit of each entry is QH/TD select bit, 1 = the entry points to ; The second bit of each entry is QH/TD select bit, 1 = the entry points to
; QH, 0 = to TD. ; QH, 0 = to TD.

View File

@ -375,9 +375,6 @@ SCR_MODE rw 2
PUTPIXEL rd 1 PUTPIXEL rd 1
GETPIXEL rd 1 GETPIXEL rd 1
BgrDrawMode rd 1
BgrDataWidth rd 1
BgrDataHeight rd 1
REDRAW_BACKGROUND rb 4 REDRAW_BACKGROUND rb 4
MOUSE_PICTURE rd 1 MOUSE_PICTURE rd 1
@ -480,6 +477,12 @@ img_background rd 1
mem_BACKGROUND rd 1 mem_BACKGROUND rd 1
static_background_data rd 1 static_background_data rd 1
BgrDrawMode rd 1
BgrDataWidth rd 1
BgrDataHeight rd 1
skin_data rd 1
cache_ide0: cache_ide0:
cache_ide0_pointer rd 1 cache_ide0_pointer rd 1
cache_ide0_size rd 1 ; not use cache_ide0_size rd 1 ; not use
@ -553,7 +556,6 @@ RESERVED_PORTS: rb 64*1024
FLOPPY_BUFF: rb 16*1024 FLOPPY_BUFF: rb 16*1024
BUTTON_INFO: rb 16*1024 BUTTON_INFO: rb 16*1024
BgrAuxTable: rb 32*1024 BgrAuxTable: rb 32*1024
skin_data: rb 32*1024
;IDE_DMA: rb 32*1024 ;IDE_DMA: rb 32*1024

View File

@ -2393,9 +2393,18 @@ Returned value:
* otherwise eax = TID - thread identifier * otherwise eax = TID - thread identifier
</UL> </UL>
======================================================================
=========================== Function 52 ==============================
======================================================================
WARNING: This function is obsolete and is only present in the
documentation as a guide to understand/port the older network
applications. For new programs, use function 74
====================================================================== ======================================================================
=== Function 52, subfunction 0 - get network driver configuration. === === Function 52, subfunction 0 - get network driver configuration. ===
====================================================================== ======================================================================
Parameters: Parameters:
* eax = 52 - function number * eax = 52 - function number
* ebx = 0 - subfunction number * ebx = 0 - subfunction number
@ -2557,6 +2566,14 @@ Returned value:
high half of eax is destroyed high half of eax is destroyed
* for other ecx: eax = -1 indicates an error * for other ecx: eax = -1 indicates an error
======================================================================
=========================== Function 53 ==============================
======================================================================
WARNING: This function is obsolete and is only present in the
documentation as a guide to understand/port the older network
applications. For new programs, use function 75.
====================================================================== ======================================================================
============ Function 53, subfunction 0 - open UDP-socket. =========== ============ Function 53, subfunction 0 - open UDP-socket. ===========
====================================================================== ======================================================================
@ -4580,6 +4597,201 @@ Parameters:
Returned value: Returned value:
* function does not return value * function does not return value
======================================================================
= Function 74, Subfunction -1, Get number of active network devices. =
======================================================================
Parameters:
* eax = 74 - function number
* bl = -1 - subfunction number
Returned value:
* eax = number of active network devices
======================================================================
======== Function 74, Subfunction 0, Get network device type. ========
======================================================================
Parameters:
* eax = 74 - function number
* bl = 0 - subfunction number
* bh = device number
Returned value:
* eax = device type
======================================================================
======== Function 74, Subfunction 1, Get network device name. ========
======================================================================
Parameters:
* eax = 74 - function number
* bl = 1 - subfunction number
* bh = device number
* ecx = pointer to 64 byte buffer
Returned value:
* eax = -1 on error
* The network device name is written into the buffer, on success
======================================================================
========= Function 74, Subfunction 2, Reset network device. ==========
======================================================================
Parameters:
* eax = 74 - function number
* bl = 2 - subfunction number
* bh = device number
Returned value:
* eax = -1 on error
======================================================================
========== Function 74, Subfunction 3, Stop network device. ==========
======================================================================
Parameters:
* eax = 74 - function number
* bl = 3 - subfunction number
* bh = device number
Returned value:
* eax = -1 on error
======================================================================
============== Function 75, Subfunction 0, Open socket. ==============
======================================================================
Parameters:
* eax = 75 - function number
* bl = 0 - subfunction number
* ecx = domain
* edx = type
* esi = protocol
Returned value:
* eax = socket number, -1 on error
======================================================================
============= Function 75, Subfunction 1, Close socket. ==============
======================================================================
Parameters:
* eax = 75 - function number
* bl = 1 - subfunction number
* ecx = socket number
Returned value:
* eax = -1 on error
======================================================================
================== Function 75, Subfunction 2, Bind. =================
======================================================================
Parameters:
* eax = 75 - function number
* bl = 2 - subfunction number
* ecx = socket number
* edx = pointer to sockaddr structure
* esi = length of sockaddr structure
Returned value:
* eax = -1 on error
======================================================================
================= Function 75, Subfunction 3, Listen. ================
======================================================================
Parameters:
* eax = 75 - function number
* bl = 3 - subfunction number
* ecx = socket number
* edx = backlog
Returned value:
* eax = -1 on error
======================================================================
================ Function 75, Subfunction 4, Connect. ================
======================================================================
Parameters:
* eax = 75 - function number
* bl = 4 - subfunction number
* ecx = socket number
* edx = pointer to sockaddr structure
* esi = length of sockaddr structure
Returned value:
* eax = -1 on error
======================================================================
================= Function 75, Subfunction 5, Accept. ================
======================================================================
Parameters:
* eax = 75 - function number
* bl = 5 - subfunction number
* ecx = socket number
* edx = pointer to sockaddr structure
* esi = length of sockaddr structure
Returned value:
* eax = -1 on error
======================================================================
================== Function 75, Subfunction 6, Send. =================
======================================================================
Parameters:
* eax = 75 - function number
* bl = 6 - subfunction number
* ecx = socket number
* edx = pointer to buffer
* esi = length of buffer
Returned value:
* eax = number of bytes copied, -1 on error
======================================================================
================ Function 75, Subfunction 7, Receive. ================
======================================================================
Parameters:
* eax = 75 - function number
* bl = 7 - subfunction number
* ecx = socket number
* edx = pointer to buffer
* esi = length of buffer
* edi = flags
Returned value:
* eax = number of bytes copied, -1 on error
======================================================================
=========== Function 75, Subfunction 8, Set socket options. ==========
======================================================================
Parameters:
* eax = 75 - function number
* bl = 8 - subfunction number
* ecx = socket number
* edx = pointer to optstruct
Returned value:
* eax = -1 on error
Remarks:
Optstruct: dd level
dd optionname
dd optlength
db options...
======================================================================
=========== Function 75, Subfunction 9, Get socket options. ==========
======================================================================
Parameters:
* eax = 75 - function number
* bl = 9 - subfunction number
* ecx = socket number
* edx = pointer to optstruct
Returned value:
* eax = -1 on error
Remarks:
Optstruct: dd level
dd optionname
dd optlength
db options...
======================================================================
============ Function 75, Subfunction 10, Get socketpair. ===========
======================================================================
Parameters:
* eax = 75 - function number
* bl = 10 - subfunction number
Returned value:
* eax = socketnum1, -1 on error
* ebx = socketnum2
Remarks:
Optstruct: dd level
dd optionname
dd optlength
db options...
====================================================================== ======================================================================
=============== Function -1 - terminate thread/process =============== =============== Function -1 - terminate thread/process ===============
====================================================================== ======================================================================

View File

@ -4,8 +4,8 @@ configuration is always selected. The kernel also reads device descriptor to
print some information, reads and parses configuration descriptor. For every print some information, reads and parses configuration descriptor. For every
interface the kernel looks for class code of this interface and loads the interface the kernel looks for class code of this interface and loads the
corresponding COFF driver. Currently the correspondence is hardcoded into corresponding COFF driver. Currently the correspondence is hardcoded into
the kernel code and looks as follows: 3 = usbhid.obj, 8 = usbstor.obj, the kernel code and looks as follows: 3 = usbhid.obj, 7 = usbprint.obj,
9 is handled by the kernel itself, other = usbother.obj. 8 = usbstor.obj, 9 is handled by the kernel itself, other = usbother.obj.
The driver must be standard driver in COFF format, exporting procedure The driver must be standard driver in COFF format, exporting procedure
named "START" and a variable named "version". Loader calls "START" procedure named "START" and a variable named "version". Loader calls "START" procedure
@ -46,7 +46,7 @@ void* __stdcall AddDevice(
void* interfacedescr void* interfacedescr
); );
The parameter 'controlpipe' is a handle of the control pipe for endpoint zero The parameter 'pipe0' is a handle of the control pipe for endpoint zero
of the device. It can be used as the argument of USBControlTransferAsync. of the device. It can be used as the argument of USBControlTransferAsync.
The parameter 'configdescr' points to USB configuration descriptor The parameter 'configdescr' points to USB configuration descriptor
and all associated data, as returned by GET_DESCRIPTOR request. and all associated data, as returned by GET_DESCRIPTOR request.
@ -93,6 +93,19 @@ The parameter 'type' selects the type of the endpoint as defined by USB:
The parameter 'interval' is ignored for control and bulk endpoints. The parameter 'interval' is ignored for control and bulk endpoints.
For interrupt endpoints, it sets the polling interval in milliseconds. For interrupt endpoints, it sets the polling interval in milliseconds.
The function returns a handle to the pipe or NULL on failure. The function returns a handle to the pipe or NULL on failure.
The output handle becomes invalid when a) it is explicitly closed with
the following function or b) the function DeviceDisconnected provided
by the driver returns.
void __stdcall USBClosePipe(
void* pipe
);
Releases all resources associated with the given pipe. The only parameter
must be a handle returned by USBOpenPipe.
When a device is disconnected, all associated pipes are closed by the kernel;
there is no need to ever call this function if all pipes are used continuously
while a device is connected.
void* __stdcall USBNormalTransferAsync( void* __stdcall USBNormalTransferAsync(
void* pipe, void* pipe,
@ -104,7 +117,7 @@ void* __stdcall USBNormalTransferAsync(
); );
void* __stdcall USBControlTransferAsync( void* __stdcall USBControlTransferAsync(
void* pipe, void* pipe,
void* config, void* setup,
void* buffer, void* buffer,
int size, int size,
void* callback, void* callback,
@ -116,12 +129,12 @@ The first function inserts a bulk or interrupt transfer to the transfer queue
for given pipe. Type and direction of transfer are fixed for bulk and interrupt for given pipe. Type and direction of transfer are fixed for bulk and interrupt
endpoints and are set in USBOpenPipe. The second function inserts a control endpoints and are set in USBOpenPipe. The second function inserts a control
transfer to the transfer queue for given pipe. Direction of a control transfer transfer to the transfer queue for given pipe. Direction of a control transfer
is concluded from 'config' packet, bit 7 of byte 0 is set for IN transfers is concluded from 'setup' packet, bit 7 of byte 0 is set for IN transfers
and cleared for OUT transfers. These function return immediately; when data and cleared for OUT transfers. These function return immediately; when data
are transferred, the callback function will be called. are transferred, the callback function will be called.
The parameter 'pipe' is a handle returned by USBOpenPipe. The parameter 'pipe' is a handle returned by USBOpenPipe.
The parameter 'config' of USBControlTransferAsync points to 8-byte The parameter 'setup' of USBControlTransferAsync points to 8-byte
configuration packet as defined by USB. configuration packet as defined by USB.
The parameter 'buffer' is a pointer to buffer. For IN transfers, it will be The parameter 'buffer' is a pointer to buffer. For IN transfers, it will be
filled with the data. For OUT transfers, it should contain data to be filled with the data. For OUT transfers, it should contain data to be
@ -174,10 +187,12 @@ USB_STATUS_BUFOVERRUN = 12 ; overflow of internal controller buffer
; possible only for isochronous transfers ; possible only for isochronous transfers
USB_STATUS_BUFUNDERRUN = 13 ; underflow of internal controller buffer USB_STATUS_BUFUNDERRUN = 13 ; underflow of internal controller buffer
; possible only for isochronous transfers ; possible only for isochronous transfers
USB_STATUS_DISCONNECTED = 16 ; device disconnected USB_STATUS_CLOSED = 16 ; pipe closed, either explicitly with USBClosePipe
; or due to device disconnect
If several transfers are queued for the same pipe, their callback functions If several transfers are queued for the same pipe, their callback functions
are called in the same order as they were queued. are called in the same order as they were queued.
When the device is disconnected, all callback functions are called When a pipe is closed, either explicitly with USBClosePipe, or
with USB_STATUS_DISCONNECTED. The call to DeviceDisconnected() occurs after implicitly due to device disconnect, all callback functions are called
with USB_STATUS_CLOSED. The call to DeviceDisconnected() occurs after
all callbacks. all callbacks.

View File

@ -0,0 +1,696 @@
; standard driver stuff
format MS COFF
DEBUG = 1
; this is for DEBUGF macro from 'fdo.inc'
__DEBUG__ = 1
__DEBUG_LEVEL__ = 1
include 'proc32.inc'
include 'imports.inc'
include 'fdo.inc'
public START
public version
; USB constants
DEVICE_DESCR_TYPE = 1
CONFIG_DESCR_TYPE = 2
STRING_DESCR_TYPE = 3
INTERFACE_DESCR_TYPE = 4
ENDPOINT_DESCR_TYPE = 5
DEVICE_QUALIFIER_DESCR_TYPE = 6
CONTROL_PIPE = 0
ISOCHRONOUS_PIPE = 1
BULK_PIPE = 2
INTERRUPT_PIPE = 3
; USB structures
virtual at 0
config_descr:
.bLength db ?
.bDescriptorType db ?
.wTotalLength dw ?
.bNumInterfaces db ?
.bConfigurationValue db ?
.iConfiguration db ?
.bmAttributes db ?
.bMaxPower db ?
.sizeof:
end virtual
virtual at 0
interface_descr:
.bLength db ?
.bDescriptorType db ?
.bInterfaceNumber db ?
.bAlternateSetting db ?
.bNumEndpoints db ?
.bInterfaceClass db ?
.bInterfaceSubClass db ?
.bInterfaceProtocol db ?
.iInterface db ?
.sizeof:
end virtual
virtual at 0
endpoint_descr:
.bLength db ?
.bDescriptorType db ?
.bEndpointAddress db ?
.bmAttributes db ?
.wMaxPacketSize dw ?
.bInterval db ?
.sizeof:
end virtual
; Driver data for all devices
virtual at 0
device_data:
.type dd ? ; 1 = keyboard, 2 = mouse
.intpipe dd ? ; interrupt pipe handle
.packetsize dd ?
.packet rb 8 ; packet with data from device
.control rb 8 ; control packet to device
.sizeof:
end virtual
; Driver data for mouse
virtual at device_data.sizeof
mouse_data:
; no additional data
.sizeof:
end virtual
; Driver data for keyboard
virtual at device_data.sizeof
keyboard_data:
.handle dd ? ; keyboard handle from RegKeyboard
.configpipe dd ? ; config pipe handle
.prevpacket rb 8 ; previous packet with data from device
.timer dd ? ; auto-repeat timer handle
.repeatkey db ? ; auto-repeat key code
.ledstate db ? ; state of LEDs
align 4
.sizeof:
end virtual
section '.flat' code readable align 16
; The start procedure.
START:
; 1. Test whether the procedure is called with the argument DRV_ENTRY.
; If not, return 0.
xor eax, eax ; initialize return value
cmp dword [esp+4], 1 ; compare the argument
jnz .nothing
; 2. Register self as a USB driver.
; The name is my_driver = 'usbhid'; IOCTL interface is not supported;
; usb_functions is an offset of a structure with callback functions.
stdcall RegUSBDriver, my_driver, eax, usb_functions
; 3. Return the returned value of RegUSBDriver.
.nothing:
ret 4
; This procedure is called when new HID device is detected.
; It initializes the device.
AddDevice:
; Arguments are addressed through esp. In this point of the function,
; [esp+4] = a handle of the config pipe, [esp+8] points to config_descr
; structure, [esp+12] points to interface_descr structure.
; 1. Check device type. Currently only mice and keyboards with
; boot protocol are supported.
; 1a. Get the subclass and the protocol. Since bInterfaceSubClass and
; bInterfaceProtocol are subsequent in interface_descr, just one
; memory reference is used for both.
mov edx, [esp+12]
push ebx ; save used register to be stdcall
mov cx, word [edx+interface_descr.bInterfaceSubClass]
; 1b. For boot protocol, subclass must be 1 and protocol must be either 1 for
; a keyboard or 2 for a mouse. Check.
cmp cx, 0x0101
jz .keyboard
cmp cx, 0x0201
jz .mouse
; 1c. If the device is neither a keyboard nor a mouse, print a message and
; go to 6c.
DEBUGF 1,'K : unknown HID device\n'
jmp .nothing
; 1d. If the device is a keyboard or a mouse, print a message and continue
; configuring.
.keyboard:
DEBUGF 1,'K : USB keyboard detected\n'
push keyboard_data.sizeof
jmp .common
.mouse:
DEBUGF 1,'K : USB mouse detected\n'
push mouse_data.sizeof
.common:
; 2. Allocate memory for device data.
pop eax ; get size of device data
; 2a. Call the kernel, saving and restoring register edx.
push edx
call Kmalloc
pop edx
; 2b. Check result. If failed, say a message and go to 6c.
test eax, eax
jnz @f
DEBUGF 1,'K : no memory\n'
jmp .nothing
@@:
xchg eax, ebx
; HID devices use one IN interrupt endpoint for polling the device
; and an optional OUT interrupt endpoint. We do not use the later,
; but must locate the first. Look for the IN interrupt endpoint.
; 3. Get the upper bound of all descriptors' data.
mov eax, [esp+8+4] ; configuration descriptor
movzx ecx, [eax+config_descr.wTotalLength]
add eax, ecx
; 4. Loop over all descriptors until
; either end-of-data reached - this is fail
; or interface descriptor found - this is fail, all further data
; correspond to that interface
; or endpoint descriptor found.
; 4a. Loop start: eax points to the interface descriptor.
.lookep:
; 4b. Get next descriptor.
movzx ecx, byte [edx] ; the first byte of all descriptors is length
add edx, ecx
; 4c. Check that at least two bytes are readable. The opposite is an error.
inc edx
cmp edx, eax
jae .errorep
dec edx
; 4d. Check that this descriptor is not interface descriptor. The opposite is
; an error.
cmp byte [edx+endpoint_descr.bDescriptorType], INTERFACE_DESCR_TYPE
jz .errorep
; 4e. Test whether this descriptor is an endpoint descriptor. If not, continue
; the loop.
cmp byte [edx+endpoint_descr.bDescriptorType], ENDPOINT_DESCR_TYPE
jnz .lookep
; 5. Check that the descriptor contains all required data and all data are
; readable. If so, proceed to 7.
cmp byte [edx+endpoint_descr.bLength], endpoint_descr.sizeof
jb .errorep
sub eax, endpoint_descr.sizeof
cmp edx, eax
jbe @f
; 6. An error occured during processing endpoint descriptor.
.errorep:
; 6a. Print a message.
DEBUGF 1,'K : error: invalid endpoint descriptor\n'
; 6b. Free memory allocated for device data.
.free:
xchg eax, ebx
call Kfree
.nothing:
; 6c. Return an error.
xor eax, eax
pop ebx
ret 12
@@:
; 7. Check that the endpoint is IN interrupt endpoint. If not, go to 6.
test [edx+endpoint_descr.bEndpointAddress], 80h
jz .errorep
mov cl, [edx+endpoint_descr.bmAttributes]
and cl, 3
cmp cl, INTERRUPT_PIPE
jnz .errorep
; 8. Open pipe for the endpoint.
; 8a. Load parameters from the descriptor.
movzx ecx, [edx+endpoint_descr.bEndpointAddress]
movzx eax, [edx+endpoint_descr.bInterval]
movzx edx, [edx+endpoint_descr.wMaxPacketSize]
; 8b. Call the kernel, saving and restoring edx.
push edx
stdcall USBOpenPipe, [esp+4+24], ecx, edx, INTERRUPT_PIPE, eax
pop edx
; 8c. Check result. If failed, go to 6b.
test eax, eax
jz .free
; We use 12 bytes for device type, interrupt pipe and interrupt packet size,
; 8 bytes for a packet and 8 bytes for previous packet, used by a keyboard.
; 9. Initialize device data.
mov [ebx+device_data.intpipe], eax
push 8
pop ecx
cmp edx, ecx
jb @f
mov edx, ecx
@@:
xor eax, eax
mov [ebx+device_data.packetsize], edx
mov dword [ebx+device_data.packet], eax
mov dword [ebx+device_data.packet+4], eax
mov edx, [esp+12+4] ; interface descriptor
movzx ecx, [edx+interface_descr.bInterfaceProtocol]
mov [ebx+device_data.type], ecx
cmp ecx, 1
jnz @f
mov [ebx+keyboard_data.handle], eax
mov [ebx+keyboard_data.timer], eax
mov [ebx+keyboard_data.repeatkey], al
mov dword [ebx+keyboard_data.prevpacket], eax
mov dword [ebx+keyboard_data.prevpacket+4], eax
mov eax, [esp+4+4]
mov [ebx+keyboard_data.configpipe], eax
@@:
; 10. Send the control packet SET_PROTOCOL(Boot Protocol) to the interface.
lea eax, [ebx+device_data.control]
mov dword [eax], 21h + (0Bh shl 8) + (0 shl 16) ; class request to interface + SET_PROTOCOL + Boot protocol
and dword [eax+4], 0
mov dl, [edx+interface_descr.bInterfaceNumber]
mov [eax+4], dl
; Callback function is mouse_configured for mice and keyboard_configured1 for keyboards.
mov edx, keyboard_configured1
cmp ecx, 1
jz @f
mov edx, mouse_configured
@@:
stdcall USBControlTransferAsync, [esp+4+28], eax, 0, 0, edx, ebx, 0
; 11. Return with pointer to device data as returned value.
xchg eax, ebx
pop ebx
ret 12
; This function is called when SET_PROTOCOL command for keyboard is done,
; either successful or unsuccessful.
keyboard_configured1:
xor edx, edx
; 1. Check the status of the transfer.
; If the transfer was failed, go to the common error handler.
cmp dword [esp+8], edx ; status is zero?
jnz keyboard_data_ready.error
; 2. Send the control packet SET_IDLE(infinity). HID auto-repeat is not useful.
mov eax, [esp+20]
push edx ; flags for USBControlTransferAsync
push eax ; userdata for USBControlTransferAsync
add eax, device_data.control
mov dword [eax], 21h + (0Ah shl 8) + (0 shl 24) ; class request to interface + SET_IDLE + no autorepeat
stdcall USBControlTransferAsync, dword [eax+keyboard_data.configpipe-device_data.control], \
eax, edx, edx, keyboard_configured2; , <userdata>, <flags>
; 3. Return.
ret 20
; This function is called when SET_IDLE command for keyboard is done,
; either successful or unsuccessful.
keyboard_configured2:
; Check the status of the transfer and go to the corresponding label
; in the main handler.
cmp dword [esp+8], 0
jnz keyboard_data_ready.error
mov edx, [esp+20]
push edx
stdcall RegKeyboard, usbkbd_functions, edx
pop edx
mov [edx+keyboard_data.handle], eax
jmp keyboard_data_ready.next
; This function is called when another interrupt packet arrives,
; processed either successfully or unsuccessfully.
; It should parse the packet and initiate another transfer with
; the same callback function.
keyboard_data_ready:
; 1. Check the status of the transfer.
mov eax, [esp+8]
test eax, eax
jnz .error
; Parse the packet, comparing with the previous packet.
; For boot protocol, USB keyboard packet consists of the first byte
; with status keys that are currently pressed. The second byte should
; be ignored, and other 5 bytes denote keys that are currently pressed.
push esi ebx ; save used registers to be stdcall
; 2. Process control keys.
; 2a. Initialize before loop for control keys. edx = mask for control bits
; that were changed.
mov ebx, [esp+20+8]
movzx edx, byte [ebx+device_data.packet] ; get state of control keys
xor dl, byte [ebx+keyboard_data.prevpacket] ; compare with previous state
; 2b. If state of control keys has not changed, advance to 3.
jz .nocontrol
; 2c. Otherwise, loop over control keys; esi = bit number.
xor esi, esi
.controlloop:
; 2d. Skip bits that have not changed.
bt edx, esi
jnc .controlnext
push edx ; save register which is possibly modified by API
; The state of the current control key has changed.
; 2e. For extended control keys, send the prefix 0xE0.
mov al, [control_keys+esi]
test al, al
jns @f
push eax
mov ecx, 0xE0
call SetKeyboardData
pop eax
and al, 0x7F
@@:
; 2f. If the current state of the control key is "pressed", send normal
; scancode. Otherwise, the key is released, so set the high bit in scancode.
movzx ecx, al
bt dword [ebx+device_data.packet], esi
jc @f
or cl, 0x80
@@:
call SetKeyboardData
pop edx ; restore register which was possibly modified by API
.controlnext:
; 2g. We have 8 control keys.
inc esi
cmp esi, 8
jb .controlloop
.nocontrol:
; 3. Initialize before loop for normal keys. esi = index.
push 2
pop esi
.normalloop:
; 4. Process one key which was pressed in the previous packet.
; 4a. Get the next pressed key from the previous packet.
movzx eax, byte [ebx+esi+keyboard_data.prevpacket]
; 4b. Ignore special codes.
cmp al, 3
jbe .normalnext1
; 4c. Ignore keys that are still pressed in the current packet.
lea ecx, [ebx+device_data.packet]
call haskey
jz .normalnext1
; 4d. Say warning about keys with strange codes.
cmp eax, normal_keys_number
jae .badkey1
movzx ecx, [normal_keys+eax]
jecxz .badkey1
; 4e. For extended keys, send the prefix 0xE0.
push ecx ; save keycode
test cl, cl
jns @f
push ecx
mov ecx, 0xE0
call SetKeyboardData
pop ecx
@@:
; 4f. Send the release event.
or cl, 0x80
call SetKeyboardData
; 4g. If this key is autorepeating, stop the timer.
pop ecx ; restore keycode
cmp cl, [ebx+keyboard_data.repeatkey]
jnz .normalnext1
mov eax, [ebx+keyboard_data.timer]
test eax, eax
jz .normalnext1
stdcall CancelTimerHS, eax
and [ebx+keyboard_data.timer], 0
jmp .normalnext1
.badkey1:
DEBUGF 1,'K : unknown keycode: %x\n',al
.normalnext1:
; 5. Process one key which is pressed in the current packet.
; 5a. Get the next pressed key from the current packet.
movzx eax, byte [ebx+esi+device_data.packet]
; 5b. Ignore special codes.
cmp al, 3
jbe .normalnext2
; 5c. Ignore keys that were already pressed in the previous packet.
lea ecx, [ebx+keyboard_data.prevpacket]
call haskey
jz .normalnext2
; 5d. Say warning about keys with strange codes.
cmp eax, normal_keys_number
jae .badkey2
movzx ecx, [normal_keys+eax]
jecxz .badkey2
; 5e. For extended keys, send the prefix 0xE0.
push ecx ; save keycode
test cl, cl
jns @f
push ecx
mov ecx, 0xE0
call SetKeyboardData
pop ecx
@@:
; 5f. Send the press event.
and cl, not 0x80
call SetKeyboardData
; 5g. Stop the current auto-repeat timer, if present.
mov eax, [ebx+keyboard_data.timer]
test eax, eax
jz @f
stdcall CancelTimerHS, eax
@@:
; 5h. Start the auto-repeat timer.
pop ecx ; restore keycode
mov [ebx+keyboard_data.repeatkey], cl
stdcall TimerHS, 25, 5, autorepeat_timer, ebx
mov [ebx+keyboard_data.timer], eax
jmp .normalnext2
.badkey2:
DEBUGF 1,'K : unknown keycode: %x\n',al
.normalnext2:
; 6. Advance to next key.
inc esi
cmp esi, 8
jb .normalloop
; 7. Save the packet data for future reference.
mov eax, dword [ebx+device_data.packet]
mov dword [ebx+keyboard_data.prevpacket], eax
mov eax, dword [ebx+device_data.packet+4]
mov dword [ebx+keyboard_data.prevpacket+4], eax
pop ebx esi ; restore registers to be stdcall
.next:
; 8. Initiate transfer on the interrupt pipe.
mov eax, [esp+20]
push 1 ; flags for USBNormalTransferAsync
push eax ; userdata for USBNormalTransferAsync
add eax, device_data.packet
stdcall USBNormalTransferAsync, dword [eax+device_data.intpipe-device_data.packet], \
eax, dword [eax+device_data.packetsize-device_data.packet], \
keyboard_data_ready;, <userdata>, <flags>
; 9. Return.
.nothing:
ret 20
.error:
; An error has occured.
; 10. If an error is caused by the disconnect, do nothing, it is handled
; in DeviceDisconnected. Otherwise, say a message.
cmp eax, 16
jz @f
push esi
mov esi, errormsgkbd
call SysMsgBoardStr
pop esi
@@:
ret 20
; Auxiliary procedure for keyboard_data_ready.
haskey:
push 2
pop edx
@@:
cmp byte [ecx+edx], al
jz @f
inc edx
cmp edx, 7
jbe @b
@@:
ret
; Timer function for auto-repeat.
autorepeat_timer:
mov eax, [esp+4]
movzx ecx, [eax+keyboard_data.repeatkey]
test cl, cl
jns @f
push ecx
mov ecx, 0xE0
call SetKeyboardData
pop ecx
and cl, not 0x80
@@:
call SetKeyboardData
ret 4
; This function is called to update LED state on the keyboard.
SetKeyboardLights:
mov eax, [esp+4]
add eax, device_data.control
mov dword [eax], 21h + (9 shl 8) + (2 shl 24)
; class request to interface + SET_REPORT + Output zero report
mov byte [eax+6], 1
mov edx, [esp+8]
shr dl, 1
jnc @f
or dl, 4
@@:
lea ecx, [eax+keyboard_data.ledstate-device_data.control]
mov [ecx], dl
stdcall USBControlTransferAsync, dword [eax+keyboard_data.configpipe-device_data.control], \
eax, ecx, 1, keyboard_data_ready.nothing, 0, 0
ret 8
; This function is called when it is safe to free keyboard data.
CloseKeyboard:
mov eax, [esp+4]
push ebx
call Kfree
pop ebx
ret 4
; This function is called when SET_PROTOCOL command for mouse is done,
; either successful or unsuccessful.
mouse_configured:
; Check the status of the transfer and go to the corresponding label
; in the main handler.
cmp dword [esp+8], 0
jnz mouse_data_ready.error
mov eax, [esp+20]
add eax, device_data.packet
jmp mouse_data_ready.next
; This function is called when another interrupt packet arrives,
; processed either successfully or unsuccessfully.
; It should parse the packet and initiate another transfer with
; the same callback function.
mouse_data_ready:
; 1. Check the status of the transfer.
mov eax, [esp+8]
test eax, eax
jnz .error
mov edx, [esp+16]
; 2. Parse the packet.
; For boot protocol, USB mouse packet consists of at least 3 bytes.
; The first byte is state of mouse buttons, the next two bytes are
; x and y movements.
; Normal mice do not distinguish between boot protocol and report protocol;
; in this case, scroll data are also present. Advanced mice, however,
; support two different protocols, boot protocol is used for compatibility
; and does not contain extended buttons or scroll data.
mov eax, [esp+12] ; buffer
push eax
xor ecx, ecx
cmp edx, 4
jbe @f
movsx ecx, byte [eax+4]
@@:
push ecx
xor ecx, ecx
cmp edx, 3
jbe @f
movsx ecx, byte [eax+3]
neg ecx
@@:
push ecx
xor ecx, ecx
cmp edx, 2
jbe @f
movsx ecx, byte [eax+2]
neg ecx
@@:
push ecx
movsx ecx, byte [eax+1]
push ecx
movzx ecx, byte [eax]
push ecx
call SetMouseData
pop eax
.next:
; 3. Initiate transfer on the interrupt pipe.
stdcall USBNormalTransferAsync, dword [eax+device_data.intpipe-device_data.packet], \
eax, dword [eax+device_data.packetsize-device_data.packet], mouse_data_ready, eax, 1
; 4. Return.
ret 20
.error:
; An error has occured.
; 5. If an error is caused by the disconnect, do nothing, it is handled
; in DeviceDisconnected. Otherwise, say a message.
cmp eax, 16
jz @f
push esi
mov esi, errormsgmouse
call SysMsgBoardStr
pop esi
@@:
ret 20
; This function is called when the device is disconnected.
DeviceDisconnected:
push ebx ; save used register to be stdcall
; 1. Say a message. Use different messages for keyboards and mice.
mov ebx, [esp+4+4]
push esi
mov esi, disconnectmsgk
cmp byte [ebx+device_data.type], 1
jz @f
mov esi, disconnectmsgm
@@:
stdcall SysMsgBoardStr
pop esi
; 2. If device is keyboard, then we must unregister it as a keyboard and
; possibly stop the auto-repeat timer.
cmp byte [ebx+device_data.type], 1
jnz .nokbd
mov eax, [ebx+keyboard_data.timer]
test eax, eax
jz @f
stdcall CancelTimerHS, eax
@@:
mov ecx, [ebx+keyboard_data.handle]
jecxz .nokbd
stdcall DelKeyboard, ecx
; If keyboard is registered, then we should free data in CloseKeyboard, not here.
jmp .nothing
.nokbd:
; 3. Free the device data.
xchg eax, ebx
call Kfree
; 4. Return.
.nothing:
pop ebx ; restore used register to be stdcall
ret 4 ; purge one dword argument to be stdcall
; strings
my_driver db 'usbhid',0
errormsgmouse db 'K : USB transfer error, disabling mouse',10,0
errormsgkbd db 'K : USB transfer error, disabling keyboard',10,0
disconnectmsgm db 'K : USB mouse disconnected',10,0
disconnectmsgk db 'K : USB keyboard disconnected',10,0
; data for keyboard: correspondence between HID usage keys and PS/2 scancodes.
EX = 80h
label control_keys byte
db 1Dh, 2Ah, 38h, 5Bh+EX, 1Dh+EX, 36h, 38h+EX, 5Ch+EX
label normal_keys byte
db 00h, 00h, 00h, 00h, 1Eh, 30h, 2Eh, 20h, 12h, 21h, 22h, 23h, 17h, 24h, 25h, 26h ; 0x
db 32h, 31h, 18h, 19h, 10h, 13h, 1Fh, 14h, 16h, 2Fh, 11h, 2Dh, 15h, 2Ch, 02h, 03h ; 1x
db 04h, 05h, 06h, 07h, 08h, 09h, 0Ah, 0Bh, 1Ch, 01h, 0Eh, 0Fh, 39h, 0Ch, 0Dh, 1Ah ; 2x
db 1Bh, 2Bh, 2Bh, 27h, 28h, 29h, 33h, 34h, 35h, 3Ah, 3Bh, 3Ch, 3Dh, 3Eh, 3Fh, 40h ; 3x
db 41h, 42h, 43h, 44h, 57h, 58h,37h+EX,46h,0,52h+EX,47h+EX,49h+EX,53h+EX,4Fh+EX,51h+EX,4Dh+EX ; 4x
db 4Bh+EX,50h+EX,48h+EX,45h,35h+EX,37h,4Ah,4Eh,1Ch+EX,4Fh,50h,51h,4Bh,4Ch,4Dh,47h ; 5x
db 48h, 49h, 52h, 53h, 56h,5Dh+EX,5Eh+EX,59h,64h,65h,66h, 67h, 68h, 69h, 6Ah, 6Bh ; 6x
db 6Ch, 6Dh, 6Eh, 76h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h ; 7x
db 00h, 00h, 00h, 00h, 00h, 7Eh, 00h, 73h, 70h, 7Dh, 79h, 7Bh, 5Ch, 00h, 00h, 00h ; 8x
db 0F2h,0F1h,78h, 77h, 76h
normal_keys_number = $ - normal_keys
; Exported variable: kernel API version.
align 4
version dd 50005h
; Structure with callback functions.
usb_functions:
dd 12
dd AddDevice
dd DeviceDisconnected
; Structure with callback functions for keyboards.
usbkbd_functions:
dd 12
dd CloseKeyboard
dd SetKeyboardLights
; for DEBUGF macro
include_debug_strings
; for uninitialized data
section '.data' data readable writable align 16

File diff suppressed because it is too large Load Diff

View File

@ -516,7 +516,7 @@ align 4
btr ecx, eax ; сбрасываем проверяемый бит маски btr ecx, eax ; сбрасываем проверяемый бит маски
; переходим на обработчик этого (eax) бита ; переходим на обработчик этого (eax) бита
cmp eax, 10 cmp eax, 10
jae .loop ; eax=[10..31], ignored (event 10...32) jae .loop ; eax=[10..31], ignored (event 11...32)
cmp eax, 3 cmp eax, 3
je .loop ; eax=3, ignored (event 4) je .loop ; eax=3, ignored (event 4)

View File

@ -17,21 +17,16 @@ read_skin_file:
stdcall load_file, ebx stdcall load_file, ebx
test eax, eax test eax, eax
jz .notfound jz .notfound
cmp dword [eax], 'SKIN' cmp dword [eax], 'SKIN'
jnz .noskin jnz .noskin
cmp ebx, 32*1024
jb @f
mov ebx, 32*1024
;--------------------------------------
align 4
@@:
lea ecx, [ebx+3]
shr ecx, 2
mov esi, eax
mov edi, skin_data
rep movsd
stdcall kernel_free, eax
xchg eax, [skin_data]
test eax, eax
jz @f
stdcall kernel_free, eax
@@:
call parse_skin_data call parse_skin_data
xor eax, eax xor eax, eax
ret ret
@ -45,8 +40,7 @@ align 4
align 4 align 4
.noskin: .noskin:
stdcall kernel_free, eax stdcall kernel_free, eax
push 2 mov eax, 2
pop eax
ret ret
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
struct SKIN_HEADER struct SKIN_HEADER
@ -98,7 +92,7 @@ load_default_skin:
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
align 4 align 4
parse_skin_data: parse_skin_data:
mov ebp, skin_data mov ebp, [skin_data]
cmp [ebp+SKIN_HEADER.ident], 'SKIN' cmp [ebp+SKIN_HEADER.ident], 'SKIN'
jne .exit jne .exit
@ -109,7 +103,7 @@ parse_skin_data:
rep stosd rep stosd
mov ebx, [ebp+SKIN_HEADER.params] mov ebx, [ebp+SKIN_HEADER.params]
add ebx, skin_data add ebx, [skin_data]
mov eax, [ebx+SKIN_PARAMS.skin_height] mov eax, [ebx+SKIN_PARAMS.skin_height]
mov [_skinh], eax mov [_skinh], eax
mov eax, [ebx+SKIN_PARAMS.colors.inner] mov eax, [ebx+SKIN_PARAMS.colors.inner]
@ -135,7 +129,7 @@ parse_skin_data:
mov dword[_skinmargins+4], eax mov dword[_skinmargins+4], eax
mov ebx, [ebp+SKIN_HEADER.bitmaps] mov ebx, [ebp+SKIN_HEADER.bitmaps]
add ebx, skin_data add ebx, [skin_data]
;-------------------------------------- ;--------------------------------------
align 4 align 4
.lp1: .lp1:
@ -160,7 +154,7 @@ align 4
dec eax dec eax
jnz .not_oper jnz .not_oper
mov esi, [ebx+SKIN_BITMAPS.data] mov esi, [ebx+SKIN_BITMAPS.data]
add esi, skin_data add esi, [skin_data]
mov eax, [esi+0] mov eax, [esi+0]
neg eax neg eax
mov edx, skin_active.oper.data mov edx, skin_active.oper.data
@ -195,7 +189,7 @@ align 4
align 4 align 4
.next_bitmap: .next_bitmap:
mov ecx, [ebx+SKIN_BITMAPS.data] mov ecx, [ebx+SKIN_BITMAPS.data]
add ecx, skin_data add ecx, [skin_data]
mov [edx+4], eax mov [edx+4], eax
mov eax, [ecx+0] mov eax, [ecx+0]
mov [edx+8], eax mov [edx+8], eax
@ -207,7 +201,7 @@ align 4
align 4 align 4
.end_bitmaps: .end_bitmaps:
mov ebx, [ebp+SKIN_HEADER.buttons] mov ebx, [ebp+SKIN_HEADER.buttons]
add ebx, skin_data add ebx, [skin_data]
;-------------------------------------- ;--------------------------------------
align 4 align 4
.lp2: .lp2:
@ -396,7 +390,8 @@ _dw3l:
;-------------------------------------- ;--------------------------------------
align 4 align 4
@@: @@:
cmp dword[skin_data], 'SKIN' mov eax, [skin_data]
cmp [eax], dword 'SKIN'
je @f je @f
xor eax, eax xor eax, eax
xor ebx, ebx xor ebx, ebx
@ -438,7 +433,8 @@ draw_clientbar:
;-------------------------------------- ;--------------------------------------
align 4 align 4
_noinside2: _noinside2:
cmp dword[skin_data], 'SKIN' mov eax, [skin_data]
cmp [eax], dword 'SKIN'
jne no_skin_add_button jne no_skin_add_button
;* close button ;* close button
mov edi, [BTN_ADDR] mov edi, [BTN_ADDR]

View File

@ -1024,6 +1024,8 @@ align 4
; no it's not, just activate the window ; no it's not, just activate the window
call window._.window_activate call window._.window_activate
xor eax, eax xor eax, eax
ret
;-------------------------------------- ;--------------------------------------
align 4 align 4
.exit: .exit:

View File

@ -77,7 +77,7 @@ $Revision$
USE_COM_IRQ equ 1 ; make irq 3 and irq 4 available for PCI devices USE_COM_IRQ equ 1 ; make irq 3 and irq 4 available for PCI devices
; Enabling the next line will enable serial output console ; Enabling the next line will enable serial output console
debug_com_base equ 0x3f8 ; 0x3f8 is com1, 0x2f8 is com2, 0x3e8 is com3, 0x2e8 is com4, no irq's are used ;debug_com_base equ 0x3f8 ; 0x3f8 is com1, 0x2f8 is com2, 0x3e8 is com3, 0x2e8 is com4, no irq's are used
; The following constant, if nonzero, duplicates debug output to the screen. ; The following constant, if nonzero, duplicates debug output to the screen.
debug_direct_print equ 0 debug_direct_print equ 0
@ -163,35 +163,6 @@ include "boot/bootcode.inc" ; 16 bit system boot code
include "bus/pci/pci16.inc" include "bus/pci/pci16.inc"
include "detect/biosdisk.inc" include "detect/biosdisk.inc"
FDD_BUFF equ (OS_BASE+0x000D000)
sys_pgdir equ (OS_BASE+0x006F000)
VGABasePtr equ (OS_BASE+0x00A0000)
RAMDISK equ (OS_BASE+0x0100000)
CLEAN_ZONE equ 0x284000
IDE_DMA equ 0x284000
BOOT_VAR equ (OS_BASE+0x02E0000)
TASK_COUNT equ (CURRENT_TASK+0x04)
TASK_BASE equ (CURRENT_TASK+0x10)
TASK_DATA equ (CURRENT_TASK+0x20)
TASK_EVENT equ (CURRENT_TASK+0x20)
BPSLine_calc_area equ (OS_BASE+0x02C4000)
d_width_calc_area equ (OS_BASE+0x02CA000)
stack_data_start equ (OS_BASE+0x02F0000)
eth_data_start equ (OS_BASE+0x02F0000)
stack_data equ (OS_BASE+0x02F4000)
stack_data_end equ (OS_BASE+0x030ffff)
resendQ equ (OS_BASE+0x0310000)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;; ;; ;;
;; SWITCH TO 32 BIT PROTECTED MODE ;; ;; SWITCH TO 32 BIT PROTECTED MODE ;;
@ -434,15 +405,17 @@ high_code:
dec eax dec eax
mov [Screen_Max_Y], eax mov [Screen_Max_Y], eax
mov [screen_workarea.bottom], eax mov [screen_workarea.bottom], eax
mov ax, word [BOOT_VAR+BOOT_VESA_MODE] ; screen mode movzx eax, word [BOOT_VAR+BOOT_VESA_MODE]; screen mode
mov [SCR_MODE], ax mov [SCR_MODE], eax
mov [BytesPerScanLine], 640*4 ; Bytes PerScanLine ; mov eax, [BOOT_VAR+0x9014] ; Vesa 1.2 bnk sw add
cmp [SCR_MODE], 0x13 ; 320x200 ; mov [BANK_SWITCH], eax
mov [BytesPerScanLine], word 640*4 ; Bytes PerScanLine
cmp [SCR_MODE], word 0x13 ; 320x200
je @f je @f
cmp [SCR_MODE], 0x12 ; VGA 640x480 cmp [SCR_MODE], word 0x12 ; VGA 640x480
je @f je @f
movzx eax, word[BOOT_VAR+BOOT_PITCH] ; for other modes movzx eax, word[BOOT_VAR+BOOT_PITCH] ; for other modes
mov [BytesPerScanLine], eax mov [BytesPerScanLine], ax
mov [_display.pitch], eax mov [_display.pitch], eax
@@: @@:
mov eax, [_display.width] mov eax, [_display.width]
@ -1268,6 +1241,7 @@ set_variables:
xor eax, eax xor eax, eax
mov [BTN_ADDR], dword BUTTON_INFO ; address of button list mov [BTN_ADDR], dword BUTTON_INFO ; address of button list
mov byte [MOUSE_BUFF_COUNT], al ; mouse buffer
mov byte [KEY_COUNT], al ; keyboard buffer mov byte [KEY_COUNT], al ; keyboard buffer
mov byte [BTN_COUNT], al ; button buffer mov byte [BTN_COUNT], al ; button buffer
; mov [MOUSE_X],dword 100*65536+100 ; mouse x/y ; mov [MOUSE_X],dword 100*65536+100 ; mouse x/y
@ -4995,7 +4969,7 @@ sys_gs: ; direct screen access
.1: ; resolution .1: ; resolution
mov eax, [Screen_Max_X] mov eax, [Screen_Max_X]
shl eax, 16 shl eax, 16
mov ax, word [Screen_Max_Y] mov ax, [Screen_Max_Y]
add eax, 0x00010001 add eax, 0x00010001
mov [esp+32], eax mov [esp+32], eax
ret ret
@ -5094,9 +5068,9 @@ syscall_drawrect: ; DrawRect
align 4 align 4
syscall_getscreensize: ; GetScreenSize syscall_getscreensize: ; GetScreenSize
mov eax, [Screen_Max_X] mov ax, [Screen_Max_X]
shl eax, 16 shl eax, 16
mov ax, word [Screen_Max_Y] mov ax, [Screen_Max_Y]
mov [esp + 32], eax mov [esp + 32], eax
ret ret

View File

@ -177,7 +177,7 @@ ARP_input:
inc [ARP_PACKETS_RX + 4*edi] ; update stats inc [ARP_PACKETS_RX + 4*edi] ; update stats
DEBUGF 1,"ARP_input: got packet from %u.%u.%u.%u through device %u\n",\ DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: got packet from %u.%u.%u.%u through device %u\n",\
[edx + ARP_header.SenderIP]:1, [edx + ARP_header.SenderIP + 1]:1,\ [edx + ARP_header.SenderIP]:1, [edx + ARP_header.SenderIP + 1]:1,\
[edx + ARP_header.SenderIP + 2]:1, [edx + ARP_header.SenderIP + 3]:1, edi [edx + ARP_header.SenderIP + 2]:1, [edx + ARP_header.SenderIP + 3]:1, edi
@ -194,7 +194,7 @@ ARP_input:
cmp [edx + ARP_header.Opcode], ARP_REP_OPCODE cmp [edx + ARP_header.Opcode], ARP_REP_OPCODE
jne .maybe_request jne .maybe_request
DEBUGF 1,"ARP_input: It's a reply\n" DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: It's a reply\n"
mov ecx, [NumARP] mov ecx, [NumARP]
test ecx, ecx test ecx, ecx
@ -208,16 +208,16 @@ ARP_input:
dec ecx dec ecx
jnz .loop jnz .loop
DEBUGF 1,"ARP_input: no matching entry found\n" DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: no matching entry found\n"
jmp .exit jmp .exit
.gotit: .gotit:
DEBUGF 1,"ARP_input: found matching entry\n" DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: found matching entry\n"
cmp [esi + ARP_entry.TTL], ARP_STATIC_ENTRY ; if it is a static entry, dont touch it cmp [esi + ARP_entry.TTL], ARP_STATIC_ENTRY ; if it is a static entry, dont touch it
je .exit je .exit
DEBUGF 1,"ARP_input: updating entry\n" DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: updating entry\n"
mov [esi + ARP_entry.Status], ARP_VALID_MAPPING mov [esi + ARP_entry.Status], ARP_VALID_MAPPING
mov [esi + ARP_entry.TTL], ARP_ENTRY_TTL mov [esi + ARP_entry.TTL], ARP_ENTRY_TTL
@ -236,7 +236,7 @@ ARP_input:
cmp [edx + ARP_header.Opcode], ARP_REQ_OPCODE cmp [edx + ARP_header.Opcode], ARP_REQ_OPCODE
jne .exit jne .exit
DEBUGF 1,"ARP_input: its a request\n" DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: its a request\n"
mov eax, [IP_LIST + 4*edi] mov eax, [IP_LIST + 4*edi]
cmp eax, [edx + ARP_header.TargetIP] ; Is it looking for my IP address? cmp eax, [edx + ARP_header.TargetIP] ; Is it looking for my IP address?
@ -277,20 +277,20 @@ ARP_input:
; mov ax , ETHER_ARP ; It's already there, I'm sure of it! ; mov ax , ETHER_ARP ; It's already there, I'm sure of it!
; stosw ; stosw
DEBUGF 1,"ARP_input: Sending reply\n" DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: Sending reply\n"
call [ebx + NET_DEVICE.transmit] call [ebx + NET_DEVICE.transmit]
ret ret
.collision: .collision:
inc [ARP_CONFLICTS + 4*edi] inc [ARP_CONFLICTS + 4*edi]
DEBUGF 1,"ARP_input: IP address conflict detected!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: IP address conflict detected!\n"
.exit: .exit:
call kernel_free call kernel_free
add esp, 4 ; pop (balance stack) add esp, 4 ; pop (balance stack)
DEBUGF 1,"ARP_input: exiting\n" DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: exiting\n"
ret ret
@ -310,7 +310,7 @@ ARP_output_request:
pushd [IP_LIST + edi] ; SenderIP pushd [IP_LIST + edi] ; SenderIP
inc [ARP_PACKETS_TX + edi] ; assume we will succeed inc [ARP_PACKETS_TX + edi] ; assume we will succeed
DEBUGF 1,"ARP_output_request: ip=%u.%u.%u.%u\n",\ DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_output_request: ip=%u.%u.%u.%u\n",\
[esp + 4]:1, [esp + 5]:1, [esp + 6]:1, [esp + 7]:1 [esp + 4]:1, [esp + 5]:1, [esp + 6]:1, [esp + 7]:1
mov ebx, [NET_DRV_LIST + edi] ; device ptr mov ebx, [NET_DRV_LIST + edi] ; device ptr
@ -344,7 +344,7 @@ ARP_output_request:
pop eax ; DestIP pop eax ; DestIP
stosd ; stosd ;
DEBUGF 1,"ARP_output_request: device=%x\n", ebx DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_output_request: device=%x\n", ebx
push edx ecx push edx ecx
call [ebx + NET_DEVICE.transmit] call [ebx + NET_DEVICE.transmit]
@ -352,7 +352,7 @@ ARP_output_request:
.exit: .exit:
add esp, 4 + 4 add esp, 4 + 4
DEBUGF 1,"ARP_output_request: failed\n" DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_output_request: failed\n"
sub eax, eax sub eax, eax
ret ret
@ -369,7 +369,7 @@ ARP_output_request:
align 4 align 4
ARP_add_entry: ARP_add_entry:
DEBUGF 1,"ARP_add_entry: " DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_add_entry: "
mov ecx, [NumARP] mov ecx, [NumARP]
cmp ecx, ARP_TABLE_SIZE ; list full ? cmp ecx, ARP_TABLE_SIZE ; list full ?
@ -400,12 +400,12 @@ ARP_add_entry:
rep movsw rep movsw
inc [NumARP] inc [NumARP]
sub edi, sizeof.ARP_entry sub edi, sizeof.ARP_entry
DEBUGF 1,"entry=%u\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "entry=%u\n", eax
ret ret
.error: .error:
DEBUGF 1,"failed\n" DEBUGF DEBUG_NETWORK_VERBOSE, "failed\n"
mov eax, -1 mov eax, -1
ret ret
@ -421,8 +421,8 @@ ARP_add_entry:
align 4 align 4
ARP_del_entry: ARP_del_entry:
DEBUGF 1,"ARP_del_entry: entry=%x entrys=%u\n", esi, [NumARP] DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_del_entry: entry=%x entrys=%u\n", esi, [NumARP]
DEBUGF 1,"ARP_del_entry: IP=%u.%u.%u.%u\n", \ DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_del_entry: IP=%u.%u.%u.%u\n", \
[esi + ARP_entry.IP]:1, [esi + ARP_entry.IP + 1]:1, [esi + ARP_entry.IP + 2]:1, [esi + ARP_entry.IP + 3]:1 [esi + ARP_entry.IP]:1, [esi + ARP_entry.IP + 1]:1, [esi + ARP_entry.IP + 2]:1, [esi + ARP_entry.IP + 3]:1
mov ecx, ARP_table + (ARP_TABLE_SIZE - 1) * sizeof.ARP_entry mov ecx, ARP_table + (ARP_TABLE_SIZE - 1) * sizeof.ARP_entry
@ -438,7 +438,7 @@ ARP_del_entry:
rep stosw rep stosw
dec [NumARP] dec [NumARP]
DEBUGF 1,"ARP_del_entry: success\n" DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_del_entry: success\n"
ret ret
@ -463,9 +463,9 @@ ARP_del_entry:
align 4 align 4
ARP_IP_to_MAC: ARP_IP_to_MAC:
DEBUGF 1,"ARP_IP_to_MAC: %u.%u", al, ah DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: %u.%u", al, ah
rol eax, 16 rol eax, 16
DEBUGF 1,".%u.%u\n", al, ah DEBUGF DEBUG_NETWORK_VERBOSE, ".%u.%u\n", al, ah
rol eax, 16 rol eax, 16
cmp eax, 0xffffffff cmp eax, 0xffffffff
@ -485,7 +485,7 @@ ARP_IP_to_MAC:
loop .scan_loop loop .scan_loop
.not_in_list: .not_in_list:
DEBUGF 1,"ARP_IP_to_MAC: preparing for ARP request\n" DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: preparing for ARP request\n"
;-------------------- ;--------------------
; Send an ARP request ; Send an ARP request
@ -535,16 +535,16 @@ else
end if end if
.valid: .valid:
DEBUGF 1,"ARP_IP_to_MAC: found MAC\n" DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: found MAC\n"
movzx eax, word[esi + ARP_entry.MAC] movzx eax, word[esi + ARP_entry.MAC]
mov ebx, dword[esi + ARP_entry.MAC + 2] mov ebx, dword[esi + ARP_entry.MAC + 2]
ret ret
.full: .full:
DEBUGF 1,"ARP_IP_to_MAC: table is full!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: table is full!\n"
add esp, 8 add esp, 8
.give_up: .give_up:
DEBUGF 1,"ARP_IP_to_MAC: entry has no valid mapping!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: entry has no valid mapping!\n"
mov eax, -1 mov eax, -1
ret ret

View File

@ -112,7 +112,7 @@ local .loop, .next
jmp .done jmp .done
.died: .died:
DEBUGF 2,"IPv4 Fragment slot timed-out!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4 Fragment slot timed-out!\n"
;;; TODO: clear all entry's of timed-out slot ;;; TODO: clear all entry's of timed-out slot
jmp .next jmp .next
@ -205,10 +205,10 @@ macro IPv4_checksum ptr {
align 4 align 4
IPv4_input: ; TODO: add IPv4 raw sockets support IPv4_input: ; TODO: add IPv4 raw sockets support
DEBUGF 2,"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 + 0]:1,[edx + IPv4_header.SourceAddress + 1]:1,\
[edx + IPv4_header.SourceAddress + 2]:1,[edx + IPv4_header.SourceAddress + 3]:1 [edx + IPv4_header.SourceAddress + 2]:1,[edx + IPv4_header.SourceAddress + 3]:1
DEBUGF 2,"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 + 0]:1,[edx + IPv4_header.DestinationAddress + 1]:1,\
[edx + IPv4_header.DestinationAddress + 2]:1,[edx + IPv4_header.DestinationAddress + 3]:1 [edx + IPv4_header.DestinationAddress + 2]:1,[edx + IPv4_header.DestinationAddress + 3]:1
@ -218,7 +218,7 @@ IPv4_input: ; TODO: add IPv4
IPv4_checksum edx IPv4_checksum edx
jnz .dump ; if checksum isn't valid then dump packet jnz .dump ; if checksum isn't valid then dump packet
DEBUGF 1,"IPv4_input: Checksum ok\n" DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Checksum ok\n"
;----------------------------------- ;-----------------------------------
; Check if destination IP is correct ; Check if destination IP is correct
@ -256,7 +256,7 @@ IPv4_input: ; TODO: add IPv4
; or it's just not meant for us.. :( ; or it's just not meant for us.. :(
DEBUGF 2,"IPv4_input: Destination address does not match!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Destination address does not match!\n"
jmp .dump jmp .dump
;------------------------ ;------------------------
@ -300,10 +300,10 @@ IPv4_input: ; TODO: add IPv4
cmp al, IP_PROTO_ICMP cmp al, IP_PROTO_ICMP
je ICMP_input je ICMP_input
DEBUGF 2,"IPv4_input: unknown protocol %u\n", al DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: unknown protocol %u\n", al
.dump: .dump:
DEBUGF 1,"IPv4_input: dumping\n" DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: dumping\n"
inc [IP_packets_dumped] ; FIXME: use correct interface inc [IP_packets_dumped] ; FIXME: use correct interface
call kernel_free call kernel_free
add esp, 4 ; pop (balance stack) add esp, 4 ; pop (balance stack)
@ -319,7 +319,7 @@ IPv4_input: ; TODO: add IPv4
xchg al, ah xchg al, ah
shl ax, 3 shl ax, 3
DEBUGF 1,"IPv4_input: fragmented packet offset=%u id=%x\n", ax, [edx + IPv4_header.Identification]:4 DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: fragmented packet offset=%u id=%x\n", ax, [edx + IPv4_header.Identification]:4
test ax, ax ; Is this the first packet of the fragment? test ax, ax ; Is this the first packet of the fragment?
jz .is_first_fragment jz .is_first_fragment
@ -328,7 +328,7 @@ IPv4_input: ; TODO: add IPv4
;------------------------------------------------------- ;-------------------------------------------------------
; We have a fragmented IP packet, but it's not the first ; We have a fragmented IP packet, but it's not the first
DEBUGF 1,"IPv4_input: Middle fragment packet received!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Middle fragment packet received!\n"
call IPv4_find_fragment_slot call IPv4_find_fragment_slot
cmp esi, -1 cmp esi, -1
@ -361,7 +361,7 @@ IPv4_input: ; TODO: add IPv4
; We have received the first fragment ; We have received the first fragment
.is_first_fragment: .is_first_fragment:
DEBUGF 1,"IPv4_input: First fragment packet received!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: First fragment packet received!\n"
; try to locate a free slot.. ; try to locate a free slot..
mov ecx, MAX_FRAGMENTS mov ecx, MAX_FRAGMENTS
mov esi, FRAGMENT_LIST mov esi, FRAGMENT_LIST
@ -395,7 +395,7 @@ IPv4_input: ; TODO: add IPv4
; We have received the last fragment ; We have received the last fragment
.is_last_fragment: .is_last_fragment:
DEBUGF 1,"IPv4_input: Last fragment packet received!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Last fragment packet received!\n"
call IPv4_find_fragment_slot call IPv4_find_fragment_slot
cmp esi, -1 cmp esi, -1
@ -411,12 +411,12 @@ IPv4_input: ; TODO: add IPv4
jne .destroy_slot_pop ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!) jne .destroy_slot_pop ; Damn, something screwed up, remove the whole slot (and free buffers too if possible!)
mov cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.TotalLength] ; Add total length mov cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.TotalLength] ; Add total length
xchg cl, ch xchg cl, ch
DEBUGF 1,"IPv4_input: Packet size=%u\n", cx DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Packet size=%u\n", cx
add ax, cx add ax, cx
movzx cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Sub Header length movzx cx, [esi + sizeof.FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Sub Header length
and cx, 0x000F and cx, 0x000F
shl cx, 2 shl cx, 2
DEBUGF 1,"IPv4_input: Header size=%u\n", cx DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Header size=%u\n", cx
sub ax, cx sub ax, cx
mov edi, esi mov edi, esi
mov esi, [esi + FRAGMENT_entry.NextPtr] mov esi, [esi + FRAGMENT_entry.NextPtr]
@ -431,9 +431,9 @@ IPv4_input: ; TODO: add IPv4
mov cx, [edx + IPv4_header.TotalLength] ; Note: This time we dont substract Header length mov cx, [edx + IPv4_header.TotalLength] ; Note: This time we dont substract Header length
xchg cl, ch xchg cl, ch
DEBUGF 1,"IPv4_input: Packet size=%u\n", cx DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Packet size=%u\n", cx
add ax, cx add ax, cx
DEBUGF 1,"IPv4_input: Total Received data size=%u\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Total Received data size=%u\n", eax
push eax push eax
mov ax, [edx + IPv4_header.FlagsAndFragmentOffset] mov ax, [edx + IPv4_header.FlagsAndFragmentOffset]
@ -441,7 +441,7 @@ IPv4_input: ; TODO: add IPv4
shl ax, 3 shl ax, 3
add cx, ax add cx, ax
pop eax pop eax
DEBUGF 1,"IPv4_input: Total Fragment size=%u\n", ecx DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Total Fragment size=%u\n", ecx
cmp ax, cx cmp ax, cx
jne .destroy_slot_pop jne .destroy_slot_pop
@ -457,7 +457,7 @@ IPv4_input: ; TODO: add IPv4
movzx ecx, [edx + sizeof.FRAGMENT_entry + IPv4_header.FlagsAndFragmentOffset] ; Calculate the fragment offset movzx ecx, [edx + sizeof.FRAGMENT_entry + IPv4_header.FlagsAndFragmentOffset] ; Calculate the fragment offset
xchg cl, ch ; intel byte order xchg cl, ch ; intel byte order
shl cx, 3 ; multiply by 8 and clear first 3 bits shl cx, 3 ; multiply by 8 and clear first 3 bits
DEBUGF 1,"IPv4_input: Fragment offset=%u\n", cx DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Fragment offset=%u\n", cx
lea edi, [eax + ecx] ; Notice that edi will be equal to eax for first fragment lea edi, [eax + ecx] ; Notice that edi will be equal to eax for first fragment
movzx ebx, [edx + sizeof.FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Find header size (in ebx) of fragment movzx ebx, [edx + sizeof.FRAGMENT_entry + IPv4_header.VersionAndIHL] ; Find header size (in ebx) of fragment
@ -504,7 +504,7 @@ IPv4_input: ; TODO: add IPv4
.destroy_slot_pop: .destroy_slot_pop:
add esp, 4 add esp, 4
.destroy_slot: .destroy_slot:
DEBUGF 1,"IPv4_input: Destroy fragment slot!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Destroy fragment slot!\n"
; TODO! ; TODO!
jmp .dump jmp .dump
@ -568,7 +568,7 @@ IPv4_find_fragment_slot:
align 4 align 4
IPv4_output: IPv4_output:
DEBUGF 1,"IPv4_output: size=%u\n", ecx DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_output: size=%u\n", ecx
cmp ecx, 65500 ; Max IPv4 packet size cmp ecx, 65500 ; Max IPv4 packet size
ja .too_large ja .too_large
@ -614,23 +614,23 @@ IPv4_output:
IPv4_checksum edi IPv4_checksum edi
add edi, sizeof.IPv4_header add edi, sizeof.IPv4_header
DEBUGF 2,"IPv4_output: success!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_output: success!\n"
ret ret
.eth_error: .eth_error:
DEBUGF 2,"IPv4_output: ethernet error\n" DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_output: ethernet error\n"
add esp, 3*4+2+6 add esp, 3*4+2+6
xor edi, edi xor edi, edi
ret ret
.arp_error: .arp_error:
DEBUGF 2,"IPv4_output: ARP error=%x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_output: ARP error=%x\n", eax
add esp, 3*4+2 add esp, 3*4+2
xor edi, edi xor edi, edi
ret ret
.too_large: .too_large:
DEBUGF 2,"IPv4_output: Packet too large!\n" DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: Packet too large!\n"
xor edi, edi xor edi, edi
ret ret
@ -713,7 +713,7 @@ IPv4_output_raw:
IPv4_checksum edi ;;;; todo: checksum for IP packet with options! IPv4_checksum edi ;;;; todo: checksum for IP packet with options!
add edi, sizeof.IPv4_header add edi, sizeof.IPv4_header
DEBUGF 2,"IPv4_output_raw: device=%x\n", ebx DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_output_raw: device=%x\n", ebx
call [ebx + NET_DEVICE.transmit] call [ebx + NET_DEVICE.transmit]
ret ret
@ -722,7 +722,7 @@ IPv4_output_raw:
.arp_error: .arp_error:
add esp, 8+4+4 add esp, 8+4+4
.too_large: .too_large:
DEBUGF 2,"IPv4_output_raw: Failed\n" DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output_raw: Failed\n"
sub edi, edi sub edi, edi
ret ret
@ -742,7 +742,7 @@ IPv4_output_raw:
align 4 align 4
IPv4_fragment: IPv4_fragment:
DEBUGF 1,"IPv4_fragment\n" DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_fragment\n"
and ecx, not 111b ; align 4 and ecx, not 111b ; align 4
@ -770,7 +770,7 @@ IPv4_fragment:
push dword 0 ; offset push dword 0 ; offset
.new_fragment: .new_fragment:
DEBUGF 1,"Ipv4_fragment: new fragment" DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: new fragment"
mov eax, [esp + 3*4] mov eax, [esp + 3*4]
@ -792,7 +792,7 @@ IPv4_fragment:
add esi, [esp] ; offset add esi, [esp] ; offset
mov ecx, [esp + 1*4] mov ecx, [esp + 1*4]
DEBUGF 1,"IPv4_fragment: copying %u bytes\n", ecx DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_fragment: copying %u bytes\n", ecx
rep movsb rep movsb
; now, correct header ; now, correct header
@ -829,7 +829,7 @@ IPv4_fragment:
sub ecx, [esp+2*4] ; ptr to ip header sub ecx, [esp+2*4] ; ptr to ip header
add ecx, [esp] ; offset add ecx, [esp] ; offset
DEBUGF 1,"Ipv4_fragment: %u bytes remaining\n", ecx DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: %u bytes remaining\n", ecx
cmp ecx, [esp+1*4] cmp ecx, [esp+1*4]
jae .new_fragment jae .new_fragment
@ -838,11 +838,11 @@ IPv4_fragment:
jmp .new_fragment jmp .new_fragment
.err: .err:
DEBUGF 1,"Ipv4_fragment: failed\n" DEBUGF DEBUG_NETWORK_ERROR, "Ipv4_fragment: failed\n"
.done: .done:
add esp, 12 + 4 + 6 add esp, 12 + 4 + 6
.err2: .err2:
DEBUGF 1,"Ipv4_fragment: dumping\n" DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: dumping\n"
call kernel_free call kernel_free
add esp, 4 add esp, 4
@ -886,7 +886,7 @@ IPv4_route:
mov eax, [GATEWAY_LIST] mov eax, [GATEWAY_LIST]
.found_it: .found_it:
DEBUGF 1,"IPv4_dest_to_dev: %u\n", edi DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_route: %u\n", edi
ret ret
.broadcast: .broadcast:

View File

@ -83,7 +83,7 @@ macro IPv6_init {
align 4 align 4
IPv6_input: IPv6_input:
DEBUGF 2,"IPv6_input from: %x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x\n",\ DEBUGF DEBUG_NETWORK_VERBOSE, "IPv6_input from: %x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x\n",\
[edx + IPv6_header.SourceAddress + 0]:2,[edx + IPv6_header.SourceAddress + 1]:2,\ [edx + IPv6_header.SourceAddress + 0]:2,[edx + IPv6_header.SourceAddress + 1]:2,\
[edx + IPv6_header.SourceAddress + 2]:2,[edx + IPv6_header.SourceAddress + 3]:2,\ [edx + IPv6_header.SourceAddress + 2]:2,[edx + IPv6_header.SourceAddress + 3]:2,\
[edx + IPv6_header.SourceAddress + 4]:2,[edx + IPv6_header.SourceAddress + 5]:2,\ [edx + IPv6_header.SourceAddress + 4]:2,[edx + IPv6_header.SourceAddress + 5]:2,\
@ -93,7 +93,7 @@ IPv6_input:
[edx + IPv6_header.SourceAddress + 12]:2,[edx + IPv6_header.SourceAddress + 13]:2,\ [edx + IPv6_header.SourceAddress + 12]:2,[edx + IPv6_header.SourceAddress + 13]:2,\
[edx + IPv6_header.SourceAddress + 14]:2,[edx + IPv6_header.SourceAddress + 15]:2 [edx + IPv6_header.SourceAddress + 14]:2,[edx + IPv6_header.SourceAddress + 15]:2
DEBUGF 1,"IPv6_input to: %x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x\n",\ DEBUGF DEBUG_NETWORK_VERBOSE, "IPv6_input to: %x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x\n",\
[edx + IPv6_header.DestinationAddress + 0]:2,[edx + IPv6_header.DestinationAddress + 1]:2,\ [edx + IPv6_header.DestinationAddress + 0]:2,[edx + IPv6_header.DestinationAddress + 1]:2,\
[edx + IPv6_header.DestinationAddress + 2]:2,[edx + IPv6_header.DestinationAddress + 3]:2,\ [edx + IPv6_header.DestinationAddress + 2]:2,[edx + IPv6_header.DestinationAddress + 3]:2,\
[edx + IPv6_header.DestinationAddress + 4]:2,[edx + IPv6_header.DestinationAddress + 5]:2,\ [edx + IPv6_header.DestinationAddress + 4]:2,[edx + IPv6_header.DestinationAddress + 5]:2,\
@ -143,10 +143,10 @@ IPv6_input:
; cmp al, 58 ; cmp al, 58
; je ICMP6_input ; je ICMP6_input
DEBUGF 2,"IPv6_input - unknown protocol: %u\n", al DEBUGF DEBUG_NETWORK_VERBOSE, "IPv6_input - unknown protocol: %u\n", al
.dump: .dump:
DEBUGF 1,"IPv6_input - dumping\n" DEBUGF DEBUG_NETWORK_VERBOSE, "IPv6_input - dumping\n"
call kernel_free call kernel_free
add esp, 4 add esp, 4
@ -166,7 +166,7 @@ IPv6_input:
; Hop-by-Hop ; Hop-by-Hop
.hop_by_hop: .hop_by_hop:
DEBUGF 1,"IPv6_input - hop by hop\n" DEBUGF DEBUG_NETWORK_VERBOSE, "IPv6_input - hop by hop\n"
pushw [esi] ; 8 bit identifier for option type pushw [esi] ; 8 bit identifier for option type
movzx eax, byte[esi + 1] ; Hdr Ext Len movzx eax, byte[esi + 1] ; Hdr Ext Len
inc eax ; first 8 octets not counted inc eax ; first 8 octets not counted
@ -195,7 +195,7 @@ IPv6_input:
.pad_n: .pad_n:
movzx eax, byte[esi + 1] movzx eax, byte[esi + 1]
DEBUGF 1,"IPv6_input - pad %u\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "IPv6_input - pad %u\n", eax
inc esi inc esi
inc esi inc esi
add esi, eax add esi, eax
@ -203,7 +203,7 @@ IPv6_input:
jmp .hop_by_hop jmp .hop_by_hop
.pad_1: .pad_1:
DEBUGF 1,"IPv6_input - pad 1\n" DEBUGF DEBUG_NETWORK_VERBOSE, "IPv6_input - pad 1\n"
inc esi inc esi
dec ecx dec ecx
jmp .hop_by_hop jmp .hop_by_hop
@ -211,11 +211,11 @@ IPv6_input:
.dest_opts: .dest_opts:
DEBUGF 1,"IPv6_input - dest opts\n" DEBUGF DEBUG_NETWORK_VERBOSE, "IPv6_input - dest opts\n"
jmp .nextheader jmp .nextheader
.routing: .routing:
DEBUGF 1,"IPv6_input - routing\n" DEBUGF DEBUG_NETWORK_VERBOSE, "IPv6_input - routing\n"
pushw [esi] ; 8 bit identifier for option type pushw [esi] ; 8 bit identifier for option type
movzx eax, byte[esi + 1] ; Hdr Ext Len movzx eax, byte[esi + 1] ; Hdr Ext Len
inc eax ; first 8 octets not counted inc eax ; first 8 octets not counted
@ -238,7 +238,7 @@ IPv6_input:
jmp .nextheader jmp .nextheader
.fragment: .fragment:
DEBUGF 1,"IPv6_input - fragment\n" DEBUGF DEBUG_NETWORK_VERBOSE, "IPv6_input - fragment\n"
jmp .nextheader jmp .nextheader

View File

@ -59,7 +59,7 @@ macro PPPoE_init {
align 4 align 4
PPPoE_discovery_input: PPPoE_discovery_input:
DEBUGF 2,"PPPoE_discovery_input\n" DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_discovery_input\n"
; First, find open PPPoE socket ; First, find open PPPoE socket
@ -84,7 +84,7 @@ PPPoE_discovery_input:
jmp SOCKET_input jmp SOCKET_input
.dump: .dump:
DEBUGF 1,'PPPoE_discovery_input: dumping\n' DEBUGF DEBUG_NETWORK_VERBOSE, 'PPPoE_discovery_input: dumping\n'
call kernel_free call kernel_free
add esp, 4 add esp, 4
ret ret
@ -103,7 +103,7 @@ PPPoE_discovery_input:
align 4 align 4
PPPoE_discovery_output: PPPoE_discovery_output:
DEBUGF 2,"PPPoE_discovery_output: socket=%x buffer=%x size=%d\n", eax, esi, ecx DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_discovery_output: socket=%x buffer=%x size=%d\n", eax, esi, ecx
; RFC2516: An entire PADI packet (including the PPPoE header) MUST NOT ; RFC2516: An entire PADI packet (including the PPPoE header) MUST NOT
; exceed 1484 octets. ; exceed 1484 octets.
@ -123,7 +123,7 @@ PPPoE_discovery_output:
cmp [ebx + NET_DEVICE.type], NET_TYPE_ETH cmp [ebx + NET_DEVICE.type], NET_TYPE_ETH
jne .bad jne .bad
DEBUGF 2,"PPPoE_discovery_output: device=%x\n", ebx DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_discovery_output: device=%x\n", ebx
; Create packet. ; Create packet.
push ecx esi push ecx esi
@ -193,7 +193,7 @@ PPPoE_session_input:
xchg cl, ch xchg cl, ch
mov ax, [edx + PPPoE_frame.SessionID] mov ax, [edx + PPPoE_frame.SessionID]
DEBUGF 2,"PPPoE_input: session ID=%x, length=%u\n", ax, cx DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_input: session ID=%x, length=%u\n", ax, cx
cmp ax, [PPPoE_SID] cmp ax, [PPPoE_SID]
jne .dump jne .dump
@ -207,10 +207,10 @@ PPPoE_session_input:
; je IPv6_input ; je IPv6_input
jmp PPPoE_discovery_input ; Send LCP,CHAP,CBCP,... packets to the PPP dialer jmp PPPoE_discovery_input ; Send LCP,CHAP,CBCP,... packets to the PPP dialer
DEBUGF 2,"PPPoE_input: Unknown protocol=%x\n", ax DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_input: Unknown protocol=%x\n", ax
.dump: .dump:
DEBUGF 2,"PPPoE_input: dumping\n" DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_input: dumping\n"
call kernel_free call kernel_free
add esp, 4 add esp, 4
ret ret
@ -238,7 +238,7 @@ PPPoE_session_input:
align 4 align 4
PPPoE_output: PPPoE_output:
DEBUGF 1,"PPPoE_output: size=%u device=%x\n", ecx, ebx DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_output: size=%u device=%x\n", ecx, ebx
pushw di pushw di
pushw [PPPoE_SID] pushw [PPPoE_SID]
@ -263,7 +263,7 @@ PPPoE_output:
sub ecx, 2 sub ecx, 2
add edi, PPPoE_frame.Payload + 2 add edi, PPPoE_frame.Payload + 2
DEBUGF 1,"PPPoE_output: success!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_output: success!\n"
ret ret
@ -276,7 +276,7 @@ PPPoE_output:
PPPoE_start_connection: PPPoE_start_connection:
DEBUGF 2,"PPPoE_start_connection: %x\n", cx DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_start_connection: %x\n", cx
cmp [PPPoE_SID], 0 cmp [PPPoE_SID], 0
jne .fail jne .fail
@ -296,7 +296,7 @@ PPPoE_start_connection:
align 4 align 4
PPPoE_stop_connection: PPPoE_stop_connection:
DEBUGF 2,"PPPoE_stop_connection\n" DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_stop_connection\n"
xor eax, eax xor eax, eax
mov [PPPoE_SID], ax mov [PPPoE_SID], ax

View File

@ -1,557 +0,0 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ARP.INC ;;
;; ;;
;; Address Resolution Protocol ;;
;; ;;
;; This file contains the following: ;;
;; arp_table_manager - Manages an ARPTable ;;
;; arp_request - Sends an ARP request on the ethernet ;;
;; arp_handler - Called when an ARP packet is received ;;
;; ;;
;; Changes history: ;;
;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net ;;
;; 11.11.2006 - [Johnny_B] and [smb] ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision$
ARP_NO_ENTRY equ 0
ARP_VALID_MAPPING equ 1
ARP_AWAITING_RESPONSE equ 2
ARP_RESPONSE_TIMEOUT equ 3
struc ARP_ENTRY ;=14 bytes
{ .IP dd ? ;+00
.MAC dp ? ;+04
.Status dw ? ;+10
.TTL dw ? ;+12 : ( in seconds )
}
virtual at 0
ARP_ENTRY ARP_ENTRY
end virtual
; The TTL field is decremented every second, and is deleted when it
; reaches 0. It is refreshed every time a packet is received
; If the TTL field is 0xFFFF it is a static entry and is never deleted
; The status field can be the following values:
; 0x0000 entry not used
; 0x0001 entry holds a valid mapping
; 0x0002 entry contains an IP address, awaiting ARP response
; 0x0003 No response received to ARP request.
; The last status value is provided to allow the network layer to delete
; a packet that is queued awaiting an ARP response
; The follow is the ARP Table.
; This table must be manually updated and the kernel recompilied if
; changes are made to it.
; Empty entries are filled with zeros
ARP_ENTRY_SIZE equ 14 ; Number of bytes per entry
ARP_TABLE_SIZE equ 20 ; Size of table
ARP_TABLE_ENTRIES equ 0 ; Number of static entries in the table
;TO ADD A STATIC ENTRY, DONT FORGET, PUT "ARPTable" from "uglobal" to "iglobal"!!!
;AND ALSO - IP and MAC have net byte-order, BUT STATUS AND TTL HAVE A MIRROR BYTE-ORDER!!!
uglobal
ARPTable:
;example, static entry -> db 11,22,33,44, 0x11,0x22,0x33,0x44,0x55,0x66, 0x01,0x00, 0xFF,0xFF
times ( ARP_TABLE_SIZE - ARP_TABLE_ENTRIES ) * ARP_ENTRY_SIZE db 0
endg
iglobal
NumARP:
dd ARP_TABLE_ENTRIES
ARPTable_ptr dd ARPTable ;pointer to ARPTable
endg
ARP_REQ_OPCODE equ 0x0100 ;request
ARP_REP_OPCODE equ 0x0200 ;reply
struc ARP_PACKET
{ .HardwareType dw ? ;+00
.ProtocolType dw ? ;+02
.HardwareSize db ? ;+04
.ProtocolSize db ? ;+05
.Opcode dw ? ;+06
.SenderMAC dp ? ;+08
.SenderIP dd ? ;+14
.TargetMAC dp ? ;+18
.TargetIP dd ? ;+24
}
virtual at 0
ARP_PACKET ARP_PACKET
end virtual
;***************************************************************************
; Function
; arp_table_manager [by Johnny_B]
;
; Description
; Does a most required operations with ARP-table
; IN:
; Operation: see Opcode's constants below
; Index: Index of entry in the ARP-table
; Extra: Extra parameter for some Opcodes
; OUT:
; EAX = Returned value depends on opcodes, more detailed see below
;
;***************************************************************************
;Opcode's constants
ARP_TABLE_ADD equ 1
ARP_TABLE_DEL equ 2
ARP_TABLE_GET equ 3
ARP_TABLE_GET_ENTRIES_NUMBER equ 4
ARP_TABLE_IP_TO_MAC equ 5
ARP_TABLE_TIMER equ 6
;Index's constants
EXTRA_IS_ARP_PACKET_PTR equ 0 ;if Extra contain pointer to ARP_PACKET
EXTRA_IS_ARP_ENTRY_PTR equ -1 ;if Extra contain pointer to ARP_ENTRY
align 4
proc arp_table_manager stdcall uses ebx esi edi ecx edx,\
Opcode:DWORD,Index:DWORD,Extra:DWORD
mov ebx, dword[ARPTable_ptr];ARPTable base
mov ecx, dword[NumARP] ;ARP-entries counter
mov eax, dword[Opcode]
cmp eax, ARP_TABLE_TIMER
je .timer
cmp eax, ARP_TABLE_ADD
je .add
cmp eax, ARP_TABLE_DEL
je .del
cmp eax, ARP_TABLE_GET
je .get
cmp eax, ARP_TABLE_IP_TO_MAC
je .ip_to_mac
cmp eax, ARP_TABLE_GET_ENTRIES_NUMBER
je .get_entries_number
jmp .exit ;if unknown opcode
;;BEGIN TIMER
;;Description: it must be callback every second. It is responsible for removing expired routes.
;;IN: Operation: ARP_TABLE_TIMER
;; Index: must be zero
;; Extra: must be zero
;;OUT:
;; EAX=not defined
;;
.timer:
test ecx, ecx
jz .exit;if NumARP=0 nothing to do
sub ecx, ARP_TABLE_ENTRIES;ecx=dynamic entries number
jz .exit;if NumARP=number of static entries then exit
add ebx, ARP_TABLE_ENTRIES*ARP_ENTRY_SIZE;ebx=dynamic entries base
.timer_loop:
movsx esi, word [ebx + ARP_ENTRY.TTL]
cmp esi, 0xFFFFFFFF
je .timer_loop_end;if TTL==0xFFFF then it's static entry
test esi, esi
jnz .timer_loop_end_with_dec;if TTL!=0
; Ok, TTL is 0
;if Status==AWAITING_RESPONSE and TTL==0
;then we have to change it to ARP_RESPONSE_TIMEOUT
cmp word [ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
jne @f
mov word [ebx + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT
mov word [ebx + ARP_ENTRY.TTL], word 0x000A;10 sec
jmp .timer_loop_end
@@:
;if TTL==0 and Status==VALID_MAPPING, we have to delete it
;if TTL==0 and Status==RESPONSE_TIMEOUT, delete too
mov esi, dword[NumARP]
sub esi, ecx ;esi=index of entry, will be deleted
stdcall arp_table_manager, ARP_TABLE_DEL, esi, 0;opcode,index,extra
jmp .timer_loop_end
.timer_loop_end_with_dec:
dec word [ebx + ARP_ENTRY.TTL];decrease TTL
.timer_loop_end:
add ebx, ARP_ENTRY_SIZE
loop .timer_loop
jmp .exit
;;END TIMER
;;BEGIN ADD
;;Description: it adds an entry in the table. If ARP-table already
;; contains same IP, it will be updated.
;;IN: Operation: ARP_TABLE_ADD
;; Index: specifies what contains Extra-parameter
;; Extra: if Index==EXTRA_IS_ARP_PACKET_PTR,
;; then Extra contains pointer to ARP_PACKET,
;; otherwise Extra contains pointer to ARP_ENTRY
;;OUT:
;; EAX=index of entry, that has been added
;;
.add:
sub esp, ARP_ENTRY_SIZE;Allocate ARP_ENTRY_SIZE byte in stack
mov esi, [Extra];pointer
mov edi, [Index];opcode
cmp edi, EXTRA_IS_ARP_PACKET_PTR
je .arp_packet_to_entry;if Extra contain ptr to ARP_PACKET and we have to form arp-entry
;else it contain ptr to arp-entry
cld
; esi already has been loaded
mov edi, esp ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add)
mov ecx, ARP_ENTRY_SIZE/2;ARP_ENTRY_SIZE must be even number!!!
rep movsw ;copy
jmp .search
.arp_packet_to_entry:
mov edx, dword[esi + ARP_PACKET.SenderIP];esi=base of ARP_PACKET
mov [esp + ARP_ENTRY.IP], edx
cld
lea esi, [esi + ARP_PACKET.SenderMAC]
lea edi, [esp + ARP_ENTRY.MAC]
movsd
movsw
mov word[esp + ARP_ENTRY.Status], ARP_VALID_MAPPING; specify the type - a valid entry
mov word[esp + ARP_ENTRY.TTL], 0x0E10; = 1 hour
.search:
mov edx, dword[esp + ARP_ENTRY.IP];edx=IP-address, which we'll search
mov ecx, dword[NumARP] ;ecx=ARP-entries counter
jecxz .add_to_end ;if ARP-entries number == 0
imul eax, ecx, ARP_ENTRY_SIZE ;eax=current table size(in bytes)
@@:
sub eax, ARP_ENTRY_SIZE
cmp dword[ebx + eax + ARP_ENTRY.IP], edx
loopnz @b
jz .replace ; found, replace existing entry, ptr to it is in eax
.add_to_end:
;else add to end
or eax, -1;set eax=0xFFFFFFFF if adding is impossible
mov ecx, dword[NumARP]
cmp ecx, ARP_TABLE_SIZE
je .add_exit;if arp-entries number is equal to arp-table maxsize
imul eax, dword[NumARP], ARP_ENTRY_SIZE;eax=ptr to end of ARPTable
inc dword [NumARP];increase ARP-entries counter
.replace:
cld
mov esi, esp ;esp=base of ARP-entry, that will be added
lea edi, [ebx + eax] ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add)
mov ecx, ARP_ENTRY_SIZE/2;ARP_ENTRY_SIZE must be even number!!!
rep movsw
mov ecx, ARP_ENTRY_SIZE
xor edx, edx;"div" takes operand from EDX:EAX
div ecx ;eax=index of entry, which has been added
.add_exit:
add esp, ARP_ENTRY_SIZE;free stack
jmp .exit
;;END ADD
;;BEGIN DEL
;;Description: it deletes an entry in the table.
;;IN: Operation: ARP_TABLE_DEL
;; Index: index of entry, that should be deleted
;; Extra: must be zero
;;OUT:
;; EAX=not defined
;;
.del:
mov esi, [Index]
imul esi, ARP_ENTRY_SIZE
mov ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY_SIZE
sub ecx, esi
lea edi, [ebx + esi] ;edi=ptr to entry that should be deleted
lea esi, [edi + ARP_ENTRY_SIZE];esi=ptr to next entry
shr ecx, 1 ;ecx/2 => ARP_ENTRY_SIZE MUST BE EVEN NUMBER!
cld
rep movsw
dec dword[NumARP];decrease arp-entries counter
jmp .exit
;;END DEL
;;BEGIN GET
;;Description: it reads an entry of table into buffer.
;;IN: Operation: ARP_TABLE_GET
;; Index: index of entry, that should be read
;; Extra: pointer to buffer for reading(size must be equal to ARP_ENTRY_SIZE)
;;OUT:
;; EAX=not defined
;;
.get:
mov esi, [Index]
imul esi, ARP_ENTRY_SIZE;esi=ptr to required ARP_ENTRY
mov edi, [Extra] ;edi=buffer for reading
mov ecx, ARP_ENTRY_SIZE/2; must be even number!!!
cld
rep movsw
jmp .exit
;;END GET
;;BEGIN IP_TO_MAC
;;Description: it gets an IP from Index, scans each entry in the table and writes
;; MAC, that relates to specified IP, into buffer specified in Extra.
;; And if it cannot find an IP-address in the table, it does an ARP-request of that.
;;IN: Operation: ARP_TABLE_IP_TO_MAC
;; Index: IP that should be transformed into MAC
;; Extra: pointer to buffer where will be written the MAC-address.
;;OUT:
;; EAX=ARP table entry status code.
;; If EAX==ARP_NO_ENTRY, IP isn't found in the table and we have sent the request.
;; If EAX==ARP_AWAITING_RESPONSE, we wait the response from remote system.
;; If EAX==ARP_RESPONSE_TIMEOUT, remote system not responds too long.
;; If EAX==ARP_VALID_MAPPING, all is ok, we've got a true MAC.
;;
;; If MAC will equal to a zero, in the buffer. It means, that IP-address was not yet
;; resolved, or that doesn't exist. I recommend you, to do at most 3-5 calls of this
;; function with 1sec delay. sure, only if it not return a valid MAC after a first call.
;;
.ip_to_mac:
xor eax, eax
mov edi, dword[Extra]
cld
stosd
stosw
; first, check destination IP to see if it is on 'this' network.
; The test is:
; if ( destIP & subnet_mask == stack_ip & subnet_mask )
; destination is local
; else
; destination is remote, so pass to gateway
mov eax, [Index] ;eax=required IP
mov esi, eax
and esi, [subnet_mask]
mov ecx, [stack_ip]
and ecx, [subnet_mask]
cmp esi, ecx
je @f ;if we and target IP are located in the same network
mov eax, [gateway_ip]
mov [Index], eax
@@:
cmp dword[NumARP], 0
je .ip_to_mac_send_request;if ARP-table not contain an entries, we have to request IP.
;EAX will be containing a zero, it's equal to ARP_NO_ENTRY
mov ecx, dword[NumARP]
imul esi, ecx, ARP_ENTRY_SIZE;esi=current ARP-table size
@@:
sub esi, ARP_ENTRY_SIZE
cmp [ebx + esi], eax ; ebx=ARPTable base
loopnz @b ; Return back if non match
jnz .ip_to_mac_send_request; and request IP->MAC if none found in the table
; Return the entry status in eax
movzx eax, word[ebx + esi + ARP_ENTRY.Status]
; esi holds index
cld
lea esi, [ebx + esi + ARP_ENTRY.MAC]
mov edi, [Extra];edi=ptr to buffer for write MAC
movsd
movsw
jmp .exit
.ip_to_mac_send_request:
stdcall arp_request, [Index], stack_ip, node_addr;TargetIP,SenderIP_ptr,SenderMAC_ptr
mov eax, ARP_NO_ENTRY
jmp .exit
;;END IP_TO_MAC
;;BEGIN GET_ENTRIES_NUMBER
;;Description: returns an ARP-entries number in the ARPTable
;;IN: Operation: ARP_TABLE_GET_ENTRIES_NUMBER
;; Index: must be zero
;; Extra: must be zero
;;OUT:
;; EAX=ARP-entries number in the ARPTable
.get_entries_number:
mov eax, dword[NumARP]
jmp .exit
;;END GET_ENTRIES_NUMBER
.exit:
ret
endp
;***************************************************************************
; Function
; arp_handler
;
; Description
; Called when an ARP packet is received on the ethernet
; Header + Data is in Ether_buffer[]
; It looks to see if the packet is a request to resolve this Hosts
; IP address. If it is, send the ARP reply packet.
; This Hosts IP address is in dword [stack_ip] ( in network format )
; This Hosts MAC address is in node_addr[6]
; All registers may be destroyed
;
;***************************************************************************
arp_handler:
; Is this a REQUEST?
; Is this a request for My Host IP
; Yes - So construct a response message.
; Send this message to the ethernet card for transmission
stdcall arp_table_manager, ARP_TABLE_ADD, EXTRA_IS_ARP_PACKET_PTR, ETH_FRAME.Data + ARP_PACKET
inc dword[arp_rx_count];increase ARP-packets counter
cmp word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REQ_OPCODE; Is this a request packet?
jne .exit ; No - so exit
mov eax, [stack_ip]
cmp eax, dword[ETH_FRAME.Data + ARP_PACKET.TargetIP] ; Is it looking for my IP address?
jne .exit ; No - so quit now
; OK, it is a request for my MAC address. Build the frame and send it
; We can reuse the packet.
mov word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REP_OPCODE
cld
mov esi, ETH_FRAME.Data + ARP_PACKET.SenderMAC
mov edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC
movsd
movsw
mov esi, ETH_FRAME.Data + ARP_PACKET.SenderIP
mov edi, ETH_FRAME.Data + ARP_PACKET.TargetIP
movsd
mov esi, node_addr
mov edi, ETH_FRAME.Data + ARP_PACKET.SenderMAC
movsd
movsw
mov esi, stack_ip
mov edi, ETH_FRAME.Data + ARP_PACKET.SenderIP
movsd
; Now, send it!
mov edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC;ptr to destination MAC address
mov bx, ETHER_ARP ;type of protocol
mov ecx, 28 ;data size
mov esi, ETH_FRAME.Data + ARP_PACKET ;ptr to data
push ebp
call dword [drvr_transmit] ;transmit packet
pop ebp
.exit:
ret
;***************************************************************************
; Function
; arp_request [by Johnny_B]
;
; Description
; Sends an ARP request on the ethernet
; IN:
; TargetIP : requested IP address
; SenderIP_ptr : POINTER to sender's IP address(our system's address)
; SenderMAC_ptr : POINTER to sender's MAC address(our system's address)
; OUT:
; EAX=0 (if all is ok), otherwise EAX is not defined
;
; EBX,ESI,EDI will be saved
;
;***************************************************************************
proc arp_request stdcall uses ebx esi edi,\
TargetIP:DWORD, SenderIP_ptr:DWORD, SenderMAC_ptr:DWORD
inc dword[arp_tx_count]; increase counter
sub esp, 28; allocate memory for ARP_PACKET
mov word[esp + ARP_PACKET.HardwareType], 0x0100;Ethernet
mov word[esp + ARP_PACKET.ProtocolType], 0x0008;IP
mov byte[esp + ARP_PACKET.HardwareSize], 0x06;MAC-addr length
mov byte[esp + ARP_PACKET.ProtocolSize], 0x04;IP-addr length
mov word[esp + ARP_PACKET.Opcode], 0x0100 ;Request
cld
mov esi, [SenderMAC_ptr]
lea edi, [esp + ARP_PACKET.SenderMAC] ;Our MAC-addr
movsd
movsw
mov esi, [SenderIP_ptr]
lea edi, [esp + ARP_PACKET.SenderIP] ;Our IP-addr
movsd
xor eax, eax
lea edi, [esp + ARP_PACKET.TargetMAC] ;Required MAC-addr(zeroed)
stosd
stosw
mov esi, dword[TargetIP]
mov dword[esp + ARP_PACKET.TargetIP], esi;Required IP-addr(we get it as function parameter)
; Now, send it!
mov edi, broadcast_add ; Pointer to 48 bit destination address
mov bx, ETHER_ARP ; Type of packet
mov ecx, 28 ; size of packet
lea esi, [esp + ARP_PACKET]; pointer to packet data
push ebp
call dword [drvr_transmit]; Call the drivers transmit function
pop ebp
add esp, 28; free memory, allocated before for ARP_PACKET
; Add an entry in the ARP table, awaiting response
sub esp, ARP_ENTRY_SIZE;allocate memory for ARP-entry
mov esi, dword[TargetIP]
mov dword[esp + ARP_ENTRY.IP], esi
lea edi, [esp + ARP_ENTRY.MAC]
xor eax, eax
stosd
stosw
mov word[esp + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
mov word[esp + ARP_ENTRY.TTL], 0x000A; 10 seconds
stdcall arp_table_manager, ARP_TABLE_ADD, EXTRA_IS_ARP_ENTRY_PTR, esp
add esp, ARP_ENTRY_SIZE; free memory
.exit:
ret
endp

File diff suppressed because it is too large Load Diff

View File

@ -1,794 +0,0 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ;;
;; I8255X.INC ;;
;; ;;
;; Ethernet driver for Menuet OS ;;
;; ;;
;; Version 0.3 11 August 2003 ;;
;; ;;
;; This driver is based on the eepro100 driver from ;;
;; the etherboot 5.0.6 project. The copyright statement is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; remaining parts Copyright 2002 Mike Hibbett, ;;
;; mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision$
;********************************************************************
; Interface
; I8255x_reset
; I8255x_probe
; I8255x_poll
; I8255x_transmit
;
; These functions are referenced in ethernet.inc
;
;********************************************************************
rxfd_status equ eth_data_start
rxfd_command equ eth_data_start + 2
rxfd_link equ eth_data_start + 4
rxfd_rx_buf_addr equ eth_data_start + 8
rxfd_count equ eth_data_start + 12
rxfd_size equ eth_data_start + 14
rxfd_packet equ eth_data_start + 16
uglobal
eeprom_data:
times 16 dd 0
align 4
lstats:
tx_good_frames:
dd 0
tx_coll16_errs:
dd 0
tx_late_colls:
dd 0
tx_underruns:
dd 0
tx_lost_carrier:
dd 0
tx_deferred:
dd 0
tx_one_colls:
dd 0
tx_multi_colls:
dd 0
tx_total_colls:
dd 0
rx_good_frames:
dd 0
rx_crc_errs:
dd 0
rx_align_errs:
dd 0
rx_resource_errs:
dd 0
rx_overrun_errs:
dd 0
rx_colls_errs:
dd 0
rx_runt_errs:
dd 0
done_marker:
dd 0
align 4
confcmd:
confcmd_status:
dw 0
confcmd_command:
dw 0
confcmd_link:
dd 0
endg
iglobal
confcmd_data:
db 22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1
db 0, 0x2e, 0, 0x60, 0, 0xf2, 0x48, 0, 0x40, 0xf2
db 0x80, 0x3f, 0x05
endg
uglobal
align 4
txfd:
txfd_status:
dw 0
txfd_command:
dw 0
txfd_link:
dd 0
txfd_tx_desc_addr:
dd 0
txfd_count:
dd 0
txfd_tx_buf_addr0:
dd 0
txfd_tx_buf_size0:
dd 0
txfd_tx_buf_addr1:
dd 0
txfd_tx_buf_size1:
dd 0
align 4
hdr:
hdr_dst_addr:
times 6 db 0
hdr_src_addr:
times 6 db 0
hdr_type:
dw 0
endg
;***************************************************************************
; Function
; wait_for_cmd_done
;
; Description
; waits for the hardware to complete a command
; port address in edx
;
; al destroyed
;***************************************************************************
wait_for_cmd_done:
in al, dx
cmp al, 0
jne wait_for_cmd_done
ret
;***************************************************************************
; Function
; mdio_read
;
; Description
; This probably reads a register in the "physical media interface chip"
; Phy_id in ebx
; location in ecx
;
; Data returned in eax
;
;***************************************************************************
mdio_read:
mov edx, [io_addr]
add edx, 16 ; SCBCtrlMDI
mov eax, 0x08000000
shl ecx, 16
or eax, ecx
shl ebx, 21
or eax, ebx
out dx, eax
mrlp:
call delay_us
in eax, dx
mov ecx, eax
and ecx, 0x10000000
jz mrlp
and eax, 0xffff
ret
;***************************************************************************
; Function
; mdio_write
;
; Description
; This probably writes a register in the "physical media interface chip"
; Phy_id in ebx
; location in ecx
; data in edx
; Data returned in eax
;
;***************************************************************************
mdio_write:
mov eax, 0x04000000
shl ecx, 16
or eax, ecx
shl ebx, 21
or eax, ebx
or eax, edx
mov edx, [io_addr]
add edx, 16 ; SCBCtrlMDI
out dx, eax
mwlp:
call delay_us
in eax, dx
mov ecx, eax
and ecx, 0x10000000
jz mwlp
and eax, 0xffff
ret
;/***********************************************************************/
;/* I82557 related defines */
;/***********************************************************************/
; Serial EEPROM section.
; A "bit" grungy, but we work our way through bit-by-bit :->.
; EEPROM_Ctrl bits.
EE_SHIFT_CLK equ 0x01 ; EEPROM shift clock.
EE_CS equ 0x02 ; EEPROM chip select.
EE_DATA_WRITE equ 0x04 ; EEPROM chip data in.
EE_DATA_READ equ 0x08 ; EEPROM chip data out.
EE_WRITE_0 equ 0x4802
EE_WRITE_1 equ 0x4806
EE_ENB equ 0x4802
; The EEPROM commands include the alway-set leading bit.
EE_READ_CMD equ 6
; The SCB accepts the following controls for the Tx and Rx units:
CU_START equ 0x0010
CU_RESUME equ 0x0020
CU_STATSADDR equ 0x0040
CU_SHOWSTATS equ 0x0050 ; Dump statistics counters.
CU_CMD_BASE equ 0x0060 ; Base address to add to add CU commands.
CU_DUMPSTATS equ 0x0070 ; Dump then reset stats counters.
RX_START equ 0x0001
RX_RESUME equ 0x0002
RX_ABORT equ 0x0004
RX_ADDR_LOAD equ 0x0006
RX_RESUMENR equ 0x0007
INT_MASK equ 0x0100
DRVR_INT equ 0x0200 ; Driver generated interrupt.
;***************************************************************************
; Function
; do_eeprom_cmd
;
; Description
; writes a cmd to the ethernet cards eeprom, by bit bashing
; cmd in ebx
; cmd length in ecx
; return in eax
;***************************************************************************
do_eeprom_cmd:
mov edx, [io_addr]; We only require the value in dx
add dx, 14 ; the value SCBeeprom
mov ax, EE_ENB
out dx, ax
call delay_us
mov ax, 0x4803 ; EE_ENB | EE_SHIFT_CLK
out dx, ax
call delay_us
; dx holds ee_addr
; ecx holds count
; eax holds cmd
xor edi, edi ; this will be the receive data
dec_001:
mov esi, 1
dec ecx
shl esi, cl
inc ecx
and esi, ebx
mov eax, EE_WRITE_0; I am assuming this doesnt affect the flags..
cmp esi, 0
jz dec_002
mov eax, EE_WRITE_1
dec_002:
out dx, ax
call delay_us
or ax, EE_SHIFT_CLK
out dx, ax
call delay_us
shl edi, 1
in ax, dx
and ax, EE_DATA_READ
cmp ax, 0
jz dec_003
inc edi
dec_003:
loop dec_001
mov ax, EE_ENB
out dx, ax
call delay_us
mov ax, 0x4800
out dx, ax
call delay_us
mov eax, edi
ret
;***************************************************************************
; Function
; I8255x_probe
; Description
; Searches for an ethernet card, enables it and clears the rx buffer
; If a card was found, it enables the ethernet -> TCPIP link
;
;***************************************************************************
I8255x_probe:
DEBUGF 1," K : Probing i8255x device \n"
mov eax, [io_addr]
mov ebx, [pci_bus]
mov ecx, [pci_dev]
mov edx, 0x04 ; PCI_COMMAND
call pcibios_read_config_word
or ax, 0x05
mov ebx, [pci_bus]
mov ecx, [pci_dev]
mov edx, 0x04 ; PCI_COMMAND
call pcibios_write_config_word
mov ebx, 0x6000000
mov ecx, 27
call do_eeprom_cmd
and eax, 0xffe0000
cmp eax, 0xffe0000
je bige
mov ebx, 0x1800000
mov ecx, 0x40
jmp doread
bige:
mov ebx, 0x6000000
mov ecx, 0x100
doread:
; do-eeprom-cmd will destroy all registers
; we have eesize in ecx
; read_cmd in ebx
; Ignore full eeprom - just load the mac address
mov ecx, 0
drlp:
push ecx ; save count
push ebx
mov eax, ecx
shl eax, 16
or ebx, eax
mov ecx, 27
call do_eeprom_cmd
pop ebx
pop ecx
mov edx, ecx
shl edx, 2
mov esi, eeprom_data
add esi, edx
mov [esi], eax
inc ecx
cmp ecx, 16
jne drlp
; OK, we have the MAC address.
; Now reset the card
mov edx, [io_addr]
add dx, 8 ; SCBPort
xor eax, eax ; The reset cmd == 0
out dx, eax
mov esi, 10
call delay_ms ; Give the card time to warm up.
mov eax, lstats
mov edx, [io_addr]
add edx, 4 ; SCBPointer
out dx, eax
mov eax, 0x0140 ; INT_MASK | CU_STATSADDR
mov edx, [io_addr]
add edx, 2 ; SCBCmd
out dx, ax
call wait_for_cmd_done
mov eax, 0
mov edx, [io_addr]
add edx, 4 ; SCBPointer
out dx, eax
mov eax, 0x0106 ; INT_MASK | RX_ADDR_LOAD
mov edx, [io_addr]
add edx, 2 ; SCBCmd
out dx, ax
call wait_for_cmd_done
; build rxrd structure
mov ax, 0x0001
mov [rxfd_status], ax
mov ax, 0x0000
mov [rxfd_command], ax
mov eax, rxfd_status
sub eax, OS_BASE
mov [rxfd_link], eax
mov eax, Ether_buffer
sub eax, OS_BASE
mov [rxfd_rx_buf_addr], eax
mov ax, 0
mov [rxfd_count], ax
mov ax, 1528
mov [rxfd_size], ax
mov edx, [io_addr]
add edx, 4 ; SCBPointer
mov eax, rxfd_status
sub eax, OS_BASE
out dx, eax
mov edx, [io_addr]
add edx, 2 ; SCBCmd
mov ax, 0x0101 ; INT_MASK | RX_START
out dx, ax
call wait_for_cmd_done
; start the reciver
mov ax, 0
mov [rxfd_status], ax
mov ax, 0xc000
mov [rxfd_command], ax
mov edx, [io_addr]
add edx, 4 ; SCBPointer
mov eax, rxfd_status
sub eax, OS_BASE
out dx, eax
mov edx, [io_addr]
add edx, 2 ; SCBCmd
mov ax, 0x0101 ; INT_MASK | RX_START
out dx, ax
; Init TX Stuff
mov edx, [io_addr]
add edx, 4 ; SCBPointer
mov eax, 0
out dx, eax
mov edx, [io_addr]
add edx, 2 ; SCBCmd
mov ax, 0x0160 ; INT_MASK | CU_CMD_BASE
out dx, ax
call wait_for_cmd_done
; Set TX Base address
; First, set up confcmd values
mov ax, 2
mov [confcmd_command], ax
mov eax, txfd
sub eax, OS_BASE
mov [confcmd_link], eax
mov ax, 1
mov [txfd_command], ax ; CmdIASetup
mov ax, 0
mov [txfd_status], ax
mov eax, confcmd
sub eax, OS_BASE
mov [txfd_link], eax
; ETH_ALEN is 6 bytes
mov esi, eeprom_data
mov edi, node_addr
mov ecx, 3
drp000:
mov eax, [esi]
mov [edi], al
shr eax, 8
inc edi
mov [edi], al
inc edi
add esi, 4
loop drp000
; Hard code your MAC address into node_addr at this point,
; If you cannot read the MAC address from the eeprom in the previous step.
; You also have to write the mac address into txfd_tx_desc_addr, rather
; than taking data from eeprom_data
mov esi, eeprom_data
mov edi, txfd_tx_desc_addr
mov ecx, 3
drp001:
mov eax, [esi]
mov [edi], al
shr eax, 8
inc edi
mov [edi], al
inc edi
add esi, 4
loop drp001
mov esi, eeprom_data + (6 * 4)
mov eax, [esi]
shr eax, 8
and eax, 0x3f
cmp eax, 4 ; DP83840
je drp002
cmp eax, 10 ; DP83840A
je drp002
jmp drp003
drp002:
mov ebx, [esi]
and ebx, 0x1f
push ebx
mov ecx, 23
call mdio_read
pop ebx
or eax, 0x0422
mov ecx, 23
mov edx, eax
call mdio_write
drp003:
mov ax, 0x4002 ; Cmdsuspend | CmdConfigure
mov [confcmd_command], ax
mov ax, 0
mov [confcmd_status], ax
mov eax, txfd
mov [confcmd_link], eax
mov ebx, confcmd_data
mov al, 0x88 ; fifo of 8 each
mov [ebx + 1], al
mov al, 0
mov [ebx + 4], al
mov al, 0x80
mov [ebx + 5], al
mov al, 0x48
mov [ebx + 15], al
mov al, 0x80
mov [ebx + 19], al
mov al, 0x05
mov [ebx + 21], al
mov eax, txfd
sub eax, OS_BASE
mov edx, [io_addr]
add edx, 4 ; SCBPointer
out dx, eax
mov eax, 0x0110 ; INT_MASK | CU_START
mov edx, [io_addr]
add edx, 2 ; SCBCmd
out dx, ax
call wait_for_cmd_done
jmp skip
; wait for thing to start
drp004:
mov ax, [txfd_status]
cmp ax, 0
je drp004
skip:
; Indicate that we have successfully reset the card
mov eax, [pci_data]
mov [eth_status], eax
I8255x_exit:
ret
;***************************************************************************
; Function
; I8255x_reset
; Description
; Place the chip (ie, the ethernet card) into a virgin state
; No inputs
; All registers destroyed
;
;***************************************************************************
I8255x_reset:
ret
;***************************************************************************
; Function
; I8255x_poll
;
; Description
; Polls the ethernet card for a received packet
; Received data, if any, ends up in Ether_buffer
;
;***************************************************************************
I8255x_poll:
mov ax, 0 ; assume no data
mov [eth_rx_data_len], ax
mov ax, [rxfd_status]
cmp ax, 0
je i8p_exit
mov ax, 0
mov [rxfd_status], ax
mov ax, 0xc000
mov [rxfd_command], ax
mov edx, [io_addr]
add edx, 4 ; SCBPointer
mov eax, rxfd_status
sub eax, OS_BASE
out dx, eax
mov edx, [io_addr]
add edx, 2 ; SCBCmd
mov ax, 0x0101 ; INT_MASK | RX_START
out dx, ax
call wait_for_cmd_done
mov esi, rxfd_packet
mov edi, Ether_buffer
mov ecx, 1518
cld
rep movsb
mov ax, [rxfd_count]
and ax, 0x3fff
mov [eth_rx_data_len], ax
i8p_exit:
ret
;***************************************************************************
; Function
; I8255x_transmit
;
; Description
; Transmits a packet of data via the ethernet card
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; size of packet in ecx
; pointer to packet data in esi
;
;***************************************************************************
I8255x_transmit:
mov [hdr_type], bx
mov eax, [edi]
mov [hdr_dst_addr], eax
mov ax, [edi+4]
mov [hdr_dst_addr+4], ax
mov eax, [node_addr]
mov [hdr_src_addr], eax
mov ax, [node_addr+4]
mov [hdr_src_addr+4], ax
mov edx, [io_addr]
in ax, dx
and ax, 0xfc00
out dx, ax
xor ax, ax
mov [txfd_status], ax
mov ax, 0x400C ; Cmdsuspend | CmdTx | CmdTxFlex
mov [txfd_command], ax
mov eax, txfd
mov [txfd_link], eax
mov eax, 0x02208000
mov [txfd_count], eax
mov eax, txfd_tx_buf_addr0
sub eax, OS_BASE
mov [txfd_tx_desc_addr], eax
mov eax, hdr
sub eax, OS_BASE
mov [txfd_tx_buf_addr0], eax
mov eax, 14; sizeof hdr
mov [txfd_tx_buf_size0], eax
; Copy the buffer address and size in
mov eax, esi
sub eax, OS_BASE
mov [txfd_tx_buf_addr1], eax
mov eax, ecx
mov [txfd_tx_buf_size1], eax
mov eax, txfd
sub eax, OS_BASE
mov edx, [io_addr]
add edx, 4 ; SCBPointer
out dx, eax
mov ax, 0x0110 ; INT_MASK | CU_START
mov edx, [io_addr]
add edx, 2 ; SCBCmd
out dx, ax
call wait_for_cmd_done
mov edx, [io_addr]
in ax, dx
I8t_001:
mov ax, [txfd_status]
cmp ax, 0
je I8t_001
mov edx, [io_addr]
in ax, dx
ret

View File

@ -1,848 +0,0 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; PCNET32.INC ;;
;; ;;
;; Ethernet driver for Menuet OS ;;
;; ;;
;; - Version 1.0 31 July 2004: ;;
;; Initial release ;;
;; ;;
;; - Version 1.01 29 March 2008: ;;
;; Adapted to work with kolibrios flat kernel ;;
;; Debug info is updated, and now uses DEBUGF macro ;;
;; by hidnplayr@kolibrios.org ;;
;; ;;
;; This driver is based on the PCNet32 driver from ;;
;; the etherboot 5.0.6 project. The copyright statement is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; remaining parts Copyright 2004 Jarek Pelczar, ;;
;; jpelczar@interia.pl ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision$
PCNET32_PORT_AUI equ 0x00
PCNET32_PORT_10BT equ 0x01
PCNET32_PORT_GPSI equ 0x02
PCNET32_PORT_MII equ 0x03
PCNET32_PORT_PORTSEL equ 0x03
PCNET32_PORT_ASEL equ 0x04
PCNET32_PORT_100 equ 0x40
PCNET32_PORT_FD equ 0x80
PCNET32_DMA_MASK equ 0xffffffff
PCNET32_LOG_TX_BUFFERS equ 1
PCNET32_LOG_RX_BUFFERS equ 2
PCNET32_TX_RING_SIZE equ (1 shl PCNET32_LOG_TX_BUFFERS)
PCNET32_TX_RING_MOD_MASK equ (PCNET32_TX_RING_SIZE-1)
PCNET32_TX_RING_LEN_BITS equ 0
PCNET32_RX_RING_SIZE equ (1 shl PCNET32_LOG_RX_BUFFERS)
PCNET32_RX_RING_MOD_MASK equ (PCNET32_RX_RING_SIZE-1)
PCNET32_RX_RING_LEN_BITS equ (PCNET32_LOG_RX_BUFFERS shl 4)
PCNET32_PKT_BUF_SZ equ 1544
PCNET32_PKT_BUF_SZ_NEG equ 0xf9f8
pcnet32_txb equ (eth_data_start)
pcnet32_rxb equ ((pcnet32_txb+(PCNET32_PKT_BUF_SZ*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0)
pcnet32_tx_ring equ ((pcnet32_rxb+(PCNET32_PKT_BUF_SZ*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0)
pcnet32_rx_ring equ ((pcnet32_tx_ring+(16*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0)
virtual at ((pcnet32_rx_ring+(16*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0)
pcnet32_private:
.mode dw ?
.tlen_rlen dw ?
.phys_addr db ?,?,?,?,?,?
.reserved dw ?
.filter dd ?,?
.rx_ring dd ?
.tx_ring dd ?
.cur_rx dd ?
.cur_tx dd ?
.dirty_rx dd ?
.dirty_tx dd ?
.tx_full db ?
.options dd ?
.full_duplex db ?
.chip_version dd ?
.mii db ?
.ltint db ?
.dxsuflo db ?
.fset db ?
.fdx db ?
end virtual
virtual at 0
pcnet32_rx_head:
.base dd ?
.buf_length dw ?
.status dw ?
.msg_length dd ?
.reserved dd ?
end virtual
virtual at 0
pcnet32_tx_head:
.base dd ?
.length dw ?
.status dw ?
.misc dd ?
.reserved dd ?
end virtual
uglobal
pcnet32_access:
.read_csr dd ?
.write_csr dd ?
.read_bcr dd ?
.write_bcr dd ?
.read_rap dd ?
.write_rap dd ?
.reset dd ?
endg
iglobal
pcnet32_options_mapping:
dd PCNET32_PORT_ASEL ; 0 Auto-select
dd PCNET32_PORT_AUI ; 1 BNC/AUI
dd PCNET32_PORT_AUI ; 2 AUI/BNC
dd PCNET32_PORT_ASEL ; 3 not supported
dd PCNET32_PORT_10BT or PCNET32_PORT_FD ; 4 10baseT-FD
dd PCNET32_PORT_ASEL ; 5 not supported
dd PCNET32_PORT_ASEL ; 6 not supported
dd PCNET32_PORT_ASEL ; 7 not supported
dd PCNET32_PORT_ASEL ; 8 not supported
dd PCNET32_PORT_MII ; 9 MII 10baseT
dd PCNET32_PORT_MII or PCNET32_PORT_FD ; 10 MII 10baseT-FD
dd PCNET32_PORT_MII ; 11 MII (autosel)
dd PCNET32_PORT_10BT ; 12 10BaseT
dd PCNET32_PORT_MII or PCNET32_PORT_100 ; 13 MII 100BaseTx
dd PCNET32_PORT_MII or PCNET32_PORT_100 or PCNET32_PORT_FD ; 14 MII 100BaseTx-FD
dd PCNET32_PORT_ASEL ; 15 not supported
endg
PCNET32_WIO_RDP equ 0x10
PCNET32_WIO_RAP equ 0x12
PCNET32_WIO_RESET equ 0x14
PCNET32_WIO_BDP equ 0x16
PCNET32_DWIO_RDP equ 0x10
PCNET32_DWIO_RAP equ 0x14
PCNET32_DWIO_RESET equ 0x18
PCNET32_DWIO_BDP equ 0x1C
PCNET32_TOTAL_SIZE equ 0x20
; ebx - index
; return:
; eax - data
pcnet32_wio_read_csr:
push edx
lea edx, [ebp+PCNET32_WIO_RAP]
mov ax, bx
out dx, ax
lea edx, [ebp+PCNET32_WIO_RDP]
in ax, dx
and eax, 0xffff
pop edx
ret
; eax - data
; ebx - index
pcnet32_wio_write_csr:
push edx
lea edx, [ebp+PCNET32_WIO_RAP]
xchg eax, ebx
out dx, ax
xchg eax, ebx
lea edx, [ebp+PCNET32_WIO_RDP]
out dx, ax
pop edx
ret
; ebx - index
; return:
; eax - data
pcnet32_wio_read_bcr:
push edx
lea edx, [ebp+PCNET32_WIO_RAP]
mov ax, bx
out dx, ax
lea edx, [ebp+PCNET32_WIO_BDP]
in ax, dx
and eax, 0xffff
pop edx
ret
; eax - data
; ebx - index
pcnet32_wio_write_bcr:
push edx
lea edx, [ebp+PCNET32_WIO_RAP]
xchg eax, ebx
out dx, ax
xchg eax, ebx
lea edx, [ebp+PCNET32_WIO_BDP]
out dx, ax
pop edx
ret
pcnet32_wio_read_rap:
push edx
lea edx, [ebp+PCNET32_WIO_RAP]
in ax, dx
and eax, 0xffff
pop edx
ret
; eax - val
pcnet32_wio_write_rap:
push edx
lea edx, [ebp+PCNET32_WIO_RAP]
out dx, ax
pop edx
ret
pcnet32_wio_reset:
push edx
push eax
lea edx, [ebp+PCNET32_WIO_RESET]
in ax, dx
pop eax
pop edx
ret
pcnet32_wio_check:
push edx
mov ax, 88
lea edx, [ebp+PCNET32_WIO_RAP]
out dx, ax
nop
nop
in ax, dx
cmp ax, 88
sete al
pop edx
ret
iglobal
pcnet32_wio:
dd pcnet32_wio_read_csr
dd pcnet32_wio_write_csr
dd pcnet32_wio_read_bcr
dd pcnet32_wio_write_bcr
dd pcnet32_wio_read_rap
dd pcnet32_wio_write_rap
dd pcnet32_wio_reset
endg
; ebx - index
; return:
; eax - data
pcnet32_dwio_read_csr:
push edx
lea edx, [ebp+PCNET32_DWIO_RAP]
mov eax, ebx
out dx, eax
lea edx, [ebp+PCNET32_DWIO_RDP]
in eax, dx
and eax, 0xffff
pop edx
ret
; ebx - index
; eax - data
pcnet32_dwio_write_csr:
push edx
lea edx, [ebp+PCNET32_DWIO_RAP]
xchg eax, ebx
out dx, eax
lea edx, [ebp+PCNET32_DWIO_RDP]
xchg eax, ebx
out dx, eax
pop edx
ret
; ebx - index
; return:
; eax - data
pcnet32_dwio_read_bcr:
push edx
lea edx, [ebp+PCNET32_DWIO_RAP]
mov eax, ebx
out dx, eax
lea edx, [ebp+PCNET32_DWIO_BDP]
in eax, dx
and eax, 0xffff
pop edx
ret
; ebx - index
; eax - data
pcnet32_dwio_write_bcr:
push edx
lea edx, [ebp+PCNET32_DWIO_RAP]
xchg eax, ebx
out dx, eax
lea edx, [ebp+PCNET32_DWIO_BDP]
xchg eax, ebx
out dx, eax
pop edx
ret
pcnet32_dwio_read_rap:
push edx
lea edx, [ebp+PCNET32_DWIO_RAP]
in eax, dx
and eax, 0xffff
pop edx
ret
; eax - val
pcnet32_dwio_write_rap:
push edx
lea edx, [ebp+PCNET32_DWIO_RAP]
out dx, eax
pop edx
ret
pcnet32_dwio_reset:
push edx
push eax
lea edx, [ebp+PCNET32_DWIO_RESET]
in eax, dx
pop eax
pop edx
ret
pcnet32_dwio_check:
push edx
lea edx, [PCNET32_DWIO_RAP]
mov eax, 88
out dx, eax
nop
nop
in eax, dx
and eax, 0xffff
cmp eax, 88
sete al
pop edx
ret
iglobal
pcnet32_dwio:
dd pcnet32_dwio_read_csr
dd pcnet32_dwio_write_csr
dd pcnet32_dwio_read_bcr
dd pcnet32_dwio_write_bcr
dd pcnet32_dwio_read_rap
dd pcnet32_dwio_write_rap
dd pcnet32_dwio_reset
endg
pcnet32_init_ring:
mov [pcnet32_private.tx_full], 0
mov [pcnet32_private.cur_rx], 0
mov [pcnet32_private.cur_tx], 0
mov [pcnet32_private.dirty_rx], 0
mov [pcnet32_private.dirty_tx], 0
mov edi, pcnet32_rx_ring
mov ecx, PCNET32_RX_RING_SIZE
mov ebx, pcnet32_rxb
sub ebx, OS_BASE
.rx_init:
mov [edi+pcnet32_rx_head.base], ebx
mov [edi+pcnet32_rx_head.buf_length], word PCNET32_PKT_BUF_SZ_NEG
mov [edi+pcnet32_rx_head.status], word 0x8000
add ebx, PCNET32_PKT_BUF_SZ
; inc ebx
add edi, 16
loop .rx_init
mov edi, pcnet32_tx_ring
mov ecx, PCNET32_TX_RING_SIZE
.tx_init:
mov [edi+pcnet32_tx_head.base], dword 0
mov [edi+pcnet32_tx_head.status], word 0
add edi, 16
loop .tx_init
mov [pcnet32_private.tlen_rlen], (PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS)
mov esi, node_addr
mov edi, pcnet32_private.phys_addr
cld
movsd
movsw
mov eax, pcnet32_rx_ring
sub eax, OS_BASE
mov dword [pcnet32_private.rx_ring], eax
mov eax, pcnet32_tx_ring
sub eax, OS_BASE
mov dword [pcnet32_private.tx_ring], eax
ret
pcnet32_reset:
; Reset PCNET32
mov ebp, [io_addr]
call dword [pcnet32_access.reset]
; set 32bit mode
mov ebx, 20
mov eax, 2
call dword [pcnet32_access.write_bcr]
; set/reset autoselect bit
mov ebx, 2
call dword [pcnet32_access.read_bcr]
and eax, not 2
test [pcnet32_private.options], PCNET32_PORT_ASEL
jz .L1
or eax, 2
.L1:
call dword [pcnet32_access.write_bcr]
; Handle full duplex setting
cmp byte [pcnet32_private.full_duplex], 0
je .L2
mov ebx, 9
call dword [pcnet32_access.read_bcr]
and eax, not 3
test [pcnet32_private.options], PCNET32_PORT_FD
jz .L3
or eax, 1
cmp [pcnet32_private.options], PCNET32_PORT_FD or PCNET32_PORT_AUI
jne .L4
or eax, 2
jmp .L4
.L3:
test [pcnet32_private.options], PCNET32_PORT_ASEL
jz .L4
cmp [pcnet32_private.chip_version], 0x2627
jne .L4
or eax, 3
.L4:
mov ebx, 9
call dword [pcnet32_access.write_bcr]
.L2:
; set/reset GPSI bit
mov ebx, 124
call dword [pcnet32_access.read_csr]
mov ecx, [pcnet32_private.options]
and ecx, PCNET32_PORT_PORTSEL
cmp ecx, PCNET32_PORT_GPSI
jne .L5
or eax, 0x10
.L5:
call dword [pcnet32_access.write_csr]
cmp [pcnet32_private.mii], 0
je .L6
test [pcnet32_private.options], PCNET32_PORT_ASEL
jnz .L6
mov ebx, 32
call dword [pcnet32_access.read_bcr]
and eax, not 0x38
test [pcnet32_private.options], PCNET32_PORT_FD
jz .L7
or eax, 0x10
.L7:
test [pcnet32_private.options], PCNET32_PORT_100
jz .L8
or eax, 0x08
.L8:
call dword [pcnet32_access.write_bcr]
jmp .L9
.L6:
test [pcnet32_private.options], PCNET32_PORT_ASEL
jz .L9
mov ebx, 32
; DEBUGF 1," K : ASEL, enable auto-negotiation\n"
call dword [pcnet32_access.read_bcr]
and eax, not 0x98
or eax, 0x20
call dword [pcnet32_access.write_bcr]
.L9:
cmp [pcnet32_private.ltint], 0
je .L10
mov ebx, 5
call dword [pcnet32_access.read_csr]
or eax, (1 shl 14)
call dword [pcnet32_access.write_csr]
.L10:
mov eax, [pcnet32_private.options]
and eax, PCNET32_PORT_PORTSEL
shl eax, 7
mov [pcnet32_private.mode], ax
mov [pcnet32_private.filter], dword 0xffffffff
mov [pcnet32_private.filter+4], dword 0xffffffff
call pcnet32_init_ring
mov ebx, 1
mov eax, pcnet32_private
sub eax, OS_BASE
and eax, 0xffff
call dword [pcnet32_access.write_csr]
mov eax, pcnet32_private
sub eax, OS_BASE
mov ebx, 2
shr eax, 16
call dword [pcnet32_access.write_csr]
mov ebx, 4
mov eax, 0x0915
call dword [pcnet32_access.write_csr]
mov ebx, 0
mov eax, 1
call dword [pcnet32_access.write_csr]
mov ecx, 100
.L11:
xor ebx, ebx
call dword [pcnet32_access.read_csr]
test ax, 0x100
jnz .L12
loop .L11
.L12:
; DEBUGF 1," K : hardware reset\n"
xor ebx, ebx
mov eax, 0x0002
call dword [pcnet32_access.write_csr]
xor ebx, ebx
call dword [pcnet32_access.read_csr]
; DEBUGF 1," K : PCNET reset complete\n"
ret
pcnet32_adjust_pci_device:
;*******Get current setting************************
mov al, 2 ;read a word
mov bh, [pci_dev]
mov ah, [pci_bus]
mov bl, 0x04 ;from command Register
call pci_read_reg
;******see if its already set as bus master********
mov bx, ax
and bx, 5
cmp bx, 5
je pcnet32_adjust_pci_device_Latency
;******Make card a bus master*******
mov cx, ax ;value to write
mov bh, [pci_dev]
mov al, 2 ;write a word
or cx, 5
mov ah, [pci_bus]
mov bl, 0x04 ;to command register
call pci_write_reg
;******Check latency setting***********
pcnet32_adjust_pci_device_Latency:
;*******Get current latency setting************************
; mov al, 1 ;read a byte
; mov bh, [pci_dev]
; mov ah, [pci_bus]
; mov bl, 0x0D ;from Lantency Timer Register
; call pci_read_reg
;******see if its aat least 64 clocks********
; cmp ax,64
; jge pcnet32_adjust_pci_device_Done
;******Set latency to 32 clocks*******
; mov cx, 64 ;value to write
; mov bh, [pci_dev]
; mov al, 1 ;write a byte
; mov ah, [pci_bus]
; mov bl, 0x0D ;to Lantency Timer Register
; call pci_write_reg
;******Check latency setting***********
pcnet32_adjust_pci_device_Done:
ret
pcnet32_probe:
mov ebp, [io_addr]
call pcnet32_wio_reset
xor ebx, ebx
call pcnet32_wio_read_csr
cmp eax, 4
jne .try_dwio
call pcnet32_wio_check
and al, al
jz .try_dwio
; DEBUGF 1," K : Using WIO\n"
mov esi, pcnet32_wio
jmp .L1
.try_dwio:
call pcnet32_dwio_reset
xor ebx, ebx
call pcnet32_dwio_read_csr
cmp eax, 4
jne .no_dev
call pcnet32_dwio_check
and al, al
jz .no_dev
; DEBUGF 1," K : Using DWIO\n"
mov esi, pcnet32_dwio
jmp .L1
.no_dev:
DEBUGF 1," K : PCNET32 not found\n"
ret
.L1:
mov edi, pcnet32_access
mov ecx, 7
cld
rep movsd
mov ebx, 88
call dword [pcnet32_access.read_csr]
mov ecx, eax
mov ebx, 89
call dword [pcnet32_access.read_csr]
shl eax, 16
or eax, ecx
mov ecx, eax
and ecx, 0xfff
cmp ecx, 3
jne .no_dev
shr eax, 12
and eax, 0xffff
mov [pcnet32_private.chip_version], eax
; DEBUGF 1," K : PCNET32 chip version OK\n"
mov [pcnet32_private.fdx], 0
mov [pcnet32_private.mii], 0
mov [pcnet32_private.fset], 0
mov [pcnet32_private.dxsuflo], 0
mov [pcnet32_private.ltint], 0
mov eax, [pcnet32_private.chip_version]
cmp eax, 0x2420
je .L2
cmp eax, 0x2430
je .L3
cmp eax, 0x2621
je .L4
cmp eax, 0x2623
je .L5
cmp eax, 0x2624
je .L6
cmp eax, 0x2625
je .L7
cmp eax, 0x2626
je .L8
cmp eax, 0x2627
je .L9
DEBUGF 1," K : Invalid chip rev\n"
jmp .no_dev
.L2:
; DEBUGF 1," K : PCnet/PCI 79C970\n"
jmp .L10
.L3:
; DEBUGF 1," K : PCnet/PCI 79C970\n"
jmp .L10
.L4:
; DEBUGF 1," K : PCnet/PCI II 79C970A\n"
mov [pcnet32_private.fdx], 1
jmp .L10
.L5:
; DEBUGF 1," K : PCnet/FAST 79C971\n"
mov [pcnet32_private.fdx], 1
mov [pcnet32_private.mii], 1
mov [pcnet32_private.fset], 1
mov [pcnet32_private.ltint], 1
jmp .L10
.L6:
; DEBUGF 1," K : PCnet/FAST+ 79C972\n"
mov [pcnet32_private.fdx], 1
mov [pcnet32_private.mii], 1
mov [pcnet32_private.fset], 1
jmp .L10
.L7:
; DEBUGF 1," K : PCnet/FAST III 79C973\n"
mov [pcnet32_private.fdx], 1
mov [pcnet32_private.mii], 1
jmp .L10
.L8:
; DEBUGF 1," K : PCnet/Home 79C978\n"
mov [pcnet32_private.fdx], 1
mov ebx, 49
call dword [pcnet32_access.read_bcr]
call dword [pcnet32_access.write_bcr]
jmp .L10
.L9:
; DEBUGF 1," K : PCnet/FAST III 79C975\n"
mov [pcnet32_private.fdx], 1
mov [pcnet32_private.mii], 1
.L10:
cmp [pcnet32_private.fset], 1
jne .L11
mov ebx, 18
call dword [pcnet32_access.read_bcr]
or eax, 0x800
call dword [pcnet32_access.write_bcr]
mov ebx, 80
call dword [pcnet32_access.read_csr]
and eax, 0xc00
or eax, 0xc00
call dword [pcnet32_access.write_csr]
mov [pcnet32_private.dxsuflo], 1
mov [pcnet32_private.ltint], 1
.L11:
; read MAC
mov edi, node_addr
mov edx, ebp
mov ecx, 6
.Lmac:
in al, dx
stosb
inc edx
loop .Lmac
; DEBUGF 1," K : MAC read\n"
call pcnet32_adjust_pci_device
; DEBUGF 1," K : PCI done\n"
mov eax, PCNET32_PORT_ASEL
mov [pcnet32_private.options], eax
mov [pcnet32_private.mode], word 0x0003
mov [pcnet32_private.tlen_rlen], word (PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS)
mov esi, node_addr
mov edi, pcnet32_private.phys_addr
cld
movsd
movsw
mov [pcnet32_private.filter], dword 0
mov [pcnet32_private.filter+4], dword 0
mov eax, pcnet32_rx_ring
sub eax, OS_BASE
mov dword [pcnet32_private.rx_ring], eax
mov eax, pcnet32_tx_ring
sub eax, OS_BASE
mov dword [pcnet32_private.tx_ring], eax
; DEBUGF 1," K : Switching to 32\n"
mov ebx, 20
mov eax, 2
call dword [pcnet32_access.write_bcr]
mov ebx, 1
mov eax, ((pcnet32_private - OS_BASE) and 0xffff)
call dword [pcnet32_access.write_csr]
mov ebx, 2
mov eax, ((pcnet32_private - OS_BASE) shr 16) and 0xffff
call dword [pcnet32_access.write_csr]
mov ebx, 0
mov eax, 1
call dword [pcnet32_access.write_csr]
mov esi, 1
call delay_ms
call pcnet32_reset
mov eax, [pci_data]
mov [eth_status], eax
ret
pcnet32_poll:
xor ax, ax
mov [eth_rx_data_len], ax
mov eax, [pcnet32_private.cur_rx]
and eax, PCNET32_RX_RING_MOD_MASK
mov ebx, eax
imul esi, eax, PCNET32_PKT_BUF_SZ
add esi, pcnet32_rxb
shl ebx, 4
add ebx, pcnet32_rx_ring
mov cx, [ebx+pcnet32_rx_head.status]
test cx, 0x8000
jnz .L1
cmp ch, 3
jne .L1
mov ecx, [ebx+pcnet32_rx_head.msg_length]
and ecx, 0xfff
sub ecx, 4
mov [eth_rx_data_len], cx
; DEBUGF 1," K : PCNETRX: %ub\n",cx
push ecx
shr ecx, 2
mov edi, Ether_buffer
cld
rep movsd
pop ecx
and ecx, 3
rep movsb
mov [ebx+pcnet32_rx_head.buf_length], word PCNET32_PKT_BUF_SZ_NEG
or [ebx+pcnet32_rx_head.status], word 0x8000
inc [pcnet32_private.cur_rx]
.L1:
ret
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; size of packet in ecx
; pointer to packet data in esi
pcnet32_xmit:
push edi
push esi
push ebx
push ecx
; DEBUGF 1," K : PCNETTX\n"
mov esi, edi
mov edi, [pcnet32_private.cur_tx]
imul edi, PCNET32_PKT_BUF_SZ
add edi, pcnet32_txb; edi=ptxb
mov eax, edi
cld ; copy MAC
movsd
movsw
mov esi, node_addr
cld
movsd
movsw
mov [edi], bx
add edi, 2
mov esi, [esp+8]
mov ecx, [esp]
push ecx
shr ecx, 2
cld
rep movsd
pop ecx
and ecx, 3
rep movsb
; mov ecx,[esp]
; add ecx,14 ; ETH_HLEN
; xor eax,eax
; pad to min length (60=ETH_ZLEN)
; cmp ecx,60
; jae .L1
; sub ecx,60
; cld
; rep stosb
;.L1:
mov edi, pcnet32_tx_ring+0; entry=0
mov ecx, [esp]
add ecx, 14
cmp cx, 60
jae .L1
mov cx, 60
.L1:
neg cx
mov [edi+pcnet32_tx_head.length], cx
mov [edi+pcnet32_tx_head.misc], dword 0
sub eax, OS_BASE
mov [edi+pcnet32_tx_head.base], eax
mov [edi+pcnet32_tx_head.status], word 0x8300
; trigger an immediate send poll
mov ebx, 0
mov eax, 0x0008; 0x0048
mov ebp, [io_addr]
call dword [pcnet32_access.write_csr]
mov dword [pcnet32_private.cur_tx], 0
; wait for TX to complete
mov ecx, [timer_ticks];[0xfdf0]
add ecx, 100
.L2:
mov ax, [edi+pcnet32_tx_head.status]
test ax, 0x8000
jz .L3
cmp ecx, [timer_ticks];[0xfdf0]
jb .L4
mov esi, 10
call delay_ms
jnz .L2
.L4:
DEBUGF 1," K : PCNET: Send timeout\n"
.L3:
mov dword [edi+pcnet32_tx_head.base], 0
pop ecx
pop ebx
pop esi
pop edi
ret

View File

@ -1,813 +0,0 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; R6040 driver for KolibriOS ;;
;; ;;
;; based on R6040.c from linux ;;
;; ;;
;; Written by Asper (asper.85@mail.ru) ;;
;; and hidnplayr (hidnplayr@gmail.com) ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;********************************************************************
; Interface
; r6040_reset
; r6040_probe
; r6040_poll
; r6040_transmit
;
; These functions are referenced in ethernet.inc
;
;********************************************************************
;; A few user-configurable values.
TX_RING_SIZE equ 4
RX_RING_SIZE equ 4
; ethernet address length
ETH_ALEN equ 6
ETH_HLEN equ (2 * ETH_ALEN + 2)
ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for
; mininmum 64bytes frame length
; system timer frequency
HZ equ 1000
; max time out delay time
W_MAX_TIMEOUT equ 0x0FFF
;; Size of the in-memory receive ring.
RX_BUF_LEN_IDX equ 3 ;; 0==8K, 1==16K, 2==32K, 3==64K
RX_BUF_LEN equ (8192 << RX_BUF_LEN_IDX)
;-; Size of the Tx bounce buffers -- must be at least (dev->mtu+14+4).
;-TX_BUF_SIZE equ 1536
;-RX_BUF_SIZE equ 1536
;; PCI Tuning Parameters
; Threshold is bytes transferred to chip before transmission starts.
TX_FIFO_THRESH equ 256 ;; In bytes, rounded down to 32 byte units.
;; The following settings are log_2(bytes)-4: 0 == 16 bytes .. 6==1024.
RX_FIFO_THRESH equ 4 ;; Rx buffer level before first PCI xfer.
RX_DMA_BURST equ 4 ;; Maximum PCI burst, '4' is 256 bytes
TX_DMA_BURST equ 4
;; Operational parameters that usually are not changed.
PHY1_ADDR equ 1 ;For MAC1
PHY2_ADDR equ 3 ;For MAC2
PHY_MODE equ 0x3100 ;PHY CHIP Register 0
PHY_CAP equ 0x01E1 ;PHY CHIP Register 4
;; Time in jiffies before concluding the transmitter is hung.
TX_TIMEOUT equ ((6000*HZ)/1000)
R6040_IO_SIZE equ 256 ; RDC MAC I/O Size
MAX_MAC equ 2 ; MAX RDC MAC
;**************************************************************************
; RDC R6040 Register Definitions
;**************************************************************************
MCR0 equ 0x00 ;Control register 0
MCR1 equ 0x01 ;Control register 1
MAC_RST equ 0x0001 ;Reset the MAC
MBCR equ 0x08 ;Bus control
MT_ICR equ 0x0C ;TX interrupt control
MR_ICR equ 0x10 ;RX interrupt control
MTPR equ 0x14 ;TX poll command register
MR_BSR equ 0x18 ;RX buffer size
MR_DCR equ 0x1A ;RX descriptor control
MLSR equ 0x1C ;Last status
MMDIO equ 0x20 ;MDIO control register
MDIO_WRITE equ 0x4000 ;MDIO write
MDIO_READ equ 0x2000 ;MDIO read
MMRD equ 0x24 ;MDIO read data register
MMWD equ 0x28 ;MDIO write data register
MTD_SA0 equ 0x2C ;TX descriptor start address 0
MTD_SA1 equ 0x30 ;TX descriptor start address 1
MRD_SA0 equ 0x34 ;RX descriptor start address 0
MRD_SA1 equ 0x38 ;RX descriptor start address 1
MISR equ 0x3C ;Status register
MIER equ 0x40 ;INT enable register
MSK_INT equ 0x0000 ;Mask off interrupts
RX_FINISH equ 0x0001 ;RX finished
RX_NO_DESC equ 0x0002 ;No RX descriptor available
RX_FIFO_FULL equ 0x0004 ;RX FIFO full
RX_EARLY equ 0x0008 ;RX early
TX_FINISH equ 0x0010 ;TX finished
TX_EARLY equ 0x0080 ;TX early
EVENT_OVRFL equ 0x0100 ;Event counter overflow
LINK_CHANGED equ 0x0200 ;PHY link changed
ME_CISR equ 0x44 ;Event counter INT status
ME_CIER equ 0x48 ;Event counter INT enable
MR_CNT equ 0x50 ;Successfully received packet counter
ME_CNT0 equ 0x52 ;Event counter 0
ME_CNT1 equ 0x54 ;Event counter 1
ME_CNT2 equ 0x56 ;Event counter 2
ME_CNT3 equ 0x58 ;Event counter 3
MT_CNT equ 0x5A ;Successfully transmit packet counter
ME_CNT4 equ 0x5C ;Event counter 4
MP_CNT equ 0x5E ;Pause frame counter register
MAR0 equ 0x60 ;Hash table 0
MAR1 equ 0x62 ;Hash table 1
MAR2 equ 0x64 ;Hash table 2
MAR3 equ 0x66 ;Hash table 3
MID_0L equ 0x68 ;Multicast address MID0 Low
MID_0M equ 0x6A ;Multicast address MID0 Medium
MID_0H equ 0x6C ;Multicast address MID0 High
MID_1L equ 0x70 ;MID1 Low
MID_1M equ 0x72 ;MID1 Medium
MID_1H equ 0x74 ;MID1 High
MID_2L equ 0x78 ;MID2 Low
MID_2M equ 0x7A ;MID2 Medium
MID_2H equ 0x7C ;MID2 High
MID_3L equ 0x80 ;MID3 Low
MID_3M equ 0x82 ;MID3 Medium
MID_3H equ 0x84 ;MID3 High
PHY_CC equ 0x88 ;PHY status change configuration register
PHY_ST equ 0x8A ;PHY status register
MAC_SM equ 0xAC ;MAC status machine
MAC_ID equ 0xBE ;Identifier register
MAX_BUF_SIZE equ 0x600 ;1536
MBCR_DEFAULT equ 0x012A ;MAC Bus Control Register
MCAST_MAX equ 3 ;Max number multicast addresses to filter
;Descriptor status
DSC_OWNER_MAC equ 0x8000 ;MAC is the owner of this descriptor
DSC_RX_OK equ 0x4000 ;RX was successfull
DSC_RX_ERR equ 0x0800 ;RX PHY error
DSC_RX_ERR_DRI equ 0x0400 ;RX dribble packet
DSC_RX_ERR_BUF equ 0x0200 ;RX length exceeds buffer size
DSC_RX_ERR_LONG equ 0x0100 ;RX length > maximum packet length
DSC_RX_ERR_RUNT equ 0x0080 ;RX packet length < 64 byte
DSC_RX_ERR_CRC equ 0x0040 ;RX CRC error
DSC_RX_BCAST equ 0x0020 ;RX broadcast (no error)
DSC_RX_MCAST equ 0x0010 ;RX multicast (no error)
DSC_RX_MCH_HIT equ 0x0008 ;RX multicast hit in hash table (no error)
DSC_RX_MIDH_HIT equ 0x0004 ;RX MID table hit (no error)
DSC_RX_IDX_MID_MASK equ 3 ;RX mask for the index of matched MIDx
;PHY settings
ICPLUS_PHY_ID equ 0x0243
RX_INTS equ RX_FIFO_FULL or RX_NO_DESC or RX_FINISH
TX_INTS equ TX_FINISH
INT_MASK equ RX_INTS or TX_INTS
r6040_txb equ (eth_data_start)
r6040_rxb equ ((r6040_txb+(MAX_BUF_SIZE*TX_RING_SIZE)+32) and 0xfffffff0)
r6040_tx_ring equ ((r6040_rxb+(MAX_BUF_SIZE*RX_RING_SIZE)+32) and 0xfffffff0)
r6040_rx_ring equ ((r6040_tx_ring+(r6040_x_head.sizeof*TX_RING_SIZE)+32) and 0xfffffff0)
virtual at ((r6040_rx_ring+(r6040_x_head.sizeof*RX_RING_SIZE)+32) and 0xfffffff0)
r6040_private:
.rx_ring dd ?
.tx_ring dd ?
.cur_rx dw ?
.cur_tx dw ?
.phy_addr dw ?
.phy_mode dw ?
.mcr0 dw ?
.mcr1 dw ?
.switch_sig dw ?
end virtual
virtual at 0
r6040_x_head:
.status dw ? ;0-1
.len dw ? ;2-3
.buf dd ? ;4-7
.ndesc dd ? ;8-B
.rev1 dd ? ;C-F
.vbufp dd ? ;10-13
.vndescp dd ? ;14-17
.skb_ptr dd ? ;18-1B
.rev2 dd ? ;1C-1F
.sizeof:
end virtual
; Read a word data from PHY Chip
proc r6040_phy_read stdcall, phy_addr:dword, reg:dword
push ecx edx
mov eax, [phy_addr]
shl eax, 8
add eax, [reg]
add eax, MDIO_READ
mov edx, [io_addr]
add edx, MMDIO
out dx, ax
;Wait for the read bit to be cleared.
mov ecx, 2048 ;limit
xor eax, eax
.read:
in ax, dx
test ax, MDIO_READ
jz @f
dec ecx
test ecx, ecx
jnz .read
@@:
mov edx, [io_addr]
add edx, MMRD
in ax, dx
and eax, 0xFFFF
pop edx ecx
ret
endp
; Write a word data to PHY Chip
proc r6040_phy_write stdcall, phy_addr:dword, reg:dword, val:dword
push eax ecx edx
mov eax, [val]
mov edx, [io_addr]
add edx, MMWD
out dx, ax
;Write the command to the MDIO bus
mov eax, [phy_addr]
shl eax, 8
add eax, [reg]
add eax, MDIO_WRITE
mov edx, [io_addr]
add edx, MMDIO
out dx, ax
;Wait for the write bit to be cleared.
mov ecx, 2048 ;limit
xor eax, eax
.write:
in ax, dx
test ax, MDIO_WRITE
jz @f
dec ecx
test ecx, ecx
jnz .write
@@:
pop edx ecx eax
ret
endp
macro r6040_mdio_write reg, val {
stdcall r6040_phy_read, [io_addr], [r6040_private.phy_addr], reg
}
macro r6040_mdio_write reg, val {
stdcall r6040_phy_write, [io_addr], [r6040_private.phy_addr], reg, val
}
proc r6040_init_ring_desc stdcall, desc_ring:dword, size:dword
push eax ecx esi
mov ecx, [size]
test ecx, ecx
jz .out
mov esi, [desc_ring]
mov eax, esi
.next_desc:
add eax, r6040_x_head.sizeof - OS_BASE
mov [esi+r6040_x_head.ndesc], eax
add eax, OS_BASE
mov [esi+r6040_x_head.vndescp], eax
mov esi, eax
dec ecx
jnz .next_desc
sub esi, r6040_x_head.sizeof
mov eax, [desc_ring]
mov [esi+r6040_x_head.vndescp], eax
sub eax, OS_BASE
mov [esi+r6040_x_head.ndesc], eax
.out:
pop esi ecx eax
ret
endp
r6040_init_rxbufs:
stdcall r6040_init_ring_desc, r6040_rx_ring, RX_RING_SIZE
; Allocate skbs for the rx descriptors
mov esi, r6040_rx_ring
mov ebx, r6040_rxb
mov ecx, RX_RING_SIZE
mov eax, r6040_rx_ring
.next_desc:
mov [esi+r6040_x_head.skb_ptr], ebx
mov [esi+r6040_x_head.buf], ebx
sub [esi+r6040_x_head.buf], OS_BASE
mov [esi+r6040_x_head.status], DSC_OWNER_MAC
mov eax, [esi+r6040_x_head.vndescp]
mov esi, eax
add ebx, MAX_BUF_SIZE
dec ecx
jnz .next_desc
xor eax, eax
.out:
ret
r6040_probe:
DEBUGF 1, "Probing r6040\n"
call adjust_pci_device
; If PHY status change register is still set to zero
; it means the bootloader didn't initialize it
mov edx, [io_addr]
add edx, PHY_CC
in ax, dx
test ax, ax
jnz @f
mov eax, 0x9F07
out dx, ax
@@:
; Set MAC address
mov ecx, 3
mov edi, node_addr
mov edx, [io_addr]
add edx, MID_0L
.mac:
in ax, dx
stosw
add edx, 2
dec ecx
jnz .mac
; Some bootloaders/BIOSes do not initialize
; MAC address, warn about that
and eax, 0xFF
or eax, [node_addr]
test eax, eax
jnz @f
DEBUGF 1, "K : MAC address not initialized\n" ;, generating random"
;Asper: Add here generate function call!
; Temporary workaround: init by constant adress
mov dword [node_addr], 0x00006000
mov word [node_addr+4], 0x0001
@@:
; Init RDC private data
mov [r6040_private.mcr0], 0x1002
;mov [r6040_private.phy_addr], 1 ; Asper: Only one network card is supported now.
mov [r6040_private.switch_sig], 0
; Check the vendor ID on the PHY, if 0xFFFF assume none attached
stdcall r6040_phy_read, 1, 2
cmp ax, 0xFFFF
jne @f
DEBUGF 1, "K : Failed to detect an attached PHY\n" ;, generating random"
mov eax, -1
ret
@@:
; Set MAC address
call r6040_mac_address
; Initialize and alloc RX/TX buffers
stdcall r6040_init_ring_desc, r6040_tx_ring, TX_RING_SIZE
call r6040_init_rxbufs ;r6040_alloc_rxbufs
test eax, eax
jnz .out
; Read the PHY ID
mov [r6040_private.phy_mode], 0x8000
stdcall r6040_phy_read, 0, 2
mov [r6040_private.switch_sig], ax
cmp ax, ICPLUS_PHY_ID
jne @f
stdcall r6040_phy_write, 29, 31, 0x175C ; Enable registers
jmp .phy_readen
@@:
; PHY Mode Check
movzx eax, [r6040_private.phy_addr]
stdcall r6040_phy_write, eax, 4, PHY_CAP
stdcall r6040_phy_write, eax, 0, PHY_MODE
; if PHY_MODE = 0x3100
call r6040_phy_mode_chk
mov [r6040_private.phy_mode], ax
jmp .phy_readen
; end if
; if not (PHY_MODE and 0x0100)
mov [r6040_private.phy_mode], 0
; end if
.phy_readen:
; Set duplex mode
mov ax, [r6040_private.phy_mode]
or [r6040_private.mcr0], ax
; improve performance (by RDC guys)
stdcall r6040_phy_read, 30, 17
or ax, 0x4000
stdcall r6040_phy_write, 30, 17, eax
stdcall r6040_phy_read, 30, 17
xor ax, -1
or ax, 0x2000
xor ax, -1
stdcall r6040_phy_write, 30, 17, eax
stdcall r6040_phy_write, 0, 19, 0x0000
stdcall r6040_phy_write, 0, 30, 0x01F0
; Initialize all Mac registers
call r6040_reset
xor eax, eax
.out:
ret
align 4
r6040_reset:
DEBUGF 1, "Resetting r6040\n"
push eax ecx edx
; Mask off Interrupt
mov eax, MSK_INT
mov edx, [io_addr]
add edx, MIER
out dx, ax
;Reset RDC MAC
mov eax, MAC_RST
mov edx, [io_addr]
add edx, MCR1
out dx, ax
mov ecx, 2048 ;limit
.read:
in ax, dx
test ax, 0x1
jnz @f
dec ecx
test ecx, ecx
jnz .read
@@:
;Reset internal state machine
mov ax, 2
mov edx, [io_addr]
add edx, MAC_SM
out dx, ax
xor ax, ax
out dx, ax
mov esi, 5
call delay_ms
;MAC Bus Control Register
mov ax, MBCR_DEFAULT
mov edx, [io_addr]
add edx, MBCR
out dx, ax
;Buffer Size Register
mov ax, MAX_BUF_SIZE
mov edx, [io_addr]
add edx, MR_BSR
out dx, ax
;Write TX ring start address
mov eax, r6040_tx_ring - OS_BASE ;Asper: Maybe we can just write dword? Hidnplayr: better use word, as described in datasheet.
mov edx, [io_addr]
add edx, MTD_SA0
out dx, ax
shr eax, 16
add edx, MTD_SA1 - MTD_SA0
out dx, ax
;Write RX ring start address
mov eax, r6040_rx_ring - OS_BASE ;Asper: Maybe we can just write dword?
mov edx, [io_addr]
add edx, MRD_SA0
out dx, ax
shr eax, 16
add edx, MRD_SA1 - MRD_SA0
out dx, ax
;Set interrupt waiting time and packet numbers
xor ax, ax
mov edx, [io_addr]
add edx, MT_ICR
out dx, ax
;Asper: ~ Disable ints ;Enable interrupts
;mov ax, MSK_INT ;INT_MASK ;Asper ~
;mov edx, [io_addr]
;add edx, MIER
;out dx, ax
;Enable TX and RX
mov ax, [r6040_private.mcr0]
or ax, 0x0002
mov edx, [io_addr]
out dx, ax
;Let TX poll the descriptors
;we may got called by r6040_tx_timeout which has left
;some unset tx buffers
xor ax, ax
inc ax
mov edx, [io_addr]
add edx, MTPR
out dx, ax
pop edx ecx eax
DEBUGF 1, "reset ok!\n"
; Indicate that we have successfully reset the card
mov eax, [pci_data]
mov [eth_status], eax
ret
proc r6040_tx_timeout
push eax edx
;...
inc [stats.tx_errors]
;Reset MAC and re-init all registers
call r6040_init_mac_regs
pop edx eax
ret
endp
proc r6040_get_stats
push eax edx
mov edx, [io_addr]
add edx, ME_CNT1
in al, dx
add [stats.rx_crc_errors], al
mov edx, [io_addr]
add edx, ME_CNT0
in al, dx
add [stats.multicast], al
pop edx eax
ret
endp
;...
proc r6040_phy_mode_chk
push ebx
;PHY Link Status Check
movzx eax, [r6040_private.phy_addr]
stdcall r6040_phy_read, eax, 1
test eax, 0x4
jnz @f
mov eax, 0x8000 ;Link Failed, full duplex
@@:
;PHY Chip Auto-Negotiation Status
movzx eax, [r6040_private.phy_addr]
stdcall r6040_phy_read, eax, 1
test eax, 0x0020
jz .force_mode
;Auto Negotuiation Mode
movzx eax, [r6040_private.phy_addr]
stdcall r6040_phy_read, eax, 5
mov ebx, eax
movzx eax, [r6040_private.phy_addr]
stdcall r6040_phy_read, eax, 4
and eax, ebx
test eax, 0x140
jz .ret_0
jmp .ret_0x8000
.force_mode:
;Force Mode
movzx eax, [r6040_private.phy_addr]
stdcall r6040_phy_read, eax, 0
test eax, 0x100
jz .ret_0
.ret_0x8000:
mov eax, 0x8000
pop ebx
ret
.ret_0:
xor eax, eax
pop ebx
ret
endp
;***************************************************************************
; Function
; r6040_rx
; Description
; polls card to see if there is a packet waiting
;
; Currently only supports one descriptor per packet, if packet is fragmented
; between multiple descriptors you will lose part of the packet
;***************************************************************************
r6040_poll:
push ebx ecx esi edi
xor eax, eax
mov [eth_rx_data_len], ax
movzx eax, [r6040_private.cur_rx]
mov ebx, eax
shl ebx, 5
mov cx, [ebx+r6040_rx_ring+r6040_x_head.status] ; Read the descriptor status
test cx, DSC_OWNER_MAC
jnz .out
test cx, DSC_RX_ERR ; Global error status set
jz .no_dsc_rx_err
;...
jmp .out
.no_dsc_rx_err:
; Packet successfully received
movzx ecx, [ebx+r6040_rx_ring+r6040_x_head.len]
and ecx, 0xFFF
sub ecx, 4 ; Do not count the CRC
mov [eth_rx_data_len], cx
mov esi, [ebx+r6040_rx_ring+r6040_x_head.skb_ptr]
push ecx
shr ecx, 2
mov edi, Ether_buffer
cld
rep movsd
pop ecx
and ecx, 3
rep movsb
or [ebx+r6040_rx_ring+r6040_x_head.status], DSC_OWNER_MAC
inc [r6040_private.cur_rx]
and [r6040_private.cur_rx], RX_RING_SIZE-1
xor eax, eax
.out:
pop edi esi ecx ebx
ret
;***************************************************************************
; Function
; r6040_transmit
; Description
; Transmits a packet of data via the ethernet card
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; size of packet in ecx
; pointer to packet data in esi
;
;***************************************************************************
r6040_transmit:
cmp ecx, MAX_BUF_SIZE
jg .out ; packet is too long
push edi esi ebx ecx
movzx eax, [r6040_private.cur_tx]
shl eax, 5
; DEBUGF 1,"R6040: TX buffer status: 0x%x, eax=%u\n", [eax + r6040_tx_ring + r6040_x_head.status]:4, eax
test [r6040_tx_ring + eax + r6040_x_head.status], 0x8000 ; check if buffer is available
jz .l3
push ecx esi
mov ecx, [timer_ticks]
add ecx, 100
.l2:
test [r6040_tx_ring + eax + r6040_x_head.status], 0x8000
jz .l5
cmp ecx, [timer_ticks]
jb .l4
mov esi, 10
call delay_ms
jmp .l2
.l4:
pop esi ecx
DEBUGF 1,"R6040: Send timeout\n"
jmp .out
.l5:
pop esi ecx
.l3:
push eax
mov esi, edi
; point to the current tx buffer
movzx edi, [r6040_private.cur_tx]
imul edi, MAX_BUF_SIZE
add edi, r6040_txb
lea eax, [edi - OS_BASE] ; real buffer address in eax
; copy destination address
movsd
movsw
; copy source address
mov esi, node_addr
movsd
movsw
; copy packet type
mov [edi], bx
add edi, 2
mov esi, [esp+8+4]
mov ecx, [esp+4]
; copy the packet data
push ecx
shr ecx, 2
rep movsd
pop ecx
and ecx, 3
rep movsb
pop edi
mov ecx, [esp]
add ecx, ETH_HLEN
cmp cx, ETH_ZLEN
jae @f
mov cx, ETH_ZLEN
@@:
mov [r6040_tx_ring + edi + r6040_x_head.len], cx
mov [r6040_tx_ring + edi + r6040_x_head.buf], eax
mov [r6040_tx_ring + edi + r6040_x_head.status], 0x8000
; Trigger the MAC to check the TX descriptor
mov ax, 0x01
mov edx, [io_addr]
add edx, MTPR
out dx, ax
inc [r6040_private.cur_tx]
and [r6040_private.cur_tx], TX_RING_SIZE-1
xor eax, eax
pop ecx ebx esi edi
.out:
ret
r6040_mac_address:
push eax ecx edx esi edi
; MAC operation register
mov ax, 1
mov edx, [io_addr]
add edx, MCR1
out dx, ax
; Reset MAC
mov ax, 2
mov edx, [io_addr]
add edx, MAC_SM
out dx, ax
; Reset internal state machine
xor ax, ax
out dx, ax
mov esi, 5
call delay_ms
; Restore MAC Address
mov ecx, 3
mov edi, node_addr
mov edx, [io_addr]
add edx, MID_0L
.mac:
in ax, dx
stosw
add edx, 2
dec ecx
jnz .mac
pop edi esi edx ecx eax
ret

View File

@ -1,976 +0,0 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; RTL8029.INC ;;
;; ;;
;; Ethernet driver for Menuet OS ;;
;; ;;
;; Version 0.2 31 July 2002 ;;
;; ;;
;; This driver is based on the ns8390 driver from ;;
;; the etherboot 5.0.6 project. The copyright statement is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; remaining parts Copyright 2002 Mike Hibbett, ;;
;; mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;; While this implementation handles only PCI bus RTL8029 ;;
;; hardware, it can be easily adapted to other NE2000 clone ;;
;; products. I just dont have any to try! ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision$
;********************************************************************
; Interface
; rtl8029_reset
; rtl8029_probe
; rtl8029_poll
; rtl8029_transmit
;
;********************************************************************
;**************************************************************************
; 8390 Register Definitions
;**************************************************************************
D8390_P0_COMMAND equ 0x00
D8390_P0_PSTART equ 0x01
D8390_P0_PSTOP equ 0x02
D8390_P0_BOUND equ 0x03
D8390_P0_TSR equ 0x04
D8390_P0_TPSR equ 0x04
D8390_P0_TBCR0 equ 0x05
D8390_P0_TBCR1 equ 0x06
D8390_P0_ISR equ 0x07
D8390_P0_RSAR0 equ 0x08
D8390_P0_RSAR1 equ 0x09
D8390_P0_RBCR0 equ 0x0A
D8390_P0_RBCR1 equ 0x0B
D8390_P0_RSR equ 0x0C
D8390_P0_RCR equ 0x0C
D8390_P0_TCR equ 0x0D
D8390_P0_DCR equ 0x0E
D8390_P0_IMR equ 0x0F
D8390_P1_COMMAND equ 0x00
D8390_P1_PAR0 equ 0x01
D8390_P1_PAR1 equ 0x02
D8390_P1_PAR2 equ 0x03
D8390_P1_PAR3 equ 0x04
D8390_P1_PAR4 equ 0x05
D8390_P1_PAR5 equ 0x06
D8390_P1_CURR equ 0x07
D8390_P1_MAR0 equ 0x08
D8390_COMMAND_PS0 equ 0x0 ; Page 0 select
D8390_COMMAND_PS1 equ 0x40 ; Page 1 select
D8390_COMMAND_PS2 equ 0x80 ; Page 2 select
D8390_COMMAND_RD2 equ 0x20 ; Remote DMA control
D8390_COMMAND_RD1 equ 0x10
D8390_COMMAND_RD0 equ 0x08
D8390_COMMAND_TXP equ 0x04 ; transmit packet
D8390_COMMAND_STA equ 0x02 ; start
D8390_COMMAND_STP equ 0x01 ; stop
D8390_COMMAND_RD2_STA equ 0x22
D8390_COMMAND_RD2_STP equ 0x21
D8390_COMMAND_RD1_STA equ 0x12
D8390_COMMAND_RD0_STA equ 0x0A
D8390_COMMAND_PS0_RD2_STP equ 0x21
D8390_COMMAND_PS1_RD2_STP equ 0x61
D8390_COMMAND_PS0_RD2_STA equ 0x22
D8390_COMMAND_PS0_TXP_RD2_STA equ 0x26
D8390_RCR_MON equ 0x20 ; monitor mode
D8390_DCR_FT1 equ 0x40
D8390_DCR_LS equ 0x08 ; Loopback select
D8390_DCR_WTS equ 0x01 ; Word transfer select
D8390_DCR_FT1_LS equ 0x48
D8390_DCR_WTS_FT1_LS equ 0x49
D8390_ISR_PRX equ 0x01 ; successful recv
D8390_ISR_PTX equ 0x02 ; successful xmit
D8390_ISR_RXE equ 0x04 ; receive error
D8390_ISR_TXE equ 0x08 ; transmit error
D8390_ISR_OVW equ 0x10 ; Overflow
D8390_ISR_CNT equ 0x20 ; Counter overflow
D8390_ISR_RDC equ 0x40 ; Remote DMA complete
D8390_ISR_RST equ 0x80 ; reset
D8390_RSTAT_PRX equ 0x01 ; successful recv
D8390_RSTAT_CRC equ 0x02 ; CRC error
D8390_RSTAT_FAE equ 0x04 ; Frame alignment error
D8390_RSTAT_OVER equ 0x08 ; FIFO overrun
D8390_TXBUF_SIZE equ 6
D8390_RXBUF_END equ 32
D8390_PAGE_SIZE equ 256
ETH_ALEN equ 6
ETH_HLEN equ 14
ETH_ZLEN equ 60
ETH_FRAME_LEN equ 1514
FLAG_PIO equ 0x01
FLAG_16BIT equ 0x02
ASIC_PIO equ 0
VENDOR_NONE equ 0
VENDOR_WD equ 1
VENDOR_NOVELL equ 2
VENDOR_3COM equ 3
NE_ASIC_OFFSET equ 0x10
NE_RESET equ 0x0F ; Used to reset card
NE_DATA equ 0x00 ; Used to read/write NIC mem
MEM_8192 equ 32
MEM_16384 equ 64
MEM_32768 equ 128
ISA_MAX_ADDR equ 0x400
uglobal
eth_flags:
db 0
eth_vendor:
db 0
eth_nic_base:
dw 0
eth_asic_base:
dw 0
eth_memsize:
db 0
eth_rx_start:
db 0
eth_tx_start:
db 0
eth_bmem:
dd 0
eth_rmem:
dd 0
romdata:
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
endg
iglobal
test_data:
db 'NE*000 memory',0
test_buffer:
db ' ',0
endg
uglobal
eth_type:
dw 0
pkthdr:
db 0,0,0,0 ; status, next, (short) len
pktoff:
dw 0
eth_rx_data_ptr:
dd 0
eth_tmp_len:
dw 0
endg
;***************************************************************************
; Function
; eth_pio_read
;
; Description
; Read a frame from the ethernet card via Programmed I/O
; src in ebx
; cnt in ecx
; dst in edi
;***************************************************************************
eth_pio_read:
mov al, [eth_flags]
and al, FLAG_16BIT
cmp al, 0
je epr_001
inc ecx
and ecx, 0xFFFFFFFE
epr_001:
mov al, D8390_COMMAND_RD2_STA
mov dx, [eth_nic_base]
add dx, D8390_P0_COMMAND
out dx, al
mov al, cl
mov dx, [eth_nic_base]
add dx, D8390_P0_RBCR0
out dx, al
mov al, ch
mov dx, [eth_nic_base]
add dx, D8390_P0_RBCR1
out dx, al
mov al, bl
mov dx, [eth_nic_base]
add dx, D8390_P0_RSAR0
out dx, al
mov al, bh
mov dx, [eth_nic_base]
add dx, D8390_P0_RSAR1
out dx, al
mov al, D8390_COMMAND_RD0_STA
mov dx, [eth_nic_base]
add dx, D8390_P0_COMMAND
out dx, al
mov dx, [eth_asic_base]
add dx, ASIC_PIO
mov al, [eth_flags]
and al, FLAG_16BIT
cmp al, 0
je epr_003
shr ecx, 1
epr_002:
; 2 bytes at a time
in ax, dx
mov [edi], ax
add edi, 2
loop epr_002
ret
epr_003:
; 1 byte at a time
in al, dx
mov [edi], al
inc edi
loop epr_003
ret
;***************************************************************************
; Function
; eth_pio_write
;
; Description
; writes a frame to the ethernet card via Programmed I/O
; dst in ebx
; cnt in ecx
; src in esi
;***************************************************************************
eth_pio_write:
mov al, [eth_flags]
and al, FLAG_16BIT
cmp al, 0
je epw_001
inc ecx
and ecx, 0xFFFFFFFE
epw_001:
mov al, D8390_COMMAND_RD2_STA
mov dx, [eth_nic_base]
add dx, D8390_P0_COMMAND
out dx, al
mov al, D8390_ISR_RDC
mov dx, [eth_nic_base]
add dx, D8390_P0_ISR
out dx, al
mov al, cl
mov dx, [eth_nic_base]
add dx, D8390_P0_RBCR0
out dx, al
mov al, ch
mov dx, [eth_nic_base]
add dx, D8390_P0_RBCR1
out dx, al
mov al, bl
mov dx, [eth_nic_base]
add dx, D8390_P0_RSAR0
out dx, al
mov al, bh
mov dx, [eth_nic_base]
add dx, D8390_P0_RSAR1
out dx, al
mov al, D8390_COMMAND_RD1_STA
mov dx, [eth_nic_base]
add dx, D8390_P0_COMMAND
out dx, al
mov dx, [eth_asic_base]
add dx, ASIC_PIO
mov al, [eth_flags]
and al, FLAG_16BIT
cmp al, 0
je epw_003
shr ecx, 1
epw_002:
; 2 bytes at a time
mov ax, [esi]
add esi, 2
out dx, ax
loop epw_002
jmp epw_004
epw_003:
; 1 byte at a time
mov al, [esi]
inc esi
out dx, al
loop epw_003
epw_004:
mov dx, [eth_nic_base]
add dx, D8390_P0_ISR
epw_005:
in al, dx
and al, D8390_ISR_RDC
cmp al, D8390_ISR_RDC
jne epw_005
ret
;***************************************************************************
; Function
; rtl8029_reset
; Description
; Place the chip (ie, the ethernet card) into a virgin state
; No inputs
; All registers destroyed
;
;***************************************************************************
rtl8029_reset:
mov bx, [eth_nic_base]
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS0_RD2_STP
out dx, al
mov dx, bx
add dx, D8390_P0_DCR
mov al, [eth_flags]
and al, FLAG_16BIT
cmp al, FLAG_16BIT
jne nsr_001
mov al, 0x49
jmp nsr_002
nsr_001:
mov al, 0x48
nsr_002:
out dx, al
xor al, al
mov dx, bx
add dx, D8390_P0_RBCR0
out dx, al
mov dx, bx
add dx, D8390_P0_RBCR1
out dx, al
mov dx, bx
add dx, D8390_P0_RCR
mov al, 0x20
out dx, al
mov dx, bx
add dx, D8390_P0_TCR
mov al, 2
out dx, al
mov dx, bx
add dx, D8390_P0_TPSR
mov al, [eth_tx_start]
out dx, al
mov dx, bx
add dx, D8390_P0_PSTART
mov al, [eth_rx_start]
out dx, al
mov dx, bx
add dx, D8390_P0_PSTOP
mov al, [eth_memsize]
out dx, al
mov dx, bx
add dx, D8390_P0_BOUND
mov al, [eth_memsize]
dec al
out dx, al
mov dx, bx
add dx, D8390_P0_ISR
mov al, 0xff
out dx, al
mov dx, bx
add dx, D8390_P0_IMR
xor al, al
out dx, al
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS1_RD2_STP
out dx, al
mov dx, bx
add dx, D8390_P1_PAR0
mov esi, node_addr
mov ecx, ETH_ALEN
nsr_003:
mov al, [esi]
out dx, al
inc esi
inc dx
loop nsr_003
mov dx, bx
add dx, D8390_P1_MAR0
mov ecx, ETH_ALEN
mov al, 0xff
nsr_004:
out dx, al
inc dx
loop nsr_004
mov dx, bx
add dx, D8390_P1_CURR
mov al, [eth_rx_start]
out dx, al
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS0_RD2_STA
out dx, al
mov dx, bx
add dx, D8390_P0_ISR
mov al, 0xff
out dx, al
mov dx, bx
add dx, D8390_P0_TCR
mov al, 0
out dx, al
mov dx, bx
add dx, D8390_P0_RCR
mov al, 4
out dx, al
ret
;***************************************************************************
; Function
; rtl8029_probe
; Description
; Searches for an ethernet card, enables it and clears the rx buffer
; If a card was found, it enables the ethernet -> TCPIP link
;
;***************************************************************************
rtl8029_probe:
mov eax, [io_addr]
mov [eth_nic_base], ax ; The IO address space is 16 bit only
mov al, VENDOR_NONE
mov [eth_vendor], al
mov al, [eth_vendor]
cmp al, VENDOR_NONE
jne ep_check_have_vendor
xor eax, eax
mov [eth_bmem], eax
mov al, FLAG_PIO
mov [eth_flags], al
mov ax, [eth_nic_base]
add ax, NE_ASIC_OFFSET
mov [eth_asic_base], ax
mov al, MEM_16384
mov [eth_memsize], al
mov al, 32
mov [eth_tx_start], al
add al, D8390_TXBUF_SIZE
mov [eth_rx_start], al
mov dx, [eth_asic_base]
add dx, NE_RESET
in al, dx
out dx, al
in al, 0x84
mov bx, [eth_nic_base]
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_RD2_STP
out dx, al
mov dx, bx
add dx, D8390_P0_RCR
mov al, D8390_RCR_MON
out dx, al
mov dx, bx
add dx, D8390_P0_DCR
mov al, D8390_DCR_FT1_LS
out dx, al
mov dx, bx
add dx, D8390_P0_PSTART
mov al, MEM_8192
out dx, al
mov dx, bx
add dx, D8390_P0_PSTOP
mov al, MEM_16384
out dx, al
mov esi, test_data
mov ebx, 8192
mov ecx, 14
call eth_pio_write
mov ebx, 8192
mov ecx, 14
mov edi, test_buffer
call eth_pio_read
mov esi, test_buffer
mov edi, test_data
mov ecx, 13
cld
rep cmpsb
je ep_set_vendor
mov al, [eth_flags]
or al, FLAG_16BIT
mov [eth_flags], al
mov al, MEM_32768
mov [eth_memsize], al
mov al, 64
mov [eth_tx_start], al
add al, D8390_TXBUF_SIZE
mov [eth_rx_start], al
mov bx, [eth_nic_base]
mov dx, bx
add dx, D8390_P0_DCR
mov al, D8390_DCR_WTS_FT1_LS
out dx, al
mov dx, bx
add dx, D8390_P0_PSTART
mov al, MEM_16384
out dx, al
mov dx, bx
add dx, D8390_P0_PSTOP
mov al, MEM_32768
out dx, al
mov esi, test_data
mov ebx, 16384
mov ecx, 14
call eth_pio_write
mov ebx, 16384
mov ecx, 14
mov edi, test_buffer
call eth_pio_read
mov esi, test_buffer
mov edi, test_data
mov ecx, 13
cld
rep cmpsb
ep_set_vendor:
; this bit is odd - probably left over from my hacking
mov ax, [eth_nic_base]
cmp ax, 0
je rtl8029_exit
cmp ax, ISA_MAX_ADDR
jbe ep_001
mov al, [eth_flags]
or al, FLAG_16BIT
mov [eth_flags], al
ep_001:
mov al, VENDOR_NOVELL
mov [eth_vendor], al
mov ebx, 0
mov ecx, 16
mov edi, romdata
call eth_pio_read
mov ecx, ETH_ALEN
mov esi, romdata
mov edi, node_addr
mov bl, [eth_flags]
and bl, FLAG_16BIT
ep_002:
mov al, [esi]
mov [edi], al
inc edi
inc esi
cmp bl, FLAG_16BIT
jne ep_003
inc esi
ep_003:
loop ep_002
ep_check_have_vendor:
mov al, [eth_vendor]
cmp al, VENDOR_NONE
je rtl8029_exit
cmp al, VENDOR_3COM
je ep_reset_card
mov eax, [eth_bmem]
mov [eth_rmem], eax
ep_reset_card:
; Reset the card
call rtl8029_reset
; Indicate that we have successfully reset the card
mov eax, [pci_data]
mov [eth_status], eax
rtl8029_exit:
ret
;***************************************************************************
; Function
; rtl8029_poll
;
; Description
; Polls the ethernet card for a received packet
; Received data, if any, ends up in Ether_buffer
;
;***************************************************************************
rtl8029_poll:
mov eax, Ether_buffer
mov [eth_rx_data_ptr], eax
mov bx, [eth_nic_base]
mov dx, bx
add dx, D8390_P0_RSR
in al, dx
and al, D8390_RSTAT_PRX
cmp al, D8390_RSTAT_PRX
jne nsp_exit
mov dx, bx
add dx, D8390_P0_BOUND
in al, dx
inc al
cmp al, [eth_memsize]
jb nsp_001
mov al, [eth_rx_start]
nsp_001:
mov ch, al
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS1
out dx, al
mov dx, bx
add dx, D8390_P1_CURR
in al, dx ; get current page
mov cl, al
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS0
out dx, al
cmp cl, [eth_memsize]
jb nsp_002
mov cl, [eth_rx_start]
nsp_002:
cmp cl, ch
je nsp_exit
xor ax, ax
mov ah, ch
mov [pktoff], ax
mov al, [eth_flags]
and al, FLAG_PIO
cmp al, FLAG_PIO
jne nsp_003
movzx ebx, word [pktoff]
mov edi, pkthdr
mov ecx, 4
call eth_pio_read
jmp nsp_004
nsp_003:
mov edi, [eth_rmem]
movzx eax, word [pktoff]
add edi, eax
mov eax, [edi]
mov [pkthdr], eax
nsp_004:
mov ax, [pktoff]
add ax, 4
mov [pktoff], ax
mov ax, [pkthdr + 2]
sub ax, 4
mov [eth_tmp_len], ax
cmp ax, ETH_ZLEN
jb nsp_exit
cmp ax, ETH_FRAME_LEN
ja nsp_exit
mov al, [pkthdr]
and al, D8390_RSTAT_PRX
cmp al, D8390_RSTAT_PRX
jne nsp_exit
; Right, we can now get the data
mov ax, [eth_tmp_len]
mov [eth_rx_data_len], ax
xor ebx, ebx
mov bh, [eth_memsize]
sub bx, [pktoff]
cmp [eth_tmp_len], bx
jbe nsp_005
mov al, [eth_flags]
and al, FLAG_PIO
cmp al, FLAG_PIO
jne nsp_006
push ebx
mov ecx, ebx
xor ebx, ebx
mov bx, [pktoff]
mov edi, [eth_rx_data_ptr]
call eth_pio_read
pop ebx
jmp nsp_007
nsp_006:
; Not implemented, as we are using PIO mode on this card
nsp_007:
xor ax, ax
mov ah, [eth_rx_start]
mov [pktoff], ax
mov eax, [eth_rx_data_ptr]
add eax, ebx
mov [eth_rx_data_ptr], eax
mov ax, [eth_tmp_len]
sub ax, bx
mov [eth_tmp_len], ax
nsp_005:
mov al, [eth_flags]
and al, FLAG_PIO
cmp al, FLAG_PIO
jne nsp_008
xor ebx, ebx
mov bx, [pktoff]
xor ecx, ecx
mov cx, [eth_tmp_len]
mov edi, [eth_rx_data_ptr]
call eth_pio_read
jmp nsp_009
nsp_008:
; Not implemented, as we are using PIO mode on this card
nsp_009:
mov al, [pkthdr+1]
cmp al, [eth_rx_start]
jne nsp_010
mov al, [eth_memsize]
nsp_010:
mov dx, [eth_nic_base]
add dx, D8390_P0_BOUND
dec al
out dx, al
nsp_exit:
ret
;***************************************************************************
; Function
; rtl8029_transmit
;
; Description
; Transmits a packet of data via the ethernet card
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; size of packet in ecx
; pointer to packet data in esi
;
;***************************************************************************
rtl8029_transmit:
mov [eth_type], bx
pusha
mov esi, edi
xor bx, bx
mov bh, [eth_tx_start]
mov ecx, ETH_ALEN
call eth_pio_write
mov esi, node_addr
xor bx, bx
mov bh, [eth_tx_start]
add bx, ETH_ALEN
mov ecx, ETH_ALEN
call eth_pio_write
mov esi, eth_type
xor bx, bx
mov bh, [eth_tx_start]
add bx, ETH_ALEN
add bx, ETH_ALEN
mov ecx, 2
call eth_pio_write
popa
xor bx, bx
mov bh, [eth_tx_start]
add bx, ETH_HLEN
push ecx
call eth_pio_write
pop ecx
add ecx, ETH_HLEN
cmp ecx, ETH_ZLEN
jae nst_001
mov ecx, ETH_ZLEN
nst_001:
push ecx
mov bx, [eth_nic_base]
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS0_RD2_STA
out dx, al
mov dx, bx
add dx, D8390_P0_TPSR
mov al, [eth_tx_start]
out dx, al
pop ecx
mov dx, bx
add dx, D8390_P0_TBCR0
mov al, cl
out dx, al
mov dx, bx
add dx, D8390_P0_TBCR1
mov al, ch
out dx, al
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS0_TXP_RD2_STA
out dx, al
ret

View File

@ -1,624 +0,0 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; RTL8139.INC ;;
;; ;;
;; Ethernet driver for Menuet OS ;;
;; ;;
;; Version 0.2 11 August 2003 ;;
;; ;;
;; Driver for chips of RealTek 8139 family ;;
;; References: ;;
;; www.realtek.com.hw - data sheets ;;
;; rtl8139.c - linux driver ;;
;; 8139too.c - linux driver ;;
;; ethernet driver template by Mike Hibbett ;;
;; ;;
;; The copyright statement is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; Copyright 2003 Endre Kozma, ;;
;; endre.kozma@axelero.hu ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;; 10.01.2007 Bugfix for l8139_transmit from Paolo Franchetti ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision$
ETH_ALEN equ 6
ETH_HLEN equ (2 * ETH_ALEN + 2)
ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for
; mininmum 64bytes frame length
PCI_REG_COMMAND equ 0x04 ; command register
PCI_BIT_PIO equ 0 ; bit0: io space control
PCI_BIT_MMIO equ 1 ; bit1: memory space control
PCI_BIT_MASTER equ 2 ; bit2: device acts as a PCI master
RTL8139_REG_MAR0 equ 0x08 ; multicast filter register 0
RTL8139_REG_MAR4 equ 0x0c ; multicast filter register 4
RTL8139_REG_TSD0 equ 0x10 ; transmit status of descriptor
RTL8139_REG_TSAD0 equ 0x20 ; transmit start address of descriptor
RTL8139_REG_RBSTART equ 0x30 ; RxBuffer start address
RTL8139_REG_COMMAND equ 0x37 ; command register
RTL8139_REG_CAPR equ 0x38 ; current address of packet read
RTL8139_REG_IMR equ 0x3c ; interrupt mask register
RTL8139_REG_ISR equ 0x3e ; interrupt status register
RTL8139_REG_TXCONFIG equ 0x40 ; transmit configuration register
RTL8139_REG_TXCONFIG_0 equ 0x40 ; transmit configuration register 0
RTL8139_REG_TXCONFIG_1 equ 0x41 ; transmit configuration register 1
RTL8139_REG_TXCONFIG_2 equ 0x42 ; transmit configuration register 2
RTL8139_REG_TXCONFIG_3 equ 0x43 ; transmit configuration register 3
RTL8139_REG_RXCONFIG equ 0x44 ; receive configuration register 0
RTL8139_REG_RXCONFIG_0 equ 0x44 ; receive configuration register 0
RTL8139_REG_RXCONFIG_1 equ 0x45 ; receive configuration register 1
RTL8139_REG_RXCONFIG_2 equ 0x46 ; receive configuration register 2
RTL8139_REG_RXCONFIG_3 equ 0x47 ; receive configuration register 3
RTL8139_REG_MPC equ 0x4c ; missed packet counter
RTL8139_REG_9346CR equ 0x50 ; serial eeprom 93C46 command register
RTL8139_REG_CONFIG1 equ 0x52 ; configuration register 1
RTL8139_REG_CONFIG4 equ 0x5a ; configuration register 4
RTL8139_REG_HLTCLK equ 0x5b ; undocumented halt clock register
RTL8139_REG_BMCR equ 0x62 ; basic mode control register
RTL8139_REG_ANAR equ 0x66 ; auto negotiation advertisement register
; 5.1 packet header
RTL8139_BIT_RUNT equ 4 ; total packet length < 64 bytes
RTL8139_BIT_LONG equ 3 ; total packet length > 4k
RTL8139_BIT_CRC equ 2 ; crc error occured
RTL8139_BIT_FAE equ 1 ; frame alignment error occured
RTL8139_BIT_ROK equ 0 ; received packet is ok
; 5.4 command register
RTL8139_BIT_RST equ 4 ; reset bit
RTL8139_BIT_RE equ 3 ; receiver enabled
RTL8139_BIT_TE equ 2 ; transmitter enabled
RTL8139_BIT_BUFE equ 0 ; rx buffer is empty, no packet stored
; 5.6 interrupt status register
RTL8139_BIT_ISR_TOK equ 2 ; transmit ok
RTL8139_BIT_ISR_RER equ 1 ; receive error interrupt
RTL8139_BIT_ISR_ROK equ 0 ; receive ok
; 5.7 transmit configyration register
RTL8139_BIT_TX_MXDMA equ 8 ; Max DMA burst size per Tx DMA burst
RTL8139_BIT_TXRR equ 4 ; Tx Retry count 16+(TXRR*16)
; 5.8 receive configuration register
RTL8139_BIT_RXFTH equ 13 ; Rx fifo threshold
RTL8139_BIT_RBLEN equ 11 ; Ring buffer length indicator
RTL8139_BIT_RX_MXDMA equ 8 ; Max DMA burst size per Rx DMA burst
RTL8139_BIT_NOWRAP equ 7 ; transfered data wrapping
RTL8139_BIT_9356SEL equ 6 ; eeprom selector 9346/9356
RTL8139_BIT_AER equ 5 ; accept error packets
RTL8139_BIT_AR equ 4 ; accept runt packets
RTL8139_BIT_AB equ 3 ; accept broadcast packets
RTL8139_BIT_AM equ 2 ; accept multicast packets
RTL8139_BIT_APM equ 1 ; accept physical match packets
RTL8139_BIT_AAP equ 0 ; accept all packets
; 5.9 93C46/93C56 command register
RTL8139_BIT_93C46_EEM1 equ 7 ; RTL8139 eeprom operating mode1
RTL8139_BIT_93C46_EEM0 equ 6 ; RTL8139 eeprom operating mode0
RTL8139_BIT_93C46_EECS equ 3 ; chip select
RTL8139_BIT_93C46_EESK equ 2 ; serial data clock
RTL8139_BIT_93C46_EEDI equ 1 ; serial data input
RTL8139_BIT_93C46_EEDO equ 0 ; serial data output
; 5.11 configuration register 1
RTL8139_BIT_LWACT equ 4 ; see RTL8139_REG_CONFIG1
RTL8139_BIT_SLEEP equ 1 ; sleep bit at older chips
RTL8139_BIT_PWRDWN equ 0 ; power down bit at older chips
RTL8139_BIT_PMEn equ 0 ; power management enabled
; 5.14 configuration register 4
RTL8139_BIT_LWPTN equ 2 ; see RTL8139_REG_CONFIG4
; 6.2 transmit status register
RTL8139_BIT_ERTXTH equ 16 ; early TX threshold
RTL8139_BIT_TOK equ 15 ; transmit ok
RTL8139_BIT_OWN equ 13 ; tx DMA operation is completed
; 6.18 basic mode control register
RTL8139_BIT_ANE equ 12 ; auto negotiation enable
; 6.20 auto negotiation advertisement register
RTL8139_BIT_TXFD equ 8 ; 100base-T full duplex
RTL8139_BIT_TX equ 7 ; 100base-T
RTL8139_BIT_10FD equ 6 ; 10base-T full duplex
RTL8139_BIT_10 equ 5 ; 10base-T
RTL8139_BIT_SELECTOR equ 0 ; binary encoded selector CSMA/CD=00001
; RX/TX buffer size
RTL8139_RBLEN equ 0 ; 0==8K 1==16k 2==32k 3==64k
RTL8139_RX_BUFFER_SIZE equ (8192 shl RTL8139_RBLEN)
MAX_ETH_FRAME_SIZE equ 1516 ; exactly 1514 wthout CRC
RTL8139_NUM_TX_DESC equ 4
RTL8139_TX_BUFFER_SIZE equ (MAX_ETH_FRAME_SIZE * RTL8139_NUM_TX_DESC)
RTL8139_TXRR equ 8 ; total retries = 16+(TXRR*16)
RTL8139_TX_MXDMA equ 6 ; 0==16 1==32 2==64 3==128
; 4==256 5==512 6==1024 7==2048
RTL8139_ERTXTH equ 8 ; in unit of 32 bytes e.g:(8*32)=256
RTL8139_RX_MXDMA equ 7 ; 0==16 1==32 2==64 3==128
; 4==256 5==512 6==1024 7==unlimited
RTL8139_RXFTH equ 7 ; 0==16 1==32 2==64 3==128
; 4==256 5==512 6==1024 7==no threshold
RTL8139_RX_CONFIG equ ((RTL8139_RBLEN shl RTL8139_BIT_RBLEN) \
or (RTL8139_RX_MXDMA shl RTL8139_BIT_RX_MXDMA) \
or (1 shl RTL8139_BIT_NOWRAP) \
or (RTL8139_RXFTH shl RTL8139_BIT_RXFTH) \
or (1 shl RTL8139_BIT_AB) or (1 shl RTL8139_BIT_APM) \
or (1 shl RTL8139_BIT_AER) or (1 shl RTL8139_BIT_AR) \
or (1 shl RTL8139_BIT_AM))
RTL8139_TX_TIMEOUT equ 30 ; 300 milliseconds timeout
EE_93C46_REG_ETH_ID equ 7 ; MAC offset
EE_93C46_READ_CMD equ (6 shl 6) ; 110b + 6bit address
EE_93C56_READ_CMD equ (6 shl 8) ; 110b + 8bit address
EE_93C46_CMD_LENGTH equ 9 ; start bit + cmd + 6bit address
EE_93C56_CMD_LENGTH equ 11 ; start bit + cmd + 8bit ddress
VER_RTL8139 equ 1100000b
VER_RTL8139A equ 1110000b
; VER_RTL8139AG equ 1110100b
VER_RTL8139B equ 1111000b
VER_RTL8130 equ VER_RTL8139B
VER_RTL8139C equ 1110100b
VER_RTL8100 equ 1111010b
VER_RTL8100B equ 1110101b
VER_RTL8139D equ VER_RTL8100B
VER_RTL8139CP equ 1110110b
VER_RTL8101 equ 1110111b
IDX_RTL8139 equ 0
IDX_RTL8139A equ 1
IDX_RTL8139B equ 2
IDX_RTL8139C equ 3
IDX_RTL8100 equ 4
IDX_RTL8139D equ 5
IDX_RTL8139D equ 6
IDX_RTL8101 equ 7
; These two must be 4 byte aligned ( which they are )
rtl8139_rx_buff equ eth_data_start
rtl8139_tx_buff equ rtl8139_rx_buff + (RTL8139_RX_BUFFER_SIZE + MAX_ETH_FRAME_SIZE)
uglobal
align 4
rtl8139_rx_buff_offset:
dd 0
curr_tx_desc dd 0
endg
iglobal
hw_ver_array:
db VER_RTL8139, VER_RTL8139A, VER_RTL8139B, VER_RTL8139C
db VER_RTL8100, VER_RTL8139D, VER_RTL8139CP, VER_RTL8101
HW_VER_ARRAY_SIZE = $-hw_ver_array
endg
uglobal
hw_ver_id:
db 0
endg
;***************************************************************************
; Function
; rtl8139_probe
; Description
; Searches for an ethernet card, enables it and clears the rx buffer
; If a card was found, it enables the ethernet -> TCPIP link
; Destroyed registers
; eax, ebx, ecx, edx
;
;***************************************************************************
rtl8139_probe:
; enable the device
mov al, 2
mov ah, [pci_bus]
mov bh, [pci_dev]
mov bl, PCI_REG_COMMAND
call pci_read_reg
mov cx, ax
or cl, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO)
and cl, not (1 shl PCI_BIT_MMIO)
mov al, 2
mov ah, [pci_bus]
mov bh, [pci_dev]
mov bl, PCI_REG_COMMAND
call pci_write_reg
; get chip version
mov edx, [io_addr]
add edx, RTL8139_REG_TXCONFIG_2
in ax, dx
shr ah, 2
shr ax, 6
and al, 01111111b
mov ecx, HW_VER_ARRAY_SIZE-1
.chip_ver_loop:
cmp al, [hw_ver_array+ecx]
je .chip_ver_found
dec ecx
jns .chip_ver_loop
xor cl, cl ; default RTL8139
.chip_ver_found:
mov [hw_ver_id], cl
; wake up the chip
mov edx, [io_addr]
add edx, RTL8139_REG_HLTCLK
mov al, 'R' ; run the clock
out dx, al
; unlock config and BMCR registers
add edx, RTL8139_REG_9346CR - RTL8139_REG_HLTCLK
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0)
out dx, al
; enable power management
add edx, RTL8139_REG_CONFIG1 - RTL8139_REG_9346CR
in al, dx
cmp byte [hw_ver_id], IDX_RTL8139B
jl .old_chip
; set LWAKE pin to active high (default value).
; it is for Wake-On-LAN functionality of some motherboards.
; this signal is used to inform the motherboard to execute a wake-up process.
; only at newer chips.
or al, (1 shl RTL8139_BIT_PMEn)
and al, not (1 shl RTL8139_BIT_LWACT)
out dx, al
add edx, RTL8139_REG_CONFIG4 - RTL8139_REG_CONFIG1
in al, dx
and al, not (1 shl RTL8139_BIT_LWPTN)
out dx, al
jmp .finish_wake_up
.old_chip:
; wake up older chips
and al, not ((1 shl RTL8139_BIT_SLEEP) or (1 shl RTL8139_BIT_PWRDWN))
out dx, al
.finish_wake_up:
; lock config and BMCR registers
xor al, al
mov edx, [io_addr]
add edx, RTL8139_REG_9346CR
out dx, al
;***************************************************************************
; Function
; rt8139_reset
; Description
; Place the chip (ie, the ethernet card) into a virgin state
; Destroyed registers
; eax, ebx, ecx, edx
;
;***************************************************************************
rtl8139_reset:
mov edx, [io_addr]
add edx, RTL8139_REG_COMMAND
mov al, 1 shl RTL8139_BIT_RST
out dx, al
mov cx, 1000 ; wait no longer for the reset
.wait_for_reset:
in al, dx
test al, 1 shl RTL8139_BIT_RST
jz .reset_completed ; RST remains 1 during reset
dec cx
jns .wait_for_reset
.reset_completed:
; get MAC (hardware address)
mov ecx, 2
.mac_read_loop:
lea eax, [EE_93C46_REG_ETH_ID+ecx]
push ecx
call rtl8139_read_eeprom
pop ecx
mov [node_addr+ecx*2], ax
dec ecx
jns .mac_read_loop
; unlock config and BMCR registers
mov edx, [io_addr]
add edx, RTL8139_REG_9346CR
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0)
out dx, al
; initialize multicast registers (no filtering)
mov eax, 0xffffffff
add edx, RTL8139_REG_MAR0 - RTL8139_REG_9346CR
out dx, eax
add edx, RTL8139_REG_MAR4 - RTL8139_REG_MAR0
out dx, eax
; enable Rx/Tx
mov al, (1 shl RTL8139_BIT_RE) or (1 shl RTL8139_BIT_TE)
add edx, RTL8139_REG_COMMAND - RTL8139_REG_MAR4
out dx, al
; 32k Rxbuffer, unlimited dma burst, no wrapping, no rx threshold
; accept broadcast packets, accept physical match packets
mov eax, RTL8139_RX_CONFIG
add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND
out dx, eax
; 1024 bytes DMA burst, total retries = 16 + 8 * 16 = 144
mov eax, (RTL8139_TX_MXDMA shl RTL8139_BIT_TX_MXDMA) \
or (RTL8139_TXRR shl RTL8139_BIT_TXRR)
add edx, RTL8139_REG_TXCONFIG - RTL8139_REG_RXCONFIG
out dx, eax
; enable auto negotiation
add edx, RTL8139_REG_BMCR - RTL8139_REG_TXCONFIG
in ax, dx
or ax, (1 shl RTL8139_BIT_ANE)
out dx, ax
; set auto negotiation advertisement
add edx, RTL8139_REG_ANAR - RTL8139_REG_BMCR
in ax, dx
or ax, (1 shl RTL8139_BIT_SELECTOR) or (1 shl RTL8139_BIT_10) \
or (1 shl RTL8139_BIT_10FD) or (1 shl RTL8139_BIT_TX) \
or (1 shl RTL8139_BIT_TXFD)
out dx, ax
; lock config and BMCR registers
xor eax, eax
add edx, RTL8139_REG_9346CR - RTL8139_REG_ANAR
out dx, al
; init RX/TX pointers
mov [rtl8139_rx_buff_offset], eax
mov [curr_tx_desc], eax
; clear missing packet counter
add edx, RTL8139_REG_MPC - RTL8139_REG_9346CR
out dx, eax
; disable all interrupts
add edx, RTL8139_REG_IMR - RTL8139_REG_MPC
out dx, ax
; set RxBuffer address, init RX buffer offset, init TX ring
mov eax, rtl8139_rx_buff ; simba
sub eax, OS_BASE
add edx, RTL8139_REG_RBSTART - RTL8139_REG_IMR
out dx, eax
; Indicate that we have successfully reset the card
mov eax, [pci_data]
mov [eth_status], eax
ret
;***************************************************************************
; Function
; rtl8139_read_eeprom
; Description
; reads eeprom type 93c46 and 93c56
; Parameters
; al - word to be read (6bit in case of 93c46 and 8bit otherwise)
; Return value
; ax - word read in
; Destroyed register(s)
; eax, cx, ebx, edx
;
;***************************************************************************
rtl8139_read_eeprom:
movzx ebx, al
mov edx, [io_addr]
add edx, RTL8139_REG_RXCONFIG
in al, dx
test al, (1 shl RTL8139_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:
add edx, RTL8139_REG_9346CR - RTL8139_REG_RXCONFIG_0
; mov al, (1 shl RTL8139_BIT_93C46_EEM1)
; out dx, al
mov al, (1 shl RTL8139_BIT_93C46_EEM1) \
or (1 shl RTL8139_BIT_93C46_EECS) ; wake up the eeprom
out dx, al
.cmd_loop:
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS)
bt bx, cx
jnc .zero_bit
or al, (1 shl RTL8139_BIT_93C46_EEDI)
.zero_bit:
out dx, al
; push eax
; in eax, dx ; eeprom delay
; pop eax
or al, (1 shl RTL8139_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 RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS)
out dx, al
mov cl, 0xf
.read_loop:
shl ebx, 1
mov al, (1 shl RTL8139_BIT_93C46_EEM1) \
or (1 shl RTL8139_BIT_93C46_EECS) \
or (1 shl RTL8139_BIT_93C46_EESK)
out dx, al
; in eax, dx ; eeprom delay
in al, dx
and al, (1 shl RTL8139_BIT_93C46_EEDO)
jz .dont_set
inc ebx
.dont_set:
mov al, (1 shl RTL8139_BIT_93C46_EEM1) \
or (1 shl RTL8139_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
ret
;***************************************************************************
; Function
; rtl8139_transmit
; Description
; Transmits a packet of data via the ethernet card
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; Size of packet in ecx
; Pointer to packet data in esi
; Destroyed registers
; eax, edx, esi, edi
; ToDo
; for waiting of timeout the rtl8139 internal timer
; should be used
;
;***************************************************************************
rtl8139_transmit:
cmp ecx, MAX_ETH_FRAME_SIZE
jg .finish ; packet is too long
push ecx
; check descriptor
mov ecx, [curr_tx_desc]
mov edx, [io_addr]
lea edx, [edx+ecx*4+RTL8139_REG_TSD0]
push edx ebx
in ax, dx
test ax, 0x1fff ; or no size given
jz .send_packet
and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN)
cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN)
jz .send_packet
; wait for timeout
mov ebx, RTL8139_TX_TIMEOUT
mov eax, 0x5 ; delay x/100 secs
int 0x40
in ax, dx
and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN)
cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN)
jz .send_packet
; chip hung, reset it
call rtl8139_reset
; reset the card
.send_packet:
; calculate tx_buffer address
pop ebx
push esi
mov eax, MAX_ETH_FRAME_SIZE
mul dword [curr_tx_desc]
mov esi, edi
lea edi, [rtl8139_tx_buff+eax]
mov eax, edi
cld
; copy destination address
movsd
movsw
; copy source address
mov esi, node_addr
movsd
movsw
; copy packet type
mov [edi], bx
add edi, 2
; copy the packet data
pop esi edx ecx
push ecx
shr ecx, 2
rep movsd
pop ecx
push ecx
and ecx, 3
rep movsb
; set address
sub eax, OS_BASE
add edx, RTL8139_REG_TSAD0 - RTL8139_REG_TSD0
out dx, eax
; set size and early threshold
pop eax ; pick up the size
add eax, ETH_HLEN
cmp eax, ETH_ZLEN
jnc .no_pad
mov eax, ETH_ZLEN
.no_pad:
or eax, (RTL8139_ERTXTH shl RTL8139_BIT_ERTXTH)
add edx, RTL8139_REG_TSD0 - RTL8139_REG_TSAD0
out dx, eax
; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ...
inc dword [curr_tx_desc]
and dword [curr_tx_desc], 3
.finish:
ret
;***************************************************************************
; Function
; rtl8139_poll
;
; Description
; Polls the ethernet card for a received packet
; Received data, if any, ends up in Ether_buffer
; Destroyed register(s)
; eax, edx, ecx
;
;***************************************************************************
rtl8139_poll:
mov word [eth_rx_data_len], 0
mov edx, [io_addr]
add edx, RTL8139_REG_COMMAND
in al, dx
test al, (1 shl RTL8139_BIT_BUFE)
jnz .finish
; new packet received copy it from rx_buffer into Ether_buffer
mov eax, rtl8139_rx_buff
add eax, [rtl8139_rx_buff_offset]
; check if packet is ok
test byte [eax], (1 shl RTL8139_BIT_ROK)
jz .reset_rx
; packet is ok copy it into the Ether_buffer
movzx ecx, word [eax+2] ; packet length
sub ecx, 4 ; don't copy CRC
mov word [eth_rx_data_len], cx
push ecx
shr ecx, 2 ; first copy dword-wise
lea esi, [eax+4] ; don't copy the packet header
mov edi, Ether_buffer
cld
rep movsd ; copy the dwords
pop ecx
and ecx, 3
rep movsb ; copy the rest bytes
; update rtl8139_rx_buff_offset
movzx eax, word [eax+2] ; packet length
add eax, [rtl8139_rx_buff_offset]
add eax, 4+3 ; packet header is 4 bytes long + dword alignment
and eax, not 3 ; dword alignment
cmp eax, RTL8139_RX_BUFFER_SIZE
jl .no_wrap
sub eax, RTL8139_RX_BUFFER_SIZE
.no_wrap:
mov [rtl8139_rx_buff_offset], eax
; update CAPR register
sub eax, 0x10 ; value 0x10 is a constant for CAPR
add edx, RTL8139_REG_CAPR - RTL8139_REG_COMMAND
out dx, ax
.finish:
; clear active interrupt sources
mov edx, [io_addr]
add edx, RTL8139_REG_ISR
in ax, dx
out dx, ax
ret
.reset_rx:
in al, dx ; read command register
push eax
and al, not (1 shl RTL8139_BIT_RE)
out dx, al
pop eax
out dx, al
add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND
mov ax, RTL8139_RX_CONFIG
out dx, ax
ret
rtl8139_cable:
pusha
mov edx, [io_addr]
add edx, 0x58
in al, dx
test al, 1 SHL 2
jnz .notconnected
popa
xor al, al
inc al
ret
.notconnected:
popa
xor al, al
ret

File diff suppressed because it is too large Load Diff

View File

@ -1,525 +0,0 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ETHERNET.INC ;;
;; ;;
;; Ethernet network layer for Menuet OS ;;
;; ;;
;; This file contains the following: ;;
;; PCI bus scanning for valid devices ;;
;; Table of supported ethernet drivers ;;
;; Code to identify and activate a supported driver ;;
;; ARP handler ;;
;; Driver interface to the IP layer ;;
;; Gateway support ;;
;; ;;
;; Individual driver files are included here ;;
;; ;;
;; The PCI bus scanning code was ported from the etherboot ;;
;; 5.0.6 project. The copyright statement for that code is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; remaining parts Copyright 2002 Mike Hibbett ;;
;; mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision$
;********************************************************************
; Interface
; ethernet_driver called by stack_handler in stack.inc
; eth_probe called by app_stack_handler in stack.inc
;
;********************************************************************
ETHER_IP equ 0x0008 ; Reversed from 0800 for intel
ETHER_ARP equ 0x0608 ; Reversed from 0806 for intel
ETHER_RARP equ 0x3580
struc ETH_FRAME
{ .DstMAC dp ? ;destination MAC-address [6 bytes]
.SrcMAC dp ? ;source MAC-address [6 bytes]
.Type dw ? ;type of the upper-layer protocol [2 bytes]
.Data db ? ;data [46-1500 bytes]
}
virtual at Ether_buffer
ETH_FRAME ETH_FRAME
end virtual
; Some useful information on data structures
; Ethernet Packet - ARP Request example
;
; 0 1 2 3
; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
;
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Dest H/W Address |
; | ( 14 byte header ) |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | | Source H/W Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Protocol - ARP 08 06 |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | H/W Type 00 01 | Protocol Type 08 00 |
; | ( ARP Request packet ) |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | HLen 0x06 | PLen 0x04 | OpCode 00 01 |
; | ( 0001 for request, 0002 for reply ) |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Source Hardware Address ( MAC Address ) |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | | Source IP Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | | Destination Hardware Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Destination IP Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; Include individual drivers source files at this point.
; If you create a new driver, include it below.
include "drivers/rtl8029.inc"
include "drivers/i8255x.inc"
include "drivers/rtl8139.inc"
include "drivers/3c59x.inc"
include "drivers/sis900.inc"
include "drivers/pcnet32.inc"
include "drivers/rtl8169.inc"
include "drivers/forcedeth.inc"
include "drivers/r6040.inc"
; PCICards
; ========
; PCI vendor and hardware types for hardware supported by the above drivers
; If you add a driver, ensure you update this datastructure, otherwise the
; card will not be probed.
; Each driver is defined by 4 double words. These are
; PCIVendorDevice probeFunction ResetFunction PollFunction transmitFunction
; The last entry must be kept at all zeros, to indicate the end of the list
; As a PCI driver may support more than one hardware implementation, there may
; be several lines which refer to the same functions.
; The first driver found on the PCI bus will be the one used.
PCICARDS_ENTRY_SIZE equ 24 ; Size of each PCICARDS entry
iglobal
PCICards:
dd 0x12098086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0
dd 0x10298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0
dd 0x12298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0
dd 0x10308086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0
dd 0x24498086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0
dd 0x10688086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0
dd 0x802910ec, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit, 0
dd 0x813910ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x813810ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x12111113, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x13601500, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x13604033, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x13001186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x13401186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0xab0613d1, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0xa1171259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0xa11e1259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0xab0614ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0xab0714ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x123411db, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x91301432, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x101202ac, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x0106018a, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x1211126c, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x81391743, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x8139021b, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x816810ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0
dd 0x816910ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0
dd 0x011616ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0
dd 0x43001186, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0
dd 0x816710ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0
dd 0x590010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x592010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x597010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x595010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x595110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x595210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x900010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x900110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x900410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x900510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x900610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x900A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x905010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x905110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x905510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x905810b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x905A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x920010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x980010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x980510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x764610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x505510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x605510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x605610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x5b5710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x505710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x515710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x525710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x656010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x656210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x656410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x450010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x09001039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit, 0
dd 0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit, 0
dd 0x20001022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0
dd 0x26251022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0
dd 0x20011022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0
dd 0x006610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; nVidia Corporation nForce2 Ethernet Controller
dd 0x01c310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x00D610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x008610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x008c10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x00e610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x00df10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x005610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x005710de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x003710de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x003810de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x026810de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x026910de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x037210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x037310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x03e510de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x03e610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x03ee10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x03ef10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x045010de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x045110de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x045210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x045310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x054c10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x054d10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x054e10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x054f10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x07dc10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x07dd10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x07de10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x07df10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x076010de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; MCP77 Ethernet Controller
dd 0x076110de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x076210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x076310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x0ab010de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x0ab110de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x0ab210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x0ab310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x0d7d10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x604017F3, r6040_probe, r6040_reset, r6040_poll, r6040_transmit, 0
rb PCICARDS_ENTRY_SIZE ; end of list marker, do not remove
endg
uglobal
;Net-stack's interface's settings
node_addr:
db 0,0,0,0,0,0
gateway_ip:
dd 0
dns_ip:
dd 0
eth_rx_data_len:
dw 0
eth_status:
dd 0
io_addr:
dd 0
hdrtype:
db 0
vendor_device:
dd 0
pci_data:
dd 0
pci_dev:
dd 0
pci_bus:
dd 0
; These will hold pointers to the selected driver functions
drvr_probe:
dd 0
drvr_reset:
dd 0
drvr_poll:
dd 0
drvr_transmit:
dd 0
drvr_cable:
dd 0
endg
iglobal
broadcast_add:
db 0xff,0xff,0xff,0xff,0xff,0xff
subnet_mask:
dd 0x00ffffff ; 255.255.255.0
endg
include "arp.inc" ;arp-protocol functions
include "pci.inc" ;PCI bus access functions
;***************************************************************************
; Function
; eth_tx
;
; Description
; Looks at the NET1OUT_QUEUE for data to send.
; Stores that destination IP in a location used by the tx routine
; Looks up the MAC address in the ARP table; stores that where
; the tx routine can get it
; Get the length of the data. Store that where the tx routine wants it
; Call tx
; Places buffer on empty queue when the tx routine finished
;
;***************************************************************************
proc eth_tx stdcall uses ebx esi edi
local MACAddress dp ? ;allocate 6 bytes in the stack
; Look for a buffer to tx
mov eax, NET1OUT_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .exit ; Exit if no buffer available
push eax;save buffer number
; convert buffer pointer eax to the absolute address
imul eax, IPBUFFSIZE
add eax, IPbuffs
; Extract the destination IP
; find the destination IP in the ARP table, get MAC
; store this MAC in 'MACAddress'
mov ebx, eax ; Save buffer address
mov edx, [ebx + 16] ; get destination address
; If the destination address is 255.255.255.255,
; set the MACAddress to all ones ( broadcast )
cld
mov esi, broadcast_add
lea edi, [MACAddress]
movsd
movsw
cmp edx, 0xffffffff
je .send ; If it is broadcast, just send
lea eax, [MACAddress];cause this is local variable
stdcall arp_table_manager, ARP_TABLE_IP_TO_MAC, edx, eax;opcode,IP,MAC_ptr - Get the MAC address.
cmp eax, ARP_VALID_MAPPING
je .send
; No valid entry. Has the request been sent, but timed out?
cmp eax, ARP_RESPONSE_TIMEOUT
je .freebuf
.wait_response: ;we wait arp-response
; Re-queue the packet, and exit
pop ebx
mov eax, NET1OUT_QUEUE
call queue ; Get the buffer back
jmp .exit
.send: ;if ARP_VALID_MAPPING then send the packet
lea edi, [MACAddress] ; Pointer to 48 bit destination address
movzx ecx, word[ebx+2] ; Size of IP packet to send
xchg ch, cl ; because mirror byte-order
mov esi, ebx ; Pointer to packet data
mov bx, ETHER_IP ; Type of packet
push ebp
call dword [drvr_transmit]; Call the drivers transmit function
pop ebp
; OK, we have sent a packet, so increment the count
inc dword [ip_tx_count]
; And finally, return the buffer to the free queue
.freebuf:
pop eax
call freeBuff
.exit:
ret
endp
;***************************************************************************
; Function
; ether_IP_handler
;
; Description
; Called when an IP ethernet packet is received on the ethernet
; Header + Data is in Ether_buffer[]
; We just need to get a buffer from the 'free' queue, and
; store the packet in it, then insert the packet number into the
; IPRX queue.
; If no queue entry is available, the packet is silently discarded
; All registers may be destroyed
;
;***************************************************************************
;uglobal
; ether_IP_handler_cnt dd ?
;endg
ether_IP_handler:
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je eiph00x
; convert buffer pointer eax to the absolute address
push eax
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
mov edi, eax
; get a pointer to the start of the DATA
mov esi, ETH_FRAME.Data
; Now store it all away
mov ecx, IPBUFFSIZE / 4 ; Copy all of the available
; data across - worse case
cld
rep movsd
; inc [ether_IP_handler_cnt]
; DEBUGF 1, "K : ether_IP_handler (%u)\n", [ether_IP_handler_cnt]
; And finally, place the buffer in the IPRX queue
pop ebx
mov eax, IPIN_QUEUE
call queue
eiph00x:
ret
;***************************************************************************
; Function
; eth_probe
; Description
; Searches for an ethernet card. If found, the card is enabled and
; the ethernet -> IP link established
;
; This function scans the PCI bus looking for a supported device.
; ISA bus is currently not supported.
;
; eax is 0 if no hardware found
;***************************************************************************
eth_probe:
; Find a card on the PCI bus, and get it's address
call scan_bus ; Find the ethernet cards PIC address
xor eax, eax
cmp [io_addr], eax
je ep_00x ; Return 0 in eax if no cards found
call dword [drvr_probe] ; Call the drivers probe function
mov eax, [io_addr] ; return a non zero value
ep_00x:
ret
;***************************************************************************
; Function
; ethernet_driver
;
; Description
; The ethernet RX and TX handler
; This is a kernel function, called by stack_handler
;
;***************************************************************************
ethernet_driver:
; Do nothing if the driver is inactive
cmp [ethernet_active], byte 0
je eth_exit
call eth_rx
call eth_tx
eth_exit:
ret
;***************************************************************************
; Function
; eth_rx
;
; Description
; Polls the ethernet card for received data. Extracts if present
; Depending on the Protocol within the packet:
; ARP : Pass to ARP_handler. This may result in an ARP reply
; being tx'ed
; IP : Store in an IP buffer
;
;***************************************************************************
eth_rx:
xor ax, ax
mov [eth_rx_data_len], ax
call dword [drvr_poll] ; Call the drivers poll function
mov ax, [eth_rx_data_len]
cmp ax, 0
je .exit
; Check the protocol. Call appropriate handler
mov ax, [ETH_FRAME.Type]; The address of the protocol word
cmp ax, ETHER_IP
je .is_ip ; It's IP
cmp ax, ETHER_ARP
je .is_arp ; It is ARP
DEBUGF 1,"K : eth_rx - dumped (%u)\n", ax
inc [dumped_rx_count]
jmp .exit ; If not IP or ARP, ignore
.is_ip:
; DEBUGF 1,"K : eth_rx - IP packet\n"
inc dword [ip_rx_count]
call ether_IP_handler
jmp .exit
.is_arp:
; DEBUGF 1,"K : eth_rx - ARP packet\n"
; At this point, the packet is still in the Ether_buffer
call arp_handler
.exit:
ret

View File

@ -1,351 +0,0 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision$
;***************************************************************************
;
; PCI CODE FOLLOWS
;
; the following functions provide access to the PCI interface.
; These functions are used by scan_bus, and also some ethernet drivers
;
;***************************************************************************
; PCI Bus defines
PCI_HEADER_TYPE equ 0x0e ;8 bit
PCI_BASE_ADDRESS_0 equ 0x10 ;32 bit
PCI_BASE_ADDRESS_5 equ 0x24 ;32 bits
PCI_BASE_ADDRESS_SPACE_IO equ 0x01
PCI_VENDOR_ID equ 0x00 ;16 bit
PCI_BASE_ADDRESS_IO_MASK equ 0xFFFFFFFC
;***************************************************************************
; Function
; config_cmd
;
; Description
; creates a command dword for use with the PCI bus
; bus # in ebx
; devfn in ecx
; where in edx
;
; command dword returned in eax
; Only eax destroyed
;***************************************************************************
config_cmd:
push ecx
mov eax, ebx
shl eax, 16
or eax, 0x80000000
shl ecx, 8
or eax, ecx
pop ecx
or eax, edx
and eax, 0xFFFFFFFC
ret
;***************************************************************************
; Function
; pcibios_read_config_byte
;
; Description
; reads a byte from the PCI config space
; bus # in ebx
; devfn in ecx
; where in edx ( ls 16 bits significant )
;
; byte returned in al ( rest of eax zero )
; Only eax/edx destroyed
;***************************************************************************
pcibios_read_config_byte:
call config_cmd
push dx
mov dx, 0xCF8
out dx, eax
pop dx
xor eax, eax
and dx, 0x03
add dx, 0xCFC
; and dx, 0xFFC
in al, dx
ret
;***************************************************************************
; Function
; pcibios_read_config_word
;
; Description
; reads a word from the PCI config space
; bus # in ebx
; devfn in ecx
; where in edx ( ls 16 bits significant )
;
; word returned in ax ( rest of eax zero )
; Only eax/edx destroyed
;***************************************************************************
pcibios_read_config_word:
call config_cmd
push dx
mov dx, 0xCF8
out dx, eax
pop dx
xor eax, eax
and dx, 0x02
add dx, 0xCFC
; and dx, 0xFFC
in ax, dx
ret
;***************************************************************************
; Function
; pcibios_read_config_dword
;
; Description
; reads a dword from the PCI config space
; bus # in ebx
; devfn in ecx
; where in edx ( ls 16 bits significant )
;
; dword returned in eax
; Only eax/edx destroyed
;***************************************************************************
pcibios_read_config_dword:
push edx
call config_cmd
push dx
mov dx, 0xCF8
out dx, eax
pop dx
xor eax, eax
mov dx, 0xCFC
in eax, dx
pop edx
ret
;***************************************************************************
; Function
; pcibios_write_config_byte
;
; Description
; write a byte in al to the PCI config space
; bus # in ebx
; devfn in ecx
; where in edx ( ls 16 bits significant )
;
; Only eax/edx destroyed
;***************************************************************************
pcibios_write_config_byte:
push ax
call config_cmd
push dx
mov dx, 0xCF8
out dx, eax
pop dx
pop ax
and dx, 0x03
add dx, 0xCFC
out dx, al
ret
;***************************************************************************
; Function
; pcibios_write_config_word
;
; Description
; write a word in ax to the PCI config space
; bus # in ebx
; devfn in ecx
; where in edx ( ls 16 bits significant )
;
; Only eax/edx destroyed
;***************************************************************************
pcibios_write_config_word:
push ax
call config_cmd
push dx
mov dx, 0xCF8
out dx, eax
pop dx
pop ax
and dx, 0x02
add dx, 0xCFC
out dx, ax
ret
;***************************************************************************
; Function
; delay_us
;
; Description
; delays for 30 to 60 us
;
; I would prefer this routine to be able to delay for
; a selectable number of microseconds, but this works for now.
;
; If you know a better way to do 2us delay, pleae tell me!
;***************************************************************************
delay_us:
push eax
push ecx
mov ecx, 2
in al, 0x61
and al, 0x10
mov ah, al
cld
dcnt1:
in al, 0x61
and al, 0x10
cmp al, ah
jz dcnt1
mov ah, al
loop dcnt1
pop ecx
pop eax
ret
;***************************************************************************
; Function
; scan_bus
;
; Description
; Scans the PCI bus for a supported device
; If a supported device is found, the drvr_ variables are initialised
; to that drivers functions ( as defined in the PCICards table)
;
; io_addr holds card I/O space. 32 bit, but only LS 16 bits valid
; pci_data holds the PCI vendor + device code
; pci_dev holds PCI bus dev #
; pci_bus holds PCI bus #
;
; io_addr will be zero if no card found
;
;***************************************************************************
scan_bus:
xor eax, eax
mov [hdrtype], al
mov [pci_data], eax
xor ebx, ebx ; ebx = bus# 0 .. 255
sb_bus_loop:
xor ecx, ecx ; ecx = devfn# 0 .. 254 ( not 255? )
sb_devf_loop:
mov eax, ecx
and eax, 0x07
cmp eax, 0
jne sb_001
mov edx, PCI_HEADER_TYPE
call pcibios_read_config_byte
mov [hdrtype], al
jmp sb_002
sb_001:
mov al, [hdrtype]
and al, 0x80
cmp al, 0x80
jne sb_inc_devf
sb_002:
mov edx, PCI_VENDOR_ID
call pcibios_read_config_dword
mov [vendor_device], eax
cmp eax, 0xffffffff
je sb_empty
cmp eax, 0
jne sb_check_vendor
sb_empty:
mov [hdrtype], byte 0
jmp sb_inc_devf
sb_check_vendor:
; iterate though PCICards until end or match found
mov esi, PCICards
sb_check:
cmp [esi], dword 0
je sb_inc_devf ; Quit if at last entry
cmp eax, [esi]
je sb_got_card
add esi, PCICARDS_ENTRY_SIZE
jmp sb_check
sb_got_card:
; indicate that we have found the card
mov [pci_data], eax
mov [pci_dev], ecx
mov [pci_bus], ebx
; Define the driver functions
push eax
mov eax, [esi+4]
mov [drvr_probe], eax
mov eax, [esi+8]
mov [drvr_reset], eax
mov eax, [esi+12]
mov [drvr_poll], eax
mov eax, [esi+16]
mov [drvr_transmit], eax
mov eax, [esi+20]
mov [drvr_cable], eax
pop eax
mov edx, PCI_BASE_ADDRESS_0
sb_reg_check:
call pcibios_read_config_dword
mov [io_addr], eax
and eax, PCI_BASE_ADDRESS_IO_MASK
cmp eax, 0
je sb_inc_reg
mov eax, [io_addr]
and eax, PCI_BASE_ADDRESS_SPACE_IO
cmp eax, 0
je sb_inc_reg
mov eax, [io_addr]
and eax, PCI_BASE_ADDRESS_IO_MASK
mov [io_addr], eax
sb_exit1:
ret
sb_inc_reg:
add edx, 4
cmp edx, PCI_BASE_ADDRESS_5
jbe sb_reg_check
sb_inc_devf:
inc ecx
cmp ecx, 255
jb sb_devf_loop
inc ebx
cmp ebx, 256
jb sb_bus_loop
; We get here if we didn't find our card
; set io_addr to 0 as an indication
xor eax, eax
mov [io_addr], eax
sb_exit2:
ret

View File

@ -56,7 +56,7 @@ ETH_input:
mov eax, [esp] mov eax, [esp]
mov ecx, [esp+4] mov ecx, [esp+4]
DEBUGF 1,"ETH_input: size=%u\n", ecx DEBUGF DEBUG_NETWORK_VERBOSE,"ETH_input: size=%u\n", ecx
cmp ecx, ETH_FRAME_MINIMUM cmp ecx, ETH_FRAME_MINIMUM
jb .dump jb .dump
sub ecx, sizeof.ETH_header sub ecx, sizeof.ETH_header
@ -79,10 +79,10 @@ ETH_input:
cmp ax, ETHER_PPP_SESSION cmp ax, ETHER_PPP_SESSION
je PPPoE_session_input je PPPoE_session_input
DEBUGF 2,"ETH_input: Unknown packet type=%x\n", ax DEBUGF DEBUG_NETWORK_ERROR, "ETH_input: Unknown packet type=%x\n", ax
.dump: .dump:
DEBUGF 2,"ETH_input: dumping\n" DEBUGF DEBUG_NETWORK_VERBOSE,"ETH_input: dumping\n"
call kernel_free call kernel_free
add esp, 4 add esp, 4
ret ret
@ -107,7 +107,7 @@ ETH_input:
align 4 align 4
ETH_output: ETH_output:
DEBUGF 1,"ETH_output: size=%u device=%x\n", ecx, ebx DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: size=%u device=%x\n", ecx, ebx
cmp ecx, [ebx + NET_DEVICE.mtu] cmp ecx, [ebx + NET_DEVICE.mtu]
ja .exit ja .exit
@ -137,7 +137,7 @@ ETH_output:
cmp edx, ETH_FRAME_MINIMUM cmp edx, ETH_FRAME_MINIMUM
jbe .adjust_size jbe .adjust_size
.done: .done:
DEBUGF 1,"ETH_output: ptr=%x size=%u\n", eax, edx DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: ptr=%x size=%u\n", eax, edx
ret ret
.adjust_size: .adjust_size:
@ -146,13 +146,13 @@ ETH_output:
jmp .done jmp .done
.out_of_ram: .out_of_ram:
DEBUGF 2,"ETH_output: Out of ram!\n" DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: Out of ram!\n"
add esp, 4+4+2+4 add esp, 4+4+2+4
sub edi, edi sub edi, edi
ret ret
.exit: .exit:
DEBUGF 2,"ETH_output: Packet too large!\n" DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: Packet too large!\n"
sub edi, edi sub edi, edi
ret ret

View File

@ -142,7 +142,7 @@ macro ICMP_init {
align 4 align 4
ICMP_input: ICMP_input:
DEBUGF 1,"ICMP_input:\n" DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input:\n"
; First, check the checksum (altough some implementations ignore it) ; First, check the checksum (altough some implementations ignore it)
@ -163,7 +163,7 @@ ICMP_input:
; We well re-use the packet so we can create the response as fast as possible ; We well re-use the packet so we can create the response as fast as possible
; Notice: this only works on pure ethernet ; Notice: this only works on pure ethernet
DEBUGF 1,"got echo request\n" DEBUGF DEBUG_NETWORK_VERBOSE, "got echo request\n"
mov [edx + ICMP_header.Type], ICMP_ECHOREPLY ; Change Packet type to reply mov [edx + ICMP_header.Type], ICMP_ECHOREPLY ; Change Packet type to reply
mov esi, [esp] ; Start of buffer mov esi, [esp] ; Start of buffer
@ -258,7 +258,7 @@ ICMP_input:
; je .dump ; je .dump
; inc [ICMP_PACKETS_RX+edi] ; inc [ICMP_PACKETS_RX+edi]
DEBUGF 1,"socket=%x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "socket=%x\n", eax
pusha pusha
lea ecx, [eax + SOCKET.mutex] lea ecx, [eax + SOCKET.mutex]
@ -270,10 +270,10 @@ ICMP_input:
.checksum_mismatch: .checksum_mismatch:
DEBUGF 1,"checksum mismatch\n" DEBUGF DEBUG_NETWORK_VERBOSE, "checksum mismatch\n"
.dump: .dump:
DEBUGF 1,"ICMP_input: dumping\n" DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: dumping\n"
call kernel_free call kernel_free
add esp, 4 ; pop (balance stack) add esp, 4 ; pop (balance stack)
@ -297,7 +297,7 @@ ICMP_input:
align 4 align 4
ICMP_output: ICMP_output:
DEBUGF 1,"Creating ICMP Packet\n" DEBUGF DEBUG_NETWORK_VERBOSE, "Creating ICMP Packet\n"
push esi edi dx push esi edi dx
@ -308,7 +308,7 @@ ICMP_output:
call IPv4_output call IPv4_output
jz .exit jz .exit
DEBUGF 1,"full icmp packet size: %u\n", edx DEBUGF DEBUG_NETWORK_VERBOSE, "full icmp packet size: %u\n", edx
pop word [edi + ICMP_header.Type] ; Write both type and code bytes at once pop word [edi + ICMP_header.Type] ; Write both type and code bytes at once
pop dword [edi + ICMP_header.Identifier] ; identifier and sequence number pop dword [edi + ICMP_header.Identifier] ; identifier and sequence number
@ -333,11 +333,11 @@ ICMP_output:
sub edi, edx ;;; TODO: find a better way to remember start of packet sub edi, edx ;;; TODO: find a better way to remember start of packet
push edx edi push edx edi
DEBUGF 1,"Sending ICMP Packet\n" DEBUGF DEBUG_NETWORK_VERBOSE, "Sending ICMP Packet\n"
call [ebx + NET_DEVICE.transmit] call [ebx + NET_DEVICE.transmit]
ret ret
.exit: .exit:
DEBUGF 1,"Creating ICMP Packet failed\n" DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
add esp, 2*4 + 2 add esp, 2*4 + 2
ret ret
@ -356,7 +356,7 @@ ICMP_output:
align 4 align 4
ICMP_output_raw: ICMP_output_raw:
DEBUGF 1,"Creating ICMP Packet for socket %x, data ptr=%x\n", eax, edx DEBUGF DEBUG_NETWORK_VERBOSE, "Creating ICMP Packet for socket %x, data ptr=%x\n", eax, edx
push edx push edx
@ -371,7 +371,7 @@ ICMP_output_raw:
push eax push eax
push edi ecx push edi ecx
DEBUGF 1,"copying %u bytes from %x to %x\n", ecx, esi, edi DEBUGF DEBUG_NETWORK_VERBOSE, "copying %u bytes from %x to %x\n", ecx, esi, edi
rep movsb rep movsb
pop ecx edi pop ecx edi
@ -383,11 +383,11 @@ ICMP_output_raw:
call checksum_2 call checksum_2
mov [edi + ICMP_header.Checksum], dx mov [edi + ICMP_header.Checksum], dx
DEBUGF 1,"Sending ICMP Packet\n" DEBUGF DEBUG_NETWORK_VERBOSE, "Sending ICMP Packet\n"
call [ebx + NET_DEVICE.transmit] call [ebx + NET_DEVICE.transmit]
ret ret
.exit: .exit:
DEBUGF 1,"Creating ICMP Packet failed\n" DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
add esp, 4 add esp, 4
ret ret

View File

@ -1,248 +0,0 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ;;
;; IP.INC ;;
;; ;;
;; IP Processes for Menuet OS TCP/IP stack ;;
;; ;;
;; Version 0.3 29 August 2002 ;;
;; ;;
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision$
; IP underlying protocols numbers
PROTOCOL_ICMP equ 1
PROTOCOL_TCP equ 6
PROTOCOL_UDP equ 17
struc IP_PACKET
{ .VersionAndIHL db ? ;+00 - Version[0-3 bits] and IHL(header length)[4-7 bits]
.TypeOfService db ? ;+01
.TotalLength dw ? ;+02
.Identification dw ? ;+04
.FlagsAndFragmentOffset dw ? ;+06 - Flags[0-2] and FragmentOffset[3-15]
.TimeToLive db ? ;+08
.Protocol db ? ;+09
.HeaderChecksum dw ? ;+10
.SourceAddress dd ? ;+12
.DestinationAddress dd ? ;+16
.DataOrOptional dd ? ;+20
}
virtual at 0
IP_PACKET IP_PACKET
end virtual
;*******************************************************************
; Interface
;
; ip_rx processes all packets received by the network layer
; It calls the appropriate protocol handler
;
;
;
;*******************************************************************
;
; IP Packet after reception - Normal IP packet format
;
; 0 1 2 3
; 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
;
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;0 |Version| IHL |Type of Service| Total Length |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;4 | Identification |Flags| Fragment Offset |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;8 | Time to Live | Protocol | Header Checksum |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;12 | Source Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;16 | Destination Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;20 | Data |
; +-+-+-.......... -+
;
;
; [smb] attention! according to RFC 791 IP packet may have 'options' sections,
; so we can't simply think, that data have offset 20. We must calculate offset from
; IHL field
;
macro GET_IHL reg, header_addr
{
movzx reg, byte [header_addr]
; we need 4-7 bits, so....
and reg, 0x0000000F
; IHL keeps number of octets, so we need to << 2 'reg'
shl reg, 2
}
include "tcp.inc"
include "udp.inc"
include "icmp.inc"
;***************************************************************************
; Function
; ip_rx
;
; Description
; This is a kernel function, called by stack_handler
; Processes all IP-packets received by the network layer
; It calls the appropriate protocol handler
;
;***************************************************************************
proc ip_rx stdcall
local buffer_number dd ?
; Look for a buffer to tx
mov eax, IPIN_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .exit ; Exit if no buffer available
mov [buffer_number], eax;save buffer number
; convert buffer pointer eax to the absolute address
imul eax, IPBUFFSIZE
add eax, IPbuffs
mov ebx, eax; ebx=pointer to IP_PACKET
; DEBUGF 1, "K : ip_rx - proto: %u\n", [ebx + IP_PACKET.Protocol]:1
; Validate the IP checksum
mov dx, word[ebx + IP_PACKET.HeaderChecksum]
xchg dh, dl ; Get the checksum in intel format
mov [ebx + IP_PACKET.HeaderChecksum], 0; clear checksum field - need to when
; recalculating checksum
; this needs two data pointers and two size #.
; 2nd pointer can be of length 0
GET_IHL ecx, ebx + IP_PACKET.VersionAndIHL ;get packet length in ecx
stdcall checksum_jb, ebx, ecx;buf_ptr, buf_size
cmp dx, ax
; DEBUGF 1, "K : ip_rx - checksums: %x - %x\n", dx, ax
jnz .dump.1;if CHECKSUM isn't valid then dump packet
mov edx, ebx; EDX (IP-BUFFER POINTER) WILL BE USED FOR *_rx HANDLERS BELOW!!!
; DEBUGF 1, "K : ip_rx - dest: %x - %x\n", [ebx + IP_PACKET.DestinationAddress], [stack_ip]
; Validate the IP address, if it isn't broadcast
mov eax, [stack_ip]
cmp dword[ebx + IP_PACKET.DestinationAddress], eax
je @f
; If the IP address is 255.255.255.255, accept it
; - it is a broadcast packet, which we need for dhcp
mov eax, [ebx + IP_PACKET.DestinationAddress]
cmp eax, 0xffffffff
je @f
mov ecx, [stack_ip]
and eax, [subnet_mask]
and ecx, [subnet_mask]
cmp eax, ecx
jne .dump.2
mov eax, [ebx + IP_PACKET.DestinationAddress]
or eax, [subnet_mask]
cmp eax, 0xffffffff
jne .dump.2
@@:
mov al, [ebx + IP_PACKET.VersionAndIHL]
and al, 0x0f;get IHL(header length)
cmp al, 0x05;if IHL!= 5*4(20 bytes)
; DEBUGF 1, "K : ip_rx - ihl: %x - 05\n", al
jnz .dump.3 ;then dump it
; DEBUGF 1, "K : ip_rx - ttl: %x - 00\n", [ebx + IP_PACKET.TimeToLive]:2
cmp [ebx + IP_PACKET.TimeToLive], 0
je .dump.4 ;if TTL==0 then dump it
mov ax, [ebx + IP_PACKET.FlagsAndFragmentOffset]
and ax, 0xFFBF;get flags
; DEBUGF 1, "K : ip_rx - flags: %x - 0000\n", ax
cmp ax, 0 ;if some flags was set then we dump this packet
jnz .dump.5 ;the flags should be used for fragmented packets
; Check the protocol, and call the appropriate handler
; Each handler will re-use or free the queue buffer as appropriate
mov al, [ebx + IP_PACKET.Protocol]
cmp al , PROTOCOL_TCP
jne .not_tcp
; DEBUGF 1,"K : ip_rx - TCP packet\n"
mov eax, dword[buffer_number]
call tcp_rx
jmp .exit
.not_tcp:
cmp al, PROTOCOL_UDP
jne .not_udp
; DEBUGF 1,"K : ip_rx - UDP packet\n"
mov eax, dword[buffer_number]
call udp_rx
jmp .exit
.not_udp:
cmp al, PROTOCOL_ICMP
jne .dump.6 ;protocol ain't supported
; DEBUGF 1,"K : ip_rx - ICMP packet\n"
;GET_IHL ecx, ebx + IP_PACKET.VersionAndIHL ;get packet length in ecx
mov eax, dword[buffer_number]
stdcall icmp_rx, eax, ebx, ecx;buffer_number,IPPacketBase,IPHeaderLength
jmp .exit
.dump.1:
DEBUGF 1, "K : ip_rx - dumped (checksum: 0x%x-0x%x)\n", dx, ax
jmp .dump.x
.dump.2:
DEBUGF 1, "K : ip_rx - dumped (ip: %u.%u.%u.%u)\n", [ebx + IP_PACKET.DestinationAddress + 0]:1, [ebx + IP_PACKET.DestinationAddress + 1]:1, [ebx + IP_PACKET.DestinationAddress + 2]:1, [ebx + IP_PACKET.DestinationAddress + 3]:1
jmp .dump.x
.dump.3:
DEBUGF 1, "K : ip_rx - dumped (ihl: %u)\n", al
jmp .dump.x
.dump.4:
DEBUGF 1, "K : ip_rx - dumped (ttl: %u)\n", [ebx + IP_PACKET.TimeToLive]
jmp .dump.x
.dump.5:
DEBUGF 1, "K : ip_rx - dumped (flags: 0x%x)\n", ax
jmp .dump.x
.dump.6:
DEBUGF 1, "K : ip_rx - dumped (proto: %u)\n", [ebx + IP_PACKET.Protocol]:1
.dump.x:
inc dword[dumped_rx_count]
mov eax, [buffer_number]
call freeBuff
.exit:
ret
endp

View File

@ -59,7 +59,7 @@ LOOP_input:
push ecx push ecx
push eax push eax
DEBUGF 1,"LOOP_input: size=%u\n", ecx DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_input: size=%u\n", ecx
lea edx, [eax + 2] lea edx, [eax + 2]
mov ax, word[eax] mov ax, word[eax]
mov ebx, LOOPBACK_DEVICE mov ebx, LOOPBACK_DEVICE
@ -67,10 +67,10 @@ LOOP_input:
cmp ax, ETHER_IPv4 cmp ax, ETHER_IPv4
je IPv4_input je IPv4_input
DEBUGF 2,"LOOP_input: Unknown packet type=%x\n", ax DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_input: Unknown packet type=%x\n", ax
.dump: .dump:
DEBUGF 2,"LOOP_input: dumping\n" DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_input: dumping\n"
call kernel_free call kernel_free
add esp, 4 add esp, 4
ret ret
@ -93,7 +93,7 @@ LOOP_input:
align 4 align 4
LOOP_output: LOOP_output:
DEBUGF 1,"LOOP_output\n" DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_output\n"
push ecx push ecx
push di push di
@ -114,11 +114,11 @@ LOOP_output:
mov ebx, LOOPBACK_DEVICE mov ebx, LOOPBACK_DEVICE
.done: .done:
DEBUGF 2,"LOOP_output: ptr=%x size=%u\n", eax, edx DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_output: ptr=%x size=%u\n", eax, edx
ret ret
.out_of_ram: .out_of_ram:
DEBUGF 2,"LOOP_output: failed\n" DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_output: failed\n"
add esp, 2+4 add esp, 2+4
sub edi, edi sub edi, edi
ret ret

View File

@ -263,7 +263,7 @@ sys_socket:
.number = ($ - .table) / 4 - 1 .number = ($ - .table) / 4 - 1
s_error: s_error:
DEBUGF 2,"SOCKET: error\n" DEBUGF DEBUG_NETWORK_ERROR, "SOCKET: error\n"
mov dword [esp+32], -1 mov dword [esp+32], -1
ret ret
@ -281,7 +281,7 @@ s_error:
align 4 align 4
SOCKET_open: SOCKET_open:
DEBUGF 2,"SOCKET_open: domain=%u type=%u protocol=%x ", ecx, edx, esi DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_open: domain=%u type=%u protocol=%x ", ecx, edx, esi
push ecx edx esi push ecx edx esi
call SOCKET_alloc call SOCKET_alloc
@ -289,7 +289,7 @@ SOCKET_open:
jz s_error jz s_error
mov [esp+32], edi ; return socketnumber mov [esp+32], edi ; return socketnumber
DEBUGF 2,"socknum=%u\n", edi DEBUGF DEBUG_NETWORK_VERBOSE, "socknum=%u\n", edi
; push edx ; push edx
; and edx, SO_NONBLOCK ; and edx, SO_NONBLOCK
@ -321,7 +321,7 @@ SOCKET_open:
je .pppoe je .pppoe
.no_ppp: .no_ppp:
DEBUGF 2,"Unknown socket family/protocol\n" DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_open: Unknown socket family/protocol\n"
ret ret
align 4 align 4
@ -394,7 +394,7 @@ align 4
align 4 align 4
SOCKET_bind: SOCKET_bind:
DEBUGF 2,"SOCKET_bind: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_bind: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi
call SOCKET_num_to_ptr call SOCKET_num_to_ptr
jz s_error jz s_error
@ -444,7 +444,7 @@ SOCKET_bind:
call SOCKET_check_port call SOCKET_check_port
jz s_error ; ZF is set by socket_check_port, on error jz s_error ; ZF is set by socket_check_port, on error
DEBUGF 1,"SOCKET_bind: local ip=%u.%u.%u.%u\n",\ DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_bind: local ip=%u.%u.%u.%u\n",\
[eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\ [eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\
[eax + IP_SOCKET.LocalIP + 2]:1,[eax + IP_SOCKET.LocalIP + 3]:1 [eax + IP_SOCKET.LocalIP + 2]:1,[eax + IP_SOCKET.LocalIP + 3]:1
@ -467,7 +467,7 @@ SOCKET_bind:
align 4 align 4
SOCKET_connect: SOCKET_connect:
DEBUGF 2,"SOCKET_connect: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_connect: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi
call SOCKET_num_to_ptr call SOCKET_num_to_ptr
jz s_error jz s_error
@ -616,7 +616,7 @@ align 4
align 4 align 4
SOCKET_listen: SOCKET_listen:
DEBUGF 2,"SOCKET_listen: socknum=%u backlog=%u\n", ecx, edx DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_listen: socknum=%u backlog=%u\n", ecx, edx
call SOCKET_num_to_ptr call SOCKET_num_to_ptr
jz s_error jz s_error
@ -668,7 +668,7 @@ SOCKET_listen:
align 4 align 4
SOCKET_accept: SOCKET_accept:
DEBUGF 2,"SOCKET_accept: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_accept: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi
call SOCKET_num_to_ptr call SOCKET_num_to_ptr
jz s_error jz s_error
@ -718,7 +718,7 @@ SOCKET_accept:
align 4 align 4
SOCKET_close: SOCKET_close:
DEBUGF 2,"SOCKET_close: socknum=%u\n", ecx DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_close: socknum=%u\n", ecx
call SOCKET_num_to_ptr call SOCKET_num_to_ptr
jz s_error jz s_error
@ -767,18 +767,21 @@ SOCKET_close:
align 4 align 4
SOCKET_receive: SOCKET_receive:
DEBUGF 2,"SOCKET_receive: socknum=%u bufaddr=%x buflength=%u flags=%x\n", ecx, edx, esi, edi DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: socknum=%u bufaddr=%x buflength=%u flags=%x\n", ecx, edx, esi, edi
call SOCKET_num_to_ptr call SOCKET_num_to_ptr
jz s_error jz s_error
jmp [eax + SOCKET.rcv_proc] call [eax + SOCKET.rcv_proc]
mov [esp+32], eax
ret
align 4 align 4
SOCKET_receive_dgram: SOCKET_receive_dgram:
DEBUGF 1,"SOCKET_receive: DGRAM\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: DGRAM\n"
mov ebx, esi mov ebx, esi
mov edi, edx ; addr to buffer mov edi, edx ; addr to buffer
@ -787,15 +790,15 @@ SOCKET_receive_dgram:
get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, .block ; destroys esi and ecx get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, .block ; destroys esi and ecx
mov ecx, [esi + socket_queue_entry.data_size] mov ecx, [esi + socket_queue_entry.data_size]
DEBUGF 1,"SOCKET_receive: %u bytes data\n", ecx DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: %u bytes data\n", ecx
cmp ecx, ebx cmp ecx, ebx
ja .too_small ja .too_small
push ecx
push [esi + socket_queue_entry.buf_ptr] ; save the buffer addr so we can clear it later push [esi + socket_queue_entry.buf_ptr] ; save the buffer addr so we can clear it later
mov esi, [esi + socket_queue_entry.data_ptr] mov esi, [esi + socket_queue_entry.data_ptr]
DEBUGF 1,"SOCKET_receive: Source buffer=%x real addr=%x\n", [esp], esi DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: Source buffer=%x real addr=%x\n", [esp], esi
mov [esp+32+4], ecx ; return number of bytes copied
; copy the data ; copy the data
shr ecx, 1 shr ecx, 1
@ -812,16 +815,20 @@ SOCKET_receive_dgram:
.nd: .nd:
call kernel_free ; remove the packet call kernel_free ; remove the packet
pop eax
ret ret
.too_small: .too_small:
DEBUGF 2,"SOCKET_receive: Buffer too small\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: Buffer too small\n"
jmp s_error .fail:
mov eax, -1
ret
.block: .block:
test [eax + SOCKET.options], SO_NONBLOCK test [eax + SOCKET.options], SO_NONBLOCK
jnz s_error jnz .fail
call SOCKET_block call SOCKET_block
jmp .loop jmp .loop
@ -846,7 +853,7 @@ SOCKET_receive_local:
align 4 align 4
SOCKET_receive_stream: SOCKET_receive_stream:
DEBUGF 1,"SOCKET_receive: STREAM\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_receive: STREAM\n"
mov ebx, edi mov ebx, edi
mov ecx, esi mov ecx, esi
@ -866,12 +873,11 @@ SOCKET_receive_stream:
call SOCKET_ring_read call SOCKET_ring_read
call SOCKET_ring_free call SOCKET_ring_free
mov [esp+32], ecx ; return number of bytes copied mov eax, ecx ; return number of bytes copied
ret ret
.peek: .peek:
mov ecx, [eax + STREAM_SOCKET.rcv + RING_BUFFER.size] mov eax, [eax + STREAM_SOCKET.rcv + RING_BUFFER.size]
mov [esp+32], ecx ; return number of bytes available
ret ret
.block: .block:
@ -882,8 +888,15 @@ SOCKET_receive_stream:
jmp .loop jmp .loop
.return0: .return0:
xor ecx, ecx test [eax + SOCKET.options], SS_CANTRCVMORE
mov [esp+32], ecx jz .ok
xor eax, eax
dec eax
ret
.ok:
xor eax, eax
ret ret
@ -902,7 +915,7 @@ SOCKET_receive_stream:
align 4 align 4
SOCKET_send: SOCKET_send:
DEBUGF 2,"SOCKET_send: socknum=%u data ptr=%x length=%u flags=%x\n", ecx, edx, esi, edi DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: socknum=%u data ptr=%x length=%u flags=%x\n", ecx, edx, esi, edi
call SOCKET_num_to_ptr call SOCKET_num_to_ptr
jz s_error jz s_error
@ -916,7 +929,7 @@ SOCKET_send:
align 4 align 4
SOCKET_send_udp: SOCKET_send_udp:
DEBUGF 1,"SOCKET_send: UDP\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: UDP\n"
mov [esp+32], ecx mov [esp+32], ecx
call UDP_output call UDP_output
@ -928,7 +941,7 @@ SOCKET_send_udp:
align 4 align 4
SOCKET_send_tcp: SOCKET_send_tcp:
DEBUGF 1,"SOCKET_send: TCP\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: TCP\n"
push eax push eax
add eax, STREAM_SOCKET.snd add eax, STREAM_SOCKET.snd
@ -944,7 +957,7 @@ SOCKET_send_tcp:
align 4 align 4
SOCKET_send_ip: SOCKET_send_ip:
DEBUGF 1,"SOCKET_send: IPv4\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: IPv4\n"
mov [esp+32], ecx mov [esp+32], ecx
call IPv4_output_raw call IPv4_output_raw
@ -956,7 +969,7 @@ SOCKET_send_ip:
align 4 align 4
SOCKET_send_icmp: SOCKET_send_icmp:
DEBUGF 1,"SOCKET_send: ICMP\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: ICMP\n"
mov [esp+32], ecx mov [esp+32], ecx
call ICMP_output_raw call ICMP_output_raw
@ -968,7 +981,7 @@ SOCKET_send_icmp:
align 4 align 4
SOCKET_send_pppoe: SOCKET_send_pppoe:
DEBUGF 1,"SOCKET_send: PPPoE\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: PPPoE\n"
mov [esp+32], ecx mov [esp+32], ecx
mov ebx, [eax + SOCKET.device] mov ebx, [eax + SOCKET.device]
@ -998,7 +1011,7 @@ SOCKET_send_local:
align 4 align 4
SOCKET_send_local_: SOCKET_send_local_:
DEBUGF 1,"SOCKET_send: LOCAL\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: LOCAL\n"
; get the other side's socket and check if it still exists ; get the other side's socket and check if it still exists
mov eax, [eax + SOCKET.device] mov eax, [eax + SOCKET.device]
@ -1037,7 +1050,7 @@ SOCKET_send_local_:
align 4 align 4
SOCKET_get_opt: SOCKET_get_opt:
DEBUGF 2,"SOCKET_get_opt\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_get_opt\n"
call SOCKET_num_to_ptr call SOCKET_num_to_ptr
jz s_error jz s_error
@ -1087,7 +1100,7 @@ SOCKET_get_opt:
align 4 align 4
SOCKET_set_opt: SOCKET_set_opt:
DEBUGF 2,"SOCKET_set_opt\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_set_opt\n"
call SOCKET_num_to_ptr call SOCKET_num_to_ptr
jz s_error jz s_error
@ -1116,7 +1129,7 @@ SOCKET_set_opt:
jz s_error jz s_error
mov [eax + SOCKET.device], edx mov [eax + SOCKET.device], edx
DEBUGF 1,"SOCKET_set_opt: Bound socket %x to device %x\n",eax, edx DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_set_opt: Bound socket %x to device %x\n",eax, edx
mov dword [esp+32], 0 ; success! mov dword [esp+32], 0 ; success!
ret ret
@ -1158,7 +1171,7 @@ SOCKET_set_opt:
align 4 align 4
SOCKET_pair: SOCKET_pair:
DEBUGF 2,"SOCKET_pair\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_pair\n"
call SOCKET_alloc call SOCKET_alloc
jz s_error jz s_error
@ -1217,7 +1230,7 @@ SOCKET_pair:
align 4 align 4
SOCKET_debug: SOCKET_debug:
DEBUGF 1,"SOCKET_debug\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_debug\n"
mov edi, edx mov edi, edx
@ -1266,7 +1279,7 @@ SOCKET_debug:
align 4 align 4
SOCKET_find_port: SOCKET_find_port:
DEBUGF 2,"SOCKET_find_port\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_find_port\n"
push ebx esi ecx push ebx esi ecx
@ -1327,7 +1340,7 @@ SOCKET_find_port:
align 4 align 4
SOCKET_check_port: SOCKET_check_port:
DEBUGF 2,"SOCKET_check_port: " DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_check_port: "
mov ecx, [eax + SOCKET.Protocol] mov ecx, [eax + SOCKET.Protocol]
mov edx, [eax + IP_SOCKET.LocalIP] mov edx, [eax + IP_SOCKET.LocalIP]
@ -1347,11 +1360,11 @@ SOCKET_check_port:
cmp [esi + UDP_SOCKET.LocalPort], bx cmp [esi + UDP_SOCKET.LocalPort], bx
jne .next_socket jne .next_socket
DEBUGF 2,"local port %x already in use\n", bx ; FIXME: find a way to print big endian values with debugf DEBUGF DEBUG_NETWORK_VERBOSE, "local port %x already in use\n", bx ; FIXME: find a way to print big endian values with debugf
ret ret
.port_ok: .port_ok:
DEBUGF 2,"local port %x is free\n", bx ; FIXME: find a way to print big endian values with debugf DEBUGF DEBUG_NETWORK_VERBOSE, "local port %x is free\n", bx ; FIXME: find a way to print big endian values with debugf
mov [eax + UDP_SOCKET.LocalPort], bx mov [eax + UDP_SOCKET.LocalPort], bx
or bx, bx ; clear the zero-flag or bx, bx ; clear the zero-flag
ret ret
@ -1378,7 +1391,7 @@ SOCKET_check_port:
align 4 align 4
SOCKET_input: SOCKET_input:
DEBUGF 2,"SOCKET_input: socket=%x, data=%x size=%u\n", eax, esi, ecx DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_input: socket=%x, data=%x size=%u\n", eax, esi, ecx
mov [esp+4], ecx mov [esp+4], ecx
push esi push esi
@ -1386,7 +1399,7 @@ SOCKET_input:
add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, SOCKET_input.full add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, SOCKET_input.full
DEBUGF 1,"SOCKET_input: success\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_input: success\n"
add esp, sizeof.socket_queue_entry add esp, sizeof.socket_queue_entry
pusha pusha
@ -1397,7 +1410,7 @@ SOCKET_input:
jmp SOCKET_notify jmp SOCKET_notify
.full: .full:
DEBUGF 2,"SOCKET_input: socket %x is full!\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_input: socket %x is full!\n", eax
pusha pusha
lea ecx, [eax + SOCKET.mutex] lea ecx, [eax + SOCKET.mutex]
@ -1424,7 +1437,7 @@ SOCKET_ring_create:
stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW
pop edx pop edx
DEBUGF 1,"SOCKET_ring_created: %x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_created: %x\n", eax
pusha pusha
lea ecx, [esi + RING_BUFFER.mutex] lea ecx, [esi + RING_BUFFER.mutex]
@ -1458,7 +1471,7 @@ SOCKET_ring_create:
align 4 align 4
SOCKET_ring_write: SOCKET_ring_write:
DEBUGF 1,"SOCKET_ring_write: ringbuff=%x ptr=%x size=%u\n", eax, esi, ecx DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_write: ringbuff=%x ptr=%x size=%u\n", eax, esi, ecx
; lock mutex ; lock mutex
pusha pusha
@ -1474,7 +1487,7 @@ SOCKET_ring_write:
mov ecx, edi mov ecx, edi
.copy: .copy:
mov edi, [eax + RING_BUFFER.write_ptr] mov edi, [eax + RING_BUFFER.write_ptr]
DEBUGF 2,"SOCKET_ring_write: %u bytes from %x to %x\n", ecx, esi, edi DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_write: %u bytes from %x to %x\n", ecx, esi, edi
; update write ptr ; update write ptr
push edi push edi
@ -1532,7 +1545,7 @@ SOCKET_ring_write:
align 4 align 4
SOCKET_ring_read: SOCKET_ring_read:
DEBUGF 1,"SOCKET_ring_read: ringbuff=%x ptr=%x size=%u offset=%x\n", eax, edi, ecx, edx DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_read: ringbuff=%x ptr=%x size=%u offset=%x\n", eax, edi, ecx, edx
pusha pusha
lea ecx, [eax + RING_BUFFER.mutex] lea ecx, [eax + RING_BUFFER.mutex]
@ -1555,7 +1568,7 @@ SOCKET_ring_read:
ja .less_data ja .less_data
.copy: .copy:
DEBUGF 2,"SOCKET_ring_read: %u bytes from %x to %x\n", ecx, esi, edi DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_read: %u bytes from %x to %x\n", ecx, esi, edi
push ecx push ecx
shr ecx, 1 shr ecx, 1
jnc .nb jnc .nb
@ -1578,7 +1591,7 @@ SOCKET_ring_read:
call mutex_unlock ; TODO: check what registers this function actually destroys call mutex_unlock ; TODO: check what registers this function actually destroys
popa popa
DEBUGF 1,"SOCKET_ring_read: no data at all!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_read: no data at all!\n"
xor ecx, ecx xor ecx, ecx
ret ret
@ -1602,7 +1615,7 @@ SOCKET_ring_read:
align 4 align 4
SOCKET_ring_free: SOCKET_ring_free:
DEBUGF 1,"SOCKET_ring_free: %u bytes from ring %x\n", ecx, eax DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_free: %u bytes from ring %x\n", ecx, eax
push eax ecx push eax ecx
lea ecx, [eax + RING_BUFFER.mutex] lea ecx, [eax + RING_BUFFER.mutex]
@ -1627,7 +1640,7 @@ SOCKET_ring_free:
ret ret
.error: ; we could free all available bytes, but that would be stupid, i guess.. .error: ; we could free all available bytes, but that would be stupid, i guess..
DEBUGF 1,"SOCKET_ring_free: buffer=%x error!\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ring_free: buffer=%x error!\n", eax
add [eax + RING_BUFFER.size], ecx add [eax + RING_BUFFER.size], ecx
push eax push eax
@ -1652,7 +1665,7 @@ SOCKET_ring_free:
align 4 align 4
SOCKET_block: SOCKET_block:
DEBUGF 1,"SOCKET_block: %x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: %x\n", eax
pushf pushf
cli cli
@ -1667,14 +1680,14 @@ SOCKET_block:
; Remember the thread ID so we can wake it up again ; Remember the thread ID so we can wake it up again
mov edx, [edx + TASKDATA.pid] mov edx, [edx + TASKDATA.pid]
DEBUGF 1,"SOCKET_block: suspending thread: %u\n", edx DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: suspending thread: %u\n", edx
mov [eax + SOCKET.TID], edx mov [eax + SOCKET.TID], edx
pop edx pop edx
call change_task call change_task
popf popf
DEBUGF 1,"SOCKET_block: continueing\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_block: continueing\n"
ret ret
@ -1692,7 +1705,7 @@ SOCKET_block:
align 4 align 4
SOCKET_notify: SOCKET_notify:
DEBUGF 1,"SOCKET_notify: %x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: %x\n", eax
call SOCKET_check call SOCKET_check
jz .error jz .error
@ -1728,7 +1741,7 @@ SOCKET_notify:
shl ecx, 8 shl ecx, 8
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK
DEBUGF 1,"SOCKET_notify: Raised a network event!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: Raised a network event!\n"
jmp .done jmp .done
@ -1756,7 +1769,7 @@ SOCKET_notify:
; Run the thread ; Run the thread
mov [esi + TASKDATA.state], 0 ; Running mov [esi + TASKDATA.state], 0 ; Running
DEBUGF 1,"SOCKET_notify: Unblocked socket!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_notify: Unblocked socket!\n"
.done: .done:
pop esi ecx eax pop esi ecx eax
@ -1785,7 +1798,7 @@ SOCKET_alloc:
push ebx push ebx
stdcall kernel_alloc, SOCKETBUFFSIZE stdcall kernel_alloc, SOCKETBUFFSIZE
DEBUGF 1, "SOCKET_alloc: ptr=%x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_alloc: ptr=%x\n", eax
or eax, eax or eax, eax
jz .exit jz .exit
@ -1821,7 +1834,7 @@ SOCKET_alloc:
.last_socket: .last_socket:
mov [last_socket_num], edi mov [last_socket_num], edi
mov [eax + SOCKET.Number], edi mov [eax + SOCKET.Number], edi
DEBUGF 1, "SOCKET_alloc: number=%u\n", edi DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_alloc: number=%u\n", edi
; Fill in PID ; Fill in PID
mov ebx, [TASK_BASE] mov ebx, [TASK_BASE]
@ -1878,7 +1891,7 @@ SOCKET_alloc:
align 4 align 4
SOCKET_free: SOCKET_free:
DEBUGF 1, "SOCKET_free: %x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: %x\n", eax
call SOCKET_check call SOCKET_check
jz .error jz .error
@ -1906,7 +1919,7 @@ SOCKET_free:
mov ebx, [eax + SOCKET.NextPtr] mov ebx, [eax + SOCKET.NextPtr]
mov eax, [eax + SOCKET.PrevPtr] mov eax, [eax + SOCKET.PrevPtr]
DEBUGF 1, "SOCKET_free: linking socket %x to socket %x\n", eax, ebx DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: linking socket %x to socket %x\n", eax, ebx
test eax, eax test eax, eax
jz @f jz @f
@ -1921,7 +1934,7 @@ SOCKET_free:
call kernel_free call kernel_free
pop ebx pop ebx
DEBUGF 1, "SOCKET_free: success!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_free: success!\n"
.error: .error:
ret ret
@ -1939,7 +1952,7 @@ SOCKET_free:
align 4 align 4
SOCKET_fork: SOCKET_fork:
DEBUGF 1,"SOCKET_fork: %x\n", ebx DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_fork: %x\n", ebx
; Exit if backlog queue is full ; Exit if backlog queue is full
mov eax, [ebx + SOCKET_QUEUE_LOCATION + queue.size] mov eax, [ebx + SOCKET_QUEUE_LOCATION + queue.size]
@ -1971,7 +1984,7 @@ SOCKET_fork:
.fail2: .fail2:
add esp, 4+4+4 add esp, 4+4+4
.fail: .fail:
DEBUGF 1,"SOCKET_fork: failed\n" DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_fork: failed\n"
xor eax, eax xor eax, eax
ret ret
@ -1990,7 +2003,7 @@ SOCKET_fork:
align 4 align 4
SOCKET_num_to_ptr: SOCKET_num_to_ptr:
DEBUGF 1,"SOCKET_num_to_ptr: num=%u ", ecx DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_num_to_ptr: num=%u ", ecx
mov eax, net_sockets mov eax, net_sockets
@ -2003,11 +2016,11 @@ SOCKET_num_to_ptr:
test eax, eax test eax, eax
DEBUGF 1,"ptr=%x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "ptr=%x\n", eax
ret ret
.error: .error:
DEBUGF 1,"not found\n", eax DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_nuto_ptr: not found\n", eax
ret ret
@ -2025,18 +2038,18 @@ SOCKET_num_to_ptr:
align 4 align 4
SOCKET_ptr_to_num: SOCKET_ptr_to_num:
DEBUGF 1,"SOCKET_ptr_to_num: ptr=%x ", eax DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_ptr_to_num: ptr=%x ", eax
call SOCKET_check call SOCKET_check
jz .error jz .error
mov eax, [eax + SOCKET.Number] mov eax, [eax + SOCKET.Number]
DEBUGF 1,"num=%u\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "num=%u\n", eax
ret ret
.error: .error:
DEBUGF 1,"not found\n", eax DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_ptr_to_num: not found\n", eax
ret ret
@ -2054,7 +2067,7 @@ SOCKET_ptr_to_num:
align 4 align 4
SOCKET_check: SOCKET_check:
DEBUGF 1,"SOCKET_check: %x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_check: %x\n", eax
push ebx push ebx
mov ebx, net_sockets mov ebx, net_sockets
@ -2088,7 +2101,7 @@ SOCKET_check:
align 4 align 4
SOCKET_check_owner: SOCKET_check_owner:
DEBUGF 1,"SOCKET_check_owner: %x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_check_owner: %x\n", eax
push ebx push ebx
mov ebx, [TASK_BASE] mov ebx, [TASK_BASE]
@ -2116,7 +2129,7 @@ SOCKET_check_owner:
align 4 align 4
SOCKET_process_end: SOCKET_process_end:
DEBUGF 1, "SOCKET_process_end: %x\n", edx DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_process_end: %x\n", edx
push ebx push ebx
mov ebx, net_sockets mov ebx, net_sockets
@ -2130,7 +2143,7 @@ SOCKET_process_end:
cmp [ebx + SOCKET.PID], edx cmp [ebx + SOCKET.PID], edx
jne .next_socket jne .next_socket
DEBUGF 1, "SOCKET_process_end: killing socket %x\n", ebx DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_process_end: killing socket %x\n", ebx
mov [ebx + SOCKET.PID], 0 mov [ebx + SOCKET.PID], 0
mov eax, ebx mov eax, ebx
@ -2160,7 +2173,7 @@ SOCKET_process_end:
align 4 align 4
SOCKET_is_connecting: SOCKET_is_connecting:
DEBUGF 1,"SOCKET_is_connecting: %x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_connecting: %x\n", eax
and [eax + SOCKET.options], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING) and [eax + SOCKET.options], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING)
or [eax + SOCKET.options], SS_ISCONNECTING or [eax + SOCKET.options], SS_ISCONNECTING
@ -2181,7 +2194,7 @@ SOCKET_is_connecting:
align 4 align 4
SOCKET_is_connected: SOCKET_is_connected:
DEBUGF 1,"SOCKET_is_connected: %x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_connected: %x\n", eax
and [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING) and [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING)
or [eax + SOCKET.options], SS_ISCONNECTED or [eax + SOCKET.options], SS_ISCONNECTED
@ -2203,7 +2216,7 @@ SOCKET_is_connected:
align 4 align 4
SOCKET_is_disconnecting: SOCKET_is_disconnecting:
DEBUGF 1,"SOCKET_is_disconnecting: %x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_disconnecting: %x\n", eax
and [eax + SOCKET.options], not (SS_ISCONNECTING) and [eax + SOCKET.options], not (SS_ISCONNECTING)
or [eax + SOCKET.options], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE or [eax + SOCKET.options], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE
@ -2224,7 +2237,7 @@ SOCKET_is_disconnecting:
align 4 align 4
SOCKET_is_disconnected: SOCKET_is_disconnected:
DEBUGF 1,"SOCKET_is_disconnected: %x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_disconnected: %x\n", eax
and [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING) and [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING)
or [eax + SOCKET.options], SS_CANTRCVMORE + SS_CANTSENDMORE or [eax + SOCKET.options], SS_CANTRCVMORE + SS_CANTSENDMORE
@ -2257,10 +2270,12 @@ SOCKET_is_disconnected:
align 4 align 4
SOCKET_cant_recv_more: SOCKET_cant_recv_more:
DEBUGF 1,"SOCKET_cant_recv_more: %x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_cant_recv_more: %x\n", eax
or [eax + SOCKET.options], SS_CANTRCVMORE or [eax + SOCKET.options], SS_CANTRCVMORE
call SOCKET_notify
ret ret
@ -2277,8 +2292,11 @@ SOCKET_cant_recv_more:
align 4 align 4
SOCKET_cant_send_more: SOCKET_cant_send_more:
DEBUGF 1,"SOCKET_cant_send_more: %x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_cant_send_more: %x\n", eax
or [eax + SOCKET.options], SS_CANTSENDMORE or [eax + SOCKET.options], SS_CANTSENDMORE
mov [eax + SOCKET.snd_proc], s_error
call SOCKET_notify
ret ret

View File

@ -28,6 +28,9 @@ uglobal
net_tmr_count dw ? net_tmr_count dw ?
endg endg
DEBUG_NETWORK_ERROR = 1
DEBUG_NETWORK_VERBOSE = 0
MAX_NET_DEVICES = 16 MAX_NET_DEVICES = 16
ARP_BLOCK = 1 ; true or false ARP_BLOCK = 1 ; true or false
@ -305,12 +308,12 @@ stack_handler:
align 4 align 4
NET_link_changed: NET_link_changed:
DEBUGF 1,"NET_link_changed device=0x%x status=0x%x\n", ebx, [ebx + NET_DEVICE.state] DEBUGF DEBUG_NETWORK_VERBOSE, "NET_link_changed device=0x%x status=0x%x\n", ebx, [ebx + NET_DEVICE.state]
align 4 align 4
NET_send_event: NET_send_event:
DEBUGF 1,"NET_send_event\n" DEBUGF DEBUG_NETWORK_VERBOSE, "NET_send_event\n"
; Send event to all applications ; Send event to all applications
push edi ecx push edi ecx
@ -340,7 +343,7 @@ NET_send_event:
align 4 align 4
NET_add_device: NET_add_device:
DEBUGF 1,"NET_Add_Device: %x\n", ebx ;;; TODO: use mutex to lock net device list DEBUGF DEBUG_NETWORK_VERBOSE, "NET_Add_Device: %x\n", ebx ;;; TODO: use mutex to lock net device list
cmp [NET_RUNNING], MAX_NET_DEVICES cmp [NET_RUNNING], MAX_NET_DEVICES
jae .error jae .error
@ -384,12 +387,12 @@ NET_add_device:
call NET_send_event call NET_send_event
DEBUGF 1,"Device number: %u\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "Device number: %u\n", eax
ret ret
.error: .error:
or eax, -1 or eax, -1
DEBUGF 2,"Adding network device failed\n" DEBUGF DEBUG_NETWORK_ERROR, "Adding network device failed\n"
ret ret
@ -407,7 +410,7 @@ NET_add_device:
align 4 align 4
NET_set_default: NET_set_default:
DEBUGF 1,"NET_set_default: device=%x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "NET_set_default: device=%x\n", eax
cmp eax, MAX_NET_DEVICES cmp eax, MAX_NET_DEVICES
jae .error jae .error
@ -417,12 +420,12 @@ NET_set_default:
mov [NET_DEFAULT], eax mov [NET_DEFAULT], eax
DEBUGF 1,"NET_set_default: succes\n" DEBUGF DEBUG_NETWORK_VERBOSE, "NET_set_default: succes\n"
ret ret
.error: .error:
or eax, -1 or eax, -1
DEBUGF 1,"NET_set_default: failed\n" DEBUGF DEBUG_NETWORK_ERROR, "NET_set_default: failed\n"
ret ret
@ -634,7 +637,7 @@ checksum_2:
.not_zero: .not_zero:
xchg dl, dh xchg dl, dh
DEBUGF 1,"Checksum: %x\n", dx DEBUGF DEBUG_NETWORK_VERBOSE, "Checksum: %x\n", dx
ret ret

View File

@ -60,7 +60,7 @@ TCP_input:
.fail: .fail:
popf popf
DEBUGF 2, "TCP incoming queue is full, discarding packet!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP incoming queue is full, discarding packet!\n"
inc [TCP_segments_missed] ; FIXME: use correct interface inc [TCP_segments_missed] ; FIXME: use correct interface
@ -97,7 +97,7 @@ TCP_process_input:
mov edi, [esi + TCP_queue_entry.ip_ptr] ; ptr to ipv4 source address, followed by ipv4 destination address mov edi, [esi + TCP_queue_entry.ip_ptr] ; ptr to ipv4 source address, followed by ipv4 destination address
mov esi, [esi + TCP_queue_entry.segment_ptr] ; change esi last mov esi, [esi + TCP_queue_entry.segment_ptr] ; change esi last
DEBUGF 1,"TCP_input: size=%u time=%d\n", ecx, [timer_ticks] DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: size=%u time=%d\n", ecx, [timer_ticks]
mov edx, esi mov edx, esi
@ -127,7 +127,7 @@ TCP_process_input:
movzx eax, [edx + TCP_header.DataOffset] movzx eax, [edx + TCP_header.DataOffset]
sub ecx, eax ; substract TCP header size from total segment size sub ecx, eax ; substract TCP header size from total segment size
jb .drop_no_socket ; If total segment size is less then the advertised header size, drop packet jb .drop_no_socket ; If total segment size is less then the advertised header size, drop packet
DEBUGF 1,"TCP_input: %u bytes of data\n", ecx DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: %u bytes of data\n", ecx
;------------------------------------------- ;-------------------------------------------
; Convert Big-endian values to little endian ; Convert Big-endian values to little endian
@ -176,7 +176,7 @@ TCP_process_input:
test ax, ax test ax, ax
jnz .socket_loop jnz .socket_loop
.found_socket: ; ebx now contains the socketpointer .found_socket: ; ebx now contains the socketpointer
DEBUGF 1,"TCP_input: socket ptr=%x state=%u flags=%x\n", ebx, [ebx + TCP_SOCKET.t_state], [edx + TCP_header.Flags]:2 DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: socket ptr=%x state=%u flags=%x\n", ebx, [ebx + TCP_SOCKET.t_state], [edx + TCP_header.Flags]:2
;------------- ;-------------
; update stats ; update stats
@ -197,7 +197,7 @@ TCP_process_input:
call mutex_lock call mutex_lock
popa popa
DEBUGF 1,"TCP_input: socket locked\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: socket locked\n"
;--------------------------- ;---------------------------
; disable all temporary bits ; disable all temporary bits
@ -220,7 +220,7 @@ TCP_process_input:
test [ebx + SOCKET.options], SO_ACCEPTCON test [ebx + SOCKET.options], SO_ACCEPTCON
jz .no_accept jz .no_accept
DEBUGF 1,"TCP_input: Accepting new connection\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Accepting new connection\n"
pusha pusha
lea ecx, [ebx + SOCKET.mutex] lea ecx, [ebx + SOCKET.mutex]
@ -263,7 +263,7 @@ TCP_process_input:
cmp ecx, sizeof.TCP_header ; Does header contain any options? cmp ecx, sizeof.TCP_header ; Does header contain any options?
je .no_options je .no_options
DEBUGF 1,"TCP_input: Segment has options\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Segment has options\n"
;;; FIXME: for LISTEN, options should be called after we determined route, we need it for MSS ;;; FIXME: for LISTEN, options should be called after we determined route, we need it for MSS
;;; cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN ; no options when in listen state ;;; cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN ; no options when in listen state
@ -290,7 +290,7 @@ TCP_process_input:
; je .opt_sack ; je .opt_sack
cmp al, TCP_OPT_TIMESTAMP cmp al, TCP_OPT_TIMESTAMP
je .opt_timestamp je .opt_timestamp
DEBUGF 1,"TCP_input: unknown option:%u\n", al DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: unknown option:%u\n", al
jmp .no_options ; If we reach here, some unknown options were received, skip them all! jmp .no_options ; If we reach here, some unknown options were received, skip them all!
.opt_maxseg: .opt_maxseg:
@ -303,7 +303,7 @@ TCP_process_input:
lodsw lodsw
rol ax, 8 rol ax, 8
DEBUGF 1,"TCP_input: Maxseg=%u\n", ax DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Maxseg=%u\n", ax
call TCP_mss call TCP_mss
@@: @@:
jmp .opt_loop jmp .opt_loop
@ -317,7 +317,7 @@ TCP_process_input:
test [edx + TCP_header.Flags], TH_SYN test [edx + TCP_header.Flags], TH_SYN
jz @f jz @f
DEBUGF 1,"TCP_input: Got window scale option\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Got window scale option\n"
or [ebx + TCP_SOCKET.t_flags], TF_RCVD_SCALE or [ebx + TCP_SOCKET.t_flags], TF_RCVD_SCALE
lodsb lodsb
@ -336,7 +336,7 @@ TCP_process_input:
test [edx + TCP_header.Flags], TH_SYN test [edx + TCP_header.Flags], TH_SYN
jz @f jz @f
DEBUGF 1,"TCP_input: Selective Acknowledgement permitted\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Selective Acknowledgement permitted\n"
or [ebx + TCP_SOCKET.t_flags], TF_SACK_PERMIT or [ebx + TCP_SOCKET.t_flags], TF_SACK_PERMIT
@@: @@:
@ -348,7 +348,7 @@ TCP_process_input:
cmp al, 10 ; length must be 10 cmp al, 10 ; length must be 10
jne .no_options jne .no_options
DEBUGF 1,"TCP_input: Got timestamp option\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Got timestamp option\n"
test [edx + TCP_header.Flags], TH_SYN test [edx + TCP_header.Flags], TH_SYN
jz @f jz @f
@ -372,7 +372,7 @@ TCP_process_input:
cmp eax, [ebx + TCP_SOCKET.ts_val] cmp eax, [ebx + TCP_SOCKET.ts_val]
jge .no_paws jge .no_paws
DEBUGF 1,"TCP_input: PAWS: detected an old segment\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: PAWS: detected an old segment\n"
mov eax, [esp+4+4] ; tcp_now mov eax, [esp+4+4] ; tcp_now
sub eax, [ebx + TCP_SOCKET.ts_recent_age] sub eax, [ebx + TCP_SOCKET.ts_recent_age]
@ -450,7 +450,7 @@ TCP_process_input:
sub eax, [ebx + TCP_SOCKET.SND_UNA] sub eax, [ebx + TCP_SOCKET.SND_UNA]
jbe .not_uni_xfer jbe .not_uni_xfer
DEBUGF 1,"TCP_input: Header prediction: we are sender\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Header prediction: we are sender\n"
;--------------------------------- ;---------------------------------
; Packet is a pure ACK, process it ; Packet is a pure ACK, process it
@ -524,7 +524,7 @@ TCP_process_input:
; Complete processing of received data ; Complete processing of received data
DEBUGF 1,"TCP_input: Header prediction: we are receiving %u bytes\n", ecx DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Header prediction: we are receiving %u bytes\n", ecx
add [ebx + TCP_SOCKET.RCV_NXT], ecx ; Update sequence number with number of bytes we have copied add [ebx + TCP_SOCKET.RCV_NXT], ecx ; Update sequence number with number of bytes we have copied
@ -545,7 +545,7 @@ TCP_process_input:
.not_uni_xfer: .not_uni_xfer:
DEBUGF 1,"TCP_input: Header prediction failed\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Header prediction failed\n"
; Calculate receive window size ; Calculate receive window size
@ -558,7 +558,7 @@ TCP_process_input:
jg @f jg @f
mov eax, edx mov eax, edx
@@: @@:
DEBUGF 1,"Receive window size=%d\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "Receive window size=%d\n", eax
mov [ebx + TCP_SOCKET.RCV_WND], eax mov [ebx + TCP_SOCKET.RCV_WND], eax
pop edx pop edx
@ -579,12 +579,12 @@ TCP_process_input:
sub eax, [edx + TCP_header.SequenceNumber] sub eax, [edx + TCP_header.SequenceNumber]
jle .no_duplicate jle .no_duplicate
DEBUGF 1,"TCP_input: %u bytes duplicate data!\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: %u bytes duplicate data!\n", eax
test [edx + TCP_header.Flags], TH_SYN test [edx + TCP_header.Flags], TH_SYN
jz .no_dup_syn jz .no_dup_syn
DEBUGF 1,"TCP_input: got duplicate syn\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: got duplicate syn\n"
and [edx + TCP_header.Flags], not (TH_SYN) and [edx + TCP_header.Flags], not (TH_SYN)
inc [edx + TCP_header.SequenceNumber] inc [edx + TCP_header.SequenceNumber]
@ -613,7 +613,7 @@ TCP_process_input:
; send an ACK and resynchronize and drop any data. ; send an ACK and resynchronize and drop any data.
; But keep on processing for RST or ACK ; But keep on processing for RST or ACK
DEBUGF 1, "616\n" DEBUGF DEBUG_NETWORK_VERBOSE, "616\n"
or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
mov eax, ecx mov eax, ecx
;TODO: update stats ;TODO: update stats
@ -658,7 +658,7 @@ TCP_process_input:
sub eax, [ebx + TCP_SOCKET.RCV_WND] ; eax now holds the number of bytes to drop sub eax, [ebx + TCP_SOCKET.RCV_WND] ; eax now holds the number of bytes to drop
jle .no_excess_data jle .no_excess_data
DEBUGF 1,"%d bytes beyond right edge of window\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "%d bytes beyond right edge of window\n", eax
;;; TODO: update stats ;;; TODO: update stats
cmp eax, ecx cmp eax, ecx
@ -687,7 +687,7 @@ TCP_process_input:
cmp eax, [ebx + TCP_SOCKET.RCV_NXT] cmp eax, [ebx + TCP_SOCKET.RCV_NXT]
jne .drop_after_ack jne .drop_after_ack
DEBUGF 1, "690\n" DEBUGF DEBUG_NETWORK_VERBOSE, "690\n"
or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
;;; TODO: update stats ;;; TODO: update stats
jmp .no_excess_data jmp .no_excess_data
@ -715,7 +715,7 @@ TCP_process_input:
sub eax, ecx sub eax, ecx
jae .no_timestamp jae .no_timestamp
DEBUGF 1,"Recording timestamp\n" DEBUGF DEBUG_NETWORK_VERBOSE, "Recording timestamp\n"
mov eax, [esp + 4] ; tcp_now mov eax, [esp + 4] ; tcp_now
mov [ebx + TCP_SOCKET.ts_recent_age], eax mov [ebx + TCP_SOCKET.ts_recent_age], eax
@ -729,7 +729,7 @@ TCP_process_input:
test [edx + TCP_header.Flags], TH_RST test [edx + TCP_header.Flags], TH_RST
jz .no_rst jz .no_rst
DEBUGF 1,"TCP_input: Got an RST flag\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Got an RST flag\n"
mov eax, [ebx + TCP_SOCKET.t_state] mov eax, [ebx + TCP_SOCKET.t_state]
shl eax, 2 shl eax, 2
@ -749,18 +749,18 @@ TCP_process_input:
dd .rst_close ; TCPS_TIMED_WAIT dd .rst_close ; TCPS_TIMED_WAIT
.econnrefused: .econnrefused:
DEBUGF 1,"TCP_input: Connection refused\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Connection refused\n"
mov [ebx + SOCKET.errorcode], ECONNREFUSED mov [ebx + SOCKET.errorcode], ECONNREFUSED
jmp .close jmp .close
.econnreset: .econnreset:
DEBUGF 1,"TCP_input: Connection reset\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Connection reset\n"
mov [ebx + SOCKET.errorcode], ECONNRESET mov [ebx + SOCKET.errorcode], ECONNRESET
.close: .close:
DEBUGF 1,"TCP_input: Closing connection\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Closing connection\n"
mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSED mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSED
;;; TODO: update stats (tcp drops) ;;; TODO: update stats (tcp drops)
@ -769,7 +769,7 @@ TCP_process_input:
jmp .drop_no_socket jmp .drop_no_socket
.rst_close: .rst_close:
DEBUGF 1,"TCP_input: Closing with reset\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Closing with reset\n"
mov eax, ebx mov eax, ebx
call TCP_close call TCP_close
@ -799,7 +799,7 @@ TCP_process_input:
jb .ack_processed ; states: closed, listen, syn_sent jb .ack_processed ; states: closed, listen, syn_sent
ja .no_syn_rcv ; established, fin_wait_1, fin_wait_2, close_wait, closing, last_ack, time_wait ja .no_syn_rcv ; established, fin_wait_1, fin_wait_2, close_wait, closing, last_ack, time_wait
DEBUGF 1,"TCP_input: state=syn_received\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: state=syn_received\n"
mov eax, [edx + TCP_header.AckNumber] mov eax, [edx + TCP_header.AckNumber]
cmp [ebx + TCP_SOCKET.SND_UNA], eax cmp [ebx + TCP_SOCKET.SND_UNA], eax
@ -846,7 +846,7 @@ TCP_process_input:
cmp eax, [ebx + TCP_SOCKET.SND_WND] cmp eax, [ebx + TCP_SOCKET.SND_WND]
jne .reset_dupacks jne .reset_dupacks
DEBUGF 1,"TCP_input: Processing duplicate ACK\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Processing duplicate ACK\n"
; If we have outstanding data, other than a window probe, this is a completely duplicate ACK ; If we have outstanding data, other than a window probe, this is a completely duplicate ACK
; (window info didnt change) The ACK is the biggest we've seen and we've seen exactly our rexmt threshold of them, ; (window info didnt change) The ACK is the biggest we've seen and we've seen exactly our rexmt threshold of them,
@ -927,7 +927,7 @@ TCP_process_input:
.no_re_xmit: .no_re_xmit:
jbe .not_dup_ack jbe .not_dup_ack
DEBUGF 1,"TCP_input: Increasing congestion window\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Increasing congestion window\n"
mov eax, [ebx + TCP_SOCKET.t_maxseg] mov eax, [ebx + TCP_SOCKET.t_maxseg]
add [ebx + TCP_SOCKET.SND_CWND], eax add [ebx + TCP_SOCKET.SND_CWND], eax
@ -980,7 +980,7 @@ TCP_process_input:
;;; TODO: update stats ;;; TODO: update stats
DEBUGF 1,"TCP_input: acceptable ACK for %u bytes\n", edi DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: acceptable ACK for %u bytes\n", edi
;------------------------------------------ ;------------------------------------------
; RTT measurements and retransmission timer (912-926) ; RTT measurements and retransmission timer (912-926)
@ -1073,7 +1073,7 @@ TCP_process_input:
call SOCKET_ring_free call SOCKET_ring_free
pop ebx edx ecx pop ebx edx ecx
DEBUGF 1,"TCP_input: our FIN is acked\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: our FIN is acked\n"
stc stc
jmp .wakeup jmp .wakeup
@ -1088,7 +1088,7 @@ TCP_process_input:
sub [ebx + TCP_SOCKET.SND_WND], ecx sub [ebx + TCP_SOCKET.SND_WND], ecx
pop edx ecx pop edx ecx
DEBUGF 1,"TCP_input: our FIN is not acked\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: our FIN is not acked\n"
clc clc
;---------------------------------------- ;----------------------------------------
@ -1176,7 +1176,7 @@ TCP_process_input:
align 4 align 4
.LISTEN: .LISTEN:
DEBUGF 1,"TCP_input: state=listen\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: state=listen\n"
test [edx + TCP_header.Flags], TH_RST test [edx + TCP_header.Flags], TH_RST
jnz .drop jnz .drop
@ -1228,7 +1228,7 @@ align 4
align 4 align 4
.SYN_SENT: .SYN_SENT:
DEBUGF 1,"TCP_input: state=syn_sent\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: state=syn_sent\n"
test [edx + TCP_header.Flags], TH_ACK test [edx + TCP_header.Flags], TH_ACK
jz @f jz @f
@ -1288,7 +1288,7 @@ align 4
test [edx + TCP_header.Flags], TH_ACK test [edx + TCP_header.Flags], TH_ACK
jz .simultaneous_open jz .simultaneous_open
DEBUGF 1,"TCP_input: active open\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: active open\n"
;;; TODO: update stats ;;; TODO: update stats
@ -1316,7 +1316,7 @@ align 4
.simultaneous_open: .simultaneous_open:
DEBUGF 1,"TCP_input: simultaneous open\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: simultaneous open\n"
; We have received a syn but no ACK, so we are having a simultaneous open.. ; We have received a syn but no ACK, so we are having a simultaneous open..
mov [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED mov [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED
@ -1339,7 +1339,7 @@ align 4
.ack_processed: .ack_processed:
DEBUGF 1,"TCP_input: ACK processed\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: ACK processed\n"
;---------------------------------------------- ;----------------------------------------------
; check if we need to update window information ; check if we need to update window information
@ -1373,7 +1373,7 @@ align 4
@@: @@:
mov [ebx + TCP_SOCKET.SND_WND], eax mov [ebx + TCP_SOCKET.SND_WND], eax
DEBUGF 1,"TCP_input: Updating window to %u\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Updating window to %u\n", eax
push [edx + TCP_header.SequenceNumber] push [edx + TCP_header.SequenceNumber]
pop [ebx + TCP_SOCKET.SND_WL1] pop [ebx + TCP_SOCKET.SND_WL1]
@ -1467,7 +1467,7 @@ align 4
call TCP_reassemble call TCP_reassemble
DEBUGF 1, "1470\n" DEBUGF DEBUG_NETWORK_VERBOSE, "1470\n"
or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
.data_done: .data_done:
@ -1478,12 +1478,12 @@ align 4
test [edx + TCP_header.Flags], TH_FIN test [edx + TCP_header.Flags], TH_FIN
jz .final_processing jz .final_processing
DEBUGF 1,"TCP_input: Processing FIN\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Processing FIN\n"
cmp [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT cmp [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT
jae .not_first_fin jae .not_first_fin
DEBUGF 1,"TCP_input: First FIN for this connection\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: First FIN for this connection\n"
mov eax, ebx mov eax, ebx
call SOCKET_cant_recv_more call SOCKET_cant_recv_more
@ -1534,7 +1534,7 @@ align 4
.drop_after_ack: .drop_after_ack:
DEBUGF 1,"TCP_input: Drop after ACK\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Drop after ACK\n"
push edx ebx push edx ebx
lea ecx, [ebx + SOCKET.mutex] lea ecx, [ebx + SOCKET.mutex]
@ -1548,7 +1548,7 @@ align 4
jmp .need_output jmp .need_output
.drop_with_reset: .drop_with_reset:
DEBUGF 1,"TCP_input: Drop with reset\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Drop with reset\n"
push ebx edx push ebx edx
lea ecx, [ebx + SOCKET.mutex] lea ecx, [ebx + SOCKET.mutex]
@ -1571,7 +1571,7 @@ align 4
; Final processing ; Final processing
.final_processing: .final_processing:
DEBUGF 1,"TCP_input: Final processing\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Final processing\n"
push ebx push ebx
lea ecx, [ebx + SOCKET.mutex] lea ecx, [ebx + SOCKET.mutex]
@ -1583,14 +1583,14 @@ align 4
test [eax + TCP_SOCKET.t_flags], TF_ACKNOW test [eax + TCP_SOCKET.t_flags], TF_ACKNOW
jz .dumpit jz .dumpit
DEBUGF 1,"TCP_input: ACK now!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: ACK now!\n"
.need_output: .need_output:
DEBUGF 1,"TCP_input: need output\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: need output\n"
call TCP_output call TCP_output
.dumpit: .dumpit:
DEBUGF 1,"TCP_input: dumping\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: dumping\n"
call kernel_free call kernel_free
add esp, 4 add esp, 4
@ -1641,7 +1641,7 @@ align 4
; Drop ; Drop
.drop: .drop:
DEBUGF 1,"TCP_input: Dropping segment\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Dropping segment\n"
pusha pusha
lea ecx, [ebx + SOCKET.mutex] lea ecx, [ebx + SOCKET.mutex]
@ -1656,7 +1656,7 @@ align 4
call SOCKET_free call SOCKET_free
.drop_no_socket: .drop_no_socket:
DEBUGF 1,"TCP_input: Drop (no socket)\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Drop (no socket)\n"
call kernel_free call kernel_free
add esp, 4 add esp, 4

View File

@ -28,7 +28,7 @@ $Revision: 3289 $
align 4 align 4
TCP_output: TCP_output:
DEBUGF 1,"TCP_output: socket=%x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: socket=%x\n", eax
push eax push eax
lea ecx, [eax + SOCKET.mutex] lea ecx, [eax + SOCKET.mutex]
@ -78,7 +78,7 @@ TCP_output:
cmp [eax + TCP_SOCKET.t_force], 0 cmp [eax + TCP_SOCKET.t_force], 0
je .no_force je .no_force
DEBUGF 1,"TCP_output: forcing data out\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: forcing data out\n"
test ecx, ecx test ecx, ecx
jnz .no_zero_window jnz .no_zero_window
@ -202,7 +202,7 @@ TCP_output:
;---------------------------------------- ;----------------------------------------
; Check if a window update should be sent (154) ; Check if a window update should be sent (154)
DEBUGF 1,"TCP_output: window=%d\n", ecx DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: window=%d\n", ecx
; Compare available window to amount of window known to peer (as advertised window less next expected input) ; Compare available window to amount of window known to peer (as advertised window less next expected input)
; If the difference is at least two max size segments, or at least 50% of the maximum possible window, ; If the difference is at least two max size segments, or at least 50% of the maximum possible window,
@ -237,7 +237,7 @@ TCP_output:
;-------------------------- ;--------------------------
; Should a segment be sent? (174) ; Should a segment be sent? (174)
DEBUGF 1,"TCP_output: 174\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: 174\n"
test [eax + TCP_SOCKET.t_flags], TF_ACKNOW ; we need to ACK test [eax + TCP_SOCKET.t_flags], TF_ACKNOW ; we need to ACK
jnz TCP_send jnz TCP_send
@ -273,7 +273,7 @@ TCP_output:
cmp [eax + TCP_SOCKET.timer_persist], 0 ; Persist timer already expired? cmp [eax + TCP_SOCKET.timer_persist], 0 ; Persist timer already expired?
jne @f jne @f
DEBUGF 1,"TCP_output: Entering persist state\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: Entering persist state\n"
mov [eax + TCP_SOCKET.t_rxtshift], 0 mov [eax + TCP_SOCKET.t_rxtshift], 0
call TCP_set_persist call TCP_set_persist
@ -282,7 +282,7 @@ TCP_output:
;---------------------------- ;----------------------------
; No reason to send a segment (219) ; No reason to send a segment (219)
DEBUGF 1,"TCP_output: No reason to send a segment\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: No reason to send a segment\n"
pusha pusha
lea ecx, [eax + SOCKET.mutex] lea ecx, [eax + SOCKET.mutex]
@ -313,7 +313,7 @@ TCP_output:
align 4 align 4
TCP_send: TCP_send:
DEBUGF 1,"TCP_send: socket=%x length=%u flags=%x\n", eax, esi, dl DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: socket=%x length=%u flags=%x\n", eax, esi, dl
push eax ; save socket ptr push eax ; save socket ptr
push esi ; and data length too push esi ; and data length too
@ -337,7 +337,7 @@ TCP_send:
push ecx push ecx
add di, 4 add di, 4
DEBUGF 1,"TCP_send: added maxseg option\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: added maxseg option\n"
test [eax + TCP_SOCKET.t_flags], TF_REQ_SCALE test [eax + TCP_SOCKET.t_flags], TF_REQ_SCALE
jz .no_scale jz .no_scale
@ -355,7 +355,7 @@ TCP_send:
pushw TCP_OPT_WINDOW + 3 shl 8 pushw TCP_OPT_WINDOW + 3 shl 8
add di, 4 add di, 4
DEBUGF 1,"TCP_send: added scale option\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: added scale option\n"
.no_scale: .no_scale:
.no_syn: .no_syn:
@ -381,7 +381,7 @@ TCP_send:
pushd TCP_OPT_NOP + TCP_OPT_NOP shl 8 + TCP_OPT_TIMESTAMP shl 16 + 10 shl 24 pushd TCP_OPT_NOP + TCP_OPT_NOP shl 8 + TCP_OPT_TIMESTAMP shl 16 + 10 shl 24
add di, 12 add di, 12
DEBUGF 1,"TCP_send: added timestamp\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: added timestamp\n"
.no_timestamp: .no_timestamp:
@ -538,7 +538,7 @@ TCP_send:
;---------------- ;----------------
; Send the packet ; Send the packet
DEBUGF 1,"TCP_send: Sending with device %x\n", ebx DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: Sending with device %x\n", ebx
call [ebx + NET_DEVICE.transmit] call [ebx + NET_DEVICE.transmit]
jnz .send_error jnz .send_error
@ -580,7 +580,7 @@ TCP_send:
test [eax + TCP_SOCKET.temp_bits], TCP_BIT_SENDALOT test [eax + TCP_SOCKET.temp_bits], TCP_BIT_SENDALOT
jnz TCP_output.again jnz TCP_output.again
DEBUGF 1,"TCP_send: success!\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: success!\n"
xor eax, eax xor eax, eax
ret ret
@ -597,7 +597,7 @@ TCP_send:
lea ecx, [eax + SOCKET.mutex] lea ecx, [eax + SOCKET.mutex]
call mutex_unlock call mutex_unlock
DEBUGF 1,"TCP_send: IP error\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: IP error\n"
or eax, -1 or eax, -1
ret ret
@ -609,7 +609,7 @@ TCP_send:
lea ecx, [eax + SOCKET.mutex] lea ecx, [eax + SOCKET.mutex]
call mutex_unlock call mutex_unlock
DEBUGF 1,"TCP_send: sending failed\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: sending failed\n"
or eax, -2 or eax, -2
ret ret

View File

@ -119,7 +119,7 @@ macro TCP_init_socket socket {
align 4 align 4
TCP_pull_out_of_band: TCP_pull_out_of_band:
DEBUGF 1,"TCP_pull_out_of_band\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_pull_out_of_band\n"
;;;; 1282-1305 ;;;; 1282-1305
@ -145,7 +145,7 @@ TCP_pull_out_of_band:
align 4 align 4
TCP_drop: TCP_drop:
DEBUGF 1,"TCP_drop: %x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_drop: %x\n", eax
cmp [eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED cmp [eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED
jb .no_syn_received jb .no_syn_received
@ -184,7 +184,7 @@ TCP_drop:
align 4 align 4
TCP_close: TCP_close:
DEBUGF 1,"TCP_close: %x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_close: %x\n", eax
;;; TODO: update RTT and mean deviation ;;; TODO: update RTT and mean deviation
;;; TODO: update slow start threshold ;;; TODO: update slow start threshold
@ -212,7 +212,7 @@ TCP_outflags:
mov edx, [eax + TCP_SOCKET.t_state] mov edx, [eax + TCP_SOCKET.t_state]
movzx edx, byte [edx + .flaglist] movzx edx, byte [edx + .flaglist]
DEBUGF 1,"TCP_outflags: socket=%x flags=%x\n", eax, dl DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_outflags: socket=%x flags=%x\n", eax, dl
ret ret
@ -248,7 +248,7 @@ TCP_outflags:
align 4 align 4
TCP_respond: TCP_respond:
DEBUGF 1,"TCP_respond_socket: socket=%x flags=%x\n", ebx, cl DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_respond_socket: socket=%x flags=%x\n", ebx, cl
;--------------------- ;---------------------
; Create the IP packet ; Create the IP packet
@ -305,7 +305,7 @@ TCP_respond:
ret ret
.error: .error:
DEBUGF 1,"TCP_respond_socket: failed\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_respond_socket: failed\n"
add esp, 2 + 4 add esp, 2 + 4
ret ret
@ -327,7 +327,7 @@ TCP_respond:
align 4 align 4
TCP_respond_segment: TCP_respond_segment:
DEBUGF 1,"TCP_respond_segment: frame=%x flags=%x\n", edx, cl DEBUGF DEBUG_NETWORK_VERBOSE,"TCP_respond_segment: frame=%x flags=%x\n", edx, cl
;--------------------- ;---------------------
; Create the IP packet ; Create the IP packet
@ -381,7 +381,7 @@ TCP_respond_segment:
ret ret
.error: .error:
DEBUGF 1,"TCP_respond_segment: failed\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_respond_segment: failed\n"
add esp, 2+4 add esp, 2+4
ret ret
@ -416,7 +416,7 @@ local .done
align 4 align 4
TCP_set_persist: TCP_set_persist:
DEBUGF 1,"TCP_set_persist\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_set_persist\n"
; First, check if retransmit timer is not set, retransmit and persist are mutually exclusive ; First, check if retransmit timer is not set, retransmit and persist are mutually exclusive
@ -454,7 +454,7 @@ TCP_set_persist:
align 4 align 4
TCP_xmit_timer: TCP_xmit_timer:
DEBUGF 1,"TCP_xmit_timer: socket=%x rtt=%d0ms\n", ebx, eax DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_xmit_timer: socket=%x rtt=%d0ms\n", ebx, eax
;TODO: update stats ;TODO: update stats

View File

@ -87,7 +87,7 @@ local .exit
dec [eax + TCP_SOCKET.timer_retransmission] dec [eax + TCP_SOCKET.timer_retransmission]
jnz .check_more2 jnz .check_more2
DEBUGF 1,"socket %x: Retransmission timer expired\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "socket %x: Retransmission timer expired\n", eax
push eax push eax
call TCP_output call TCP_output
@ -97,7 +97,7 @@ local .exit
dec [eax + TCP_SOCKET.timer_keepalive] dec [eax + TCP_SOCKET.timer_keepalive]
jnz .check_more3 jnz .check_more3
DEBUGF 1,"socket %x: Keepalive expired\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "socket %x: Keepalive expired\n", eax
cmp [eax + TCP_SOCKET.state], TCPS_ESTABLISHED cmp [eax + TCP_SOCKET.state], TCPS_ESTABLISHED
ja .dont_kill ja .dont_kill
@ -126,13 +126,13 @@ local .exit
dec [eax + TCP_SOCKET.timer_timed_wait] dec [eax + TCP_SOCKET.timer_timed_wait]
jnz .check_more5 jnz .check_more5
DEBUGF 1,"socket %x: 2MSL timer expired\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "socket %x: 2MSL timer expired\n", eax
.check_more5: .check_more5:
dec [eax + TCP_SOCKET.timer_persist] dec [eax + TCP_SOCKET.timer_persist]
jnz .loop jnz .loop
DEBUGF 1,"socket %x: persist timer expired\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "socket %x: persist timer expired\n", eax
call TCP_set_persist call TCP_set_persist
mov [eax + TCP_SOCKET.t_force], 1 mov [eax + TCP_SOCKET.t_force], 1

View File

@ -27,7 +27,7 @@
align 4 align 4
TCP_usrclosed: TCP_usrclosed:
DEBUGF 1,"TCP_usrclosed: %x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_usrclosed: %x\n", eax
push ebx push ebx
mov ebx, [eax + TCP_SOCKET.t_state] mov ebx, [eax + TCP_SOCKET.t_state]
@ -87,7 +87,7 @@ TCP_usrclosed:
align 4 align 4
TCP_disconnect: TCP_disconnect:
DEBUGF 1,"TCP_disconnect: %x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_disconnect: %x\n", eax
cmp [eax + TCP_SOCKET.t_state], TCPS_ESTABLISHED cmp [eax + TCP_SOCKET.t_state], TCPS_ESTABLISHED
jb TCP_close jb TCP_close

View File

@ -116,7 +116,7 @@ macro UDP_checksum IP1, IP2 { ; esi = ptr to udp packet, ecx = packet size
align 4 align 4
UDP_input: UDP_input:
DEBUGF 1,"UDP_input: size=%u\n", ecx DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: size=%u\n", ecx
; First validate, checksum ; First validate, checksum
@ -129,7 +129,7 @@ UDP_input:
jnz .checksum_mismatch jnz .checksum_mismatch
.no_checksum: .no_checksum:
DEBUGF 1,"UDP_input: checksum ok\n" DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: checksum ok\n"
; Convert length to little endian ; Convert length to little endian
@ -158,7 +158,7 @@ UDP_input:
cmp [eax + UDP_SOCKET.LocalPort], dx cmp [eax + UDP_SOCKET.LocalPort], dx
jne .next_socket jne .next_socket
DEBUGF 1,"UDP_input: socket=%x\n", eax DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: socket=%x\n", eax
;;; TODO: when packet is processed, check more sockets! ;;; TODO: when packet is processed, check more sockets!
@ -196,7 +196,7 @@ UDP_input:
call mutex_lock call mutex_lock
popa popa
DEBUGF 1,"UDP_input: new remote port=%x\n", cx ; FIXME: find a way to print big endian values with debugf DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: new remote port=%x\n", cx ; FIXME: find a way to print big endian values with debugf
mov [eax + UDP_SOCKET.RemotePort], cx mov [eax + UDP_SOCKET.RemotePort], cx
inc [eax + UDP_SOCKET.firstpacket] inc [eax + UDP_SOCKET.firstpacket]
@ -204,12 +204,12 @@ UDP_input:
.checksum_mismatch: .checksum_mismatch:
DEBUGF 2,"UDP_input: checksum mismatch\n" DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: checksum mismatch\n"
.dump: .dump:
call kernel_free call kernel_free
add esp, 4 ; pop (balance stack) add esp, 4 ; pop (balance stack)
DEBUGF 2,"UDP_input: dumping\n" DEBUGF DEBUG_NETWORK_VERBOSE,"UDP_input: dumping\n"
ret ret
@ -229,13 +229,13 @@ UDP_input:
align 4 align 4
UDP_output: UDP_output:
DEBUGF 1,"UDP_output: socket=%x bytes=%u data_ptr=%x\n", eax, ecx, esi DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_output: socket=%x bytes=%u data_ptr=%x\n", eax, ecx, esi
mov dx, [eax + UDP_SOCKET.RemotePort] mov dx, [eax + UDP_SOCKET.RemotePort]
DEBUGF 1,"UDP_output: remote port=%x, ", dx ; FIXME: find a way to print big endian values with debugf DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_output: remote port=%x, ", dx ; FIXME: find a way to print big endian values with debugf
rol edx, 16 rol edx, 16
mov dx, [eax + UDP_SOCKET.LocalPort] mov dx, [eax + UDP_SOCKET.LocalPort]
DEBUGF 1,"local port=%x\n", dx DEBUGF DEBUG_NETWORK_VERBOSE, "local port=%x\n", dx
sub esp, 8 ; Data ptr and data size will be placed here sub esp, 8 ; Data ptr and data size will be placed here
push edx esi push edx esi
@ -270,7 +270,7 @@ UDP_output:
mov [edi + UDP_header.Checksum], 0 mov [edi + UDP_header.Checksum], 0
UDP_checksum (edi-4), (edi-8) ; FIXME: IPv4 packet could have options.. UDP_checksum (edi-4), (edi-8) ; FIXME: IPv4 packet could have options..
DEBUGF 1,"UDP_output: sending with device %x\n", ebx DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_output: sending with device %x\n", ebx
call [ebx + NET_DEVICE.transmit] call [ebx + NET_DEVICE.transmit]
test eax, eax test eax, eax
jnz @f jnz @f
@ -280,7 +280,7 @@ UDP_output:
ret ret
.fail: .fail:
DEBUGF 1,"UDP_output: failed\n" DEBUGF DEBUG_NETWORK_ERROR, "UDP_output: failed\n"
add esp, 4+4+8 add esp, 4+4+8
or eax, -1 or eax, -1
ret ret