forked from KolibriOS/kolibrios
acpi:update
git-svn-id: svn://kolibrios.org@3589 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
996be4829b
commit
8dd796543b
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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 ===============
|
||||||
======================================================================
|
======================================================================
|
||||||
|
@ -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.
|
||||||
|
696
kernel/branches/Kolibri-acpi/drivers/usbhid.asm
Normal file
696
kernel/branches/Kolibri-acpi/drivers/usbhid.asm
Normal 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
|
1609
kernel/branches/Kolibri-acpi/drivers/usbstor.asm
Normal file
1609
kernel/branches/Kolibri-acpi/drivers/usbstor.asm
Normal file
File diff suppressed because it is too large
Load Diff
@ -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)
|
||||||
|
@ -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]
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
File diff suppressed because it is too large
Load Diff
@ -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
|
|
@ -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
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
@ -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
File diff suppressed because it is too large
Load Diff
@ -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
|
|
@ -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
|
|
@ -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
|
||||||
|
|
||||||
|
@ -38,8 +38,8 @@ ICMP_UNREACH_HOST_PROHIB = 10 ; ditto
|
|||||||
ICMP_UNREACH_TOSNET = 11 ; bad tos for net
|
ICMP_UNREACH_TOSNET = 11 ; bad tos for net
|
||||||
ICMP_UNREACH_TOSHOST = 12 ; bad tos for host
|
ICMP_UNREACH_TOSHOST = 12 ; bad tos for host
|
||||||
ICMP_UNREACH_FILTER_PROHIB = 13 ; admin prohib
|
ICMP_UNREACH_FILTER_PROHIB = 13 ; admin prohib
|
||||||
ICMP_UNREACH_HOST_PRECEDENCE = 14 ; host prec vio.
|
ICMP_UNREACH_HOST_PRECEDENCE = 14 ; host prec vio.
|
||||||
ICMP_UNREACH_PRECEDENCE_CUTOFF = 15 ; prec cutoff
|
ICMP_UNREACH_PRECEDENCE_CUTOFF = 15 ; prec cutoff
|
||||||
|
|
||||||
ICMP_SOURCEQUENCH = 4 ; Packet lost, slow down
|
ICMP_SOURCEQUENCH = 4 ; Packet lost, slow down
|
||||||
|
|
||||||
@ -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
|
||||||
|
|
||||||
|
@ -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
|
|
||||||
|
|
@ -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
|
||||||
|
@ -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
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user