forked from KolibriOS/kolibrios
-Refactoring of network drivers.
-Ommitted unnescessary copying of packets in some drivers. -Some small updates in TCP (perhaps 50% done ?) git-svn-id: svn://kolibrios.org@1519 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
bec4526284
commit
084d99548d
@ -1,22 +1,18 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; 3Com network driver for KolibriOS ;;
|
||||
;; ;;
|
||||
;; Ported to KolibriOS net-branch by hidnplayr (28/05/10) ;;
|
||||
;; ;;
|
||||
;; Thanks to: scrap metal recyclers, whom provide me with ;;
|
||||
;; loads of hardware ;;
|
||||
;; diamond: who makes me understand KolibriOS ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; Ethernet Driver for KolibriOS
|
||||
;;
|
||||
;; 3c59x.asm
|
||||
;; Ported to KolibriOS net-branch by hidnplayr (28/05/10)
|
||||
;;
|
||||
;; Thanks to: scrap metal recyclers, whom provide me with loads of hardware
|
||||
;; diamond: who makes me understand KolibriOS
|
||||
;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; 3C59X.INC ;;
|
||||
@ -84,13 +80,14 @@
|
||||
;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
PROMISCIOUS equ 1
|
||||
|
||||
|
||||
format MS COFF
|
||||
|
||||
API_VERSION equ 0x01000100
|
||||
DRIVER_VERSION equ 5
|
||||
|
||||
MAX_DEVICES equ 16
|
||||
FORCE_FD equ 0 ; forcing full duplex mode makes sense at some cards and link types
|
||||
PROMISCIOUS equ 0 ; enables promiscous mode
|
||||
|
||||
DEBUG equ 1
|
||||
__DEBUG__ equ 1
|
||||
@ -101,47 +98,10 @@ include 'imports.inc'
|
||||
include 'fdo.inc'
|
||||
include 'netdrv.inc'
|
||||
|
||||
|
||||
OS_BASE equ 0
|
||||
new_app_base equ 0x60400000
|
||||
PROC_BASE equ OS_BASE+0x0080000
|
||||
|
||||
public START
|
||||
public service_proc
|
||||
public version
|
||||
|
||||
|
||||
virtual at ebx
|
||||
|
||||
device:
|
||||
|
||||
ETH_DEVICE
|
||||
|
||||
.rx_buffer dd ?
|
||||
.tx_buffer dd ?
|
||||
.dpd_buffer dd ?
|
||||
.upd_buffer dd ?
|
||||
.curr_upd dd ?
|
||||
.prev_dpd dd ?
|
||||
|
||||
.io_addr dd ?
|
||||
.pci_bus db ?
|
||||
.pci_dev db ?
|
||||
.irq_line db ?
|
||||
|
||||
.prev_tx_frame dd ?
|
||||
.ver_id db ?
|
||||
.full_bus_master db ?
|
||||
.has_hwcksm db ?
|
||||
.preamble db ?
|
||||
.dn_list_ptr_cleared db ?
|
||||
.self_directed_packet rb 20
|
||||
|
||||
.size = $ - device
|
||||
|
||||
end virtual
|
||||
|
||||
|
||||
struc DPD { ; Download Packet Descriptor
|
||||
|
||||
.next_ptr dd ?
|
||||
@ -172,17 +132,11 @@ virtual at 0
|
||||
upd UPD
|
||||
end virtual
|
||||
|
||||
|
||||
MAX_DEVICES equ 16
|
||||
FORCE_FD equ 0 ; forcing full duplex mode makes sense at some cards and link types
|
||||
|
||||
|
||||
; Ethernet frame symbols
|
||||
ETH_ALEN equ 6
|
||||
ETH_HLEN equ (2*ETH_ALEN+2)
|
||||
ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for
|
||||
; mininmum 64bytes frame length
|
||||
|
||||
; Registers
|
||||
REG_POWER_MGMT_CTRL equ 0x7c
|
||||
REG_UP_LIST_PTR equ 0x38
|
||||
@ -193,9 +147,11 @@ end virtual
|
||||
REG_TX_STATUS equ 0x1b
|
||||
REG_RX_STATUS equ 0x18
|
||||
REG_TX_DATA equ 0x10
|
||||
|
||||
; Common window registers
|
||||
REG_INT_STATUS equ 0xe
|
||||
REG_COMMAND equ 0xe
|
||||
|
||||
; Register window 7
|
||||
REG_MASTER_STATUS equ 0xc
|
||||
REG_POWER_MGMT_EVENT equ 0xc
|
||||
@ -203,6 +159,7 @@ end virtual
|
||||
REG_VLAN_ETHER_TYPE equ 0x4
|
||||
REG_VLAN_MASK equ 0x0
|
||||
REG_MASTER_ADDRESS equ 0x0
|
||||
|
||||
; Register window 6
|
||||
REG_BYTES_XMITTED_OK equ 0xc
|
||||
REG_BYTES_RCVD_OK equ 0xa
|
||||
@ -216,6 +173,7 @@ end virtual
|
||||
REG_MULTIPLE_COLLISIONS equ 0x2
|
||||
REG_SQE_ERRORS equ 0x1
|
||||
REG_CARRIER_LOST equ 0x0
|
||||
|
||||
; Register window 5
|
||||
REG_INDICATION_ENABLE equ 0xc
|
||||
REG_INTERRUPT_ENABLE equ 0xa
|
||||
@ -223,6 +181,7 @@ end virtual
|
||||
REG_RX_FILTER equ 0x8
|
||||
REG_RX_EARLY_THRESH equ 0x6
|
||||
REG_TX_START_THRESH equ 0x0
|
||||
|
||||
; Register window 4
|
||||
REG_UPPER_BYTES_OK equ 0xe
|
||||
REG_BAD_SSD equ 0xc
|
||||
@ -231,8 +190,10 @@ end virtual
|
||||
REG_NETWORK_DIAGNOSTIC equ 0x6
|
||||
REG_FIFO_DIAGNOSTIC equ 0x4
|
||||
REG_VCO_DIAGNOSTIC equ 0x2 ; may not supported
|
||||
|
||||
; Bits in register window 4
|
||||
BIT_AUTOSELECT equ 24
|
||||
|
||||
; Register window 3
|
||||
REG_TX_FREE equ 0xc
|
||||
REG_RX_FREE equ 0xa
|
||||
@ -240,6 +201,7 @@ end virtual
|
||||
REG_MAC_CONTROL equ 0x6
|
||||
REG_MAX_PKT_SIZE equ 0x4
|
||||
REG_INTERNAL_CONFIG equ 0x0
|
||||
|
||||
; Register window 2
|
||||
REG_RESET_OPTIONS equ 0xc
|
||||
REG_STATION_MASK_HI equ 0xa
|
||||
@ -248,6 +210,7 @@ end virtual
|
||||
REG_STATION_ADDRESS_HI equ 0x4
|
||||
REG_STATION_ADDRESS_MID equ 0x2
|
||||
REG_STATION_ADDRESS_LO equ 0x0
|
||||
|
||||
; Register window 1
|
||||
REG_TRIGGER_BITS equ 0xc
|
||||
REG_SOS_BITS equ 0xa
|
||||
@ -258,34 +221,42 @@ end virtual
|
||||
REG_SMB_STATUS equ 0x2
|
||||
REG_SMB_ADDRESS equ 0x1
|
||||
REG_SMB_FIFO_DATA equ 0x0
|
||||
|
||||
; Register window 0
|
||||
REG_EEPROM_DATA equ 0xc
|
||||
REG_EEPROM_COMMAND equ 0xa
|
||||
REG_BIOS_ROM_DATA equ 0x8
|
||||
REG_BIOS_ROM_ADDR equ 0x4
|
||||
|
||||
; Physical management bits
|
||||
BIT_MGMT_DIR equ 2 ; drive with the data written in mgmtData
|
||||
BIT_MGMT_DATA equ 1 ; MII management data bit
|
||||
BIT_MGMT_CLK equ 0 ; MII management clock
|
||||
|
||||
; MII commands
|
||||
MII_CMD_MASK equ (1111b shl 10)
|
||||
MII_CMD_READ equ (0110b shl 10)
|
||||
MII_CMD_WRITE equ (0101b shl 10)
|
||||
|
||||
; MII registers
|
||||
REG_MII_BMCR equ 0 ; basic mode control register
|
||||
REG_MII_BMSR equ 1 ; basic mode status register
|
||||
REG_MII_ANAR equ 4 ; auto negotiation advertisement register
|
||||
REG_MII_ANLPAR equ 5 ; auto negotiation link partner ability register
|
||||
REG_MII_ANER equ 6 ; auto negotiation expansion register
|
||||
|
||||
; MII bits
|
||||
BIT_MII_AUTONEG_COMPLETE equ 5 ; auto-negotiation complete
|
||||
BIT_MII_PREAMBLE_SUPPRESSION equ 6
|
||||
|
||||
; eeprom bits and commands
|
||||
EEPROM_CMD_READ equ 0x80
|
||||
EEPROM_BIT_BUSY equ 15
|
||||
|
||||
; eeprom registers
|
||||
EEPROM_REG_OEM_NODE_ADDR equ 0xa
|
||||
EEPROM_REG_CAPABILITIES equ 0x10
|
||||
|
||||
; Commands for command register
|
||||
SELECT_REGISTER_WINDOW equ (1 shl 11)
|
||||
|
||||
@ -306,7 +277,6 @@ end virtual
|
||||
EXTRA_PREAMBLE equ 0x4000
|
||||
|
||||
; Status
|
||||
|
||||
IntLatch equ 0x0001
|
||||
HostError equ 0x0002
|
||||
TxComplete equ 0x0004
|
||||
@ -315,18 +285,15 @@ end virtual
|
||||
RxEarly equ 0x0020
|
||||
IntReq equ 0x0040
|
||||
StatsFull equ 0x0080
|
||||
DMADone equ 0x0100 ; 1 shl 8
|
||||
DownComplete equ 0x0200 ; 1 shl 9
|
||||
UpComplete equ 0x0400 ; 1 shl 10
|
||||
DMADone equ 0x0100
|
||||
DownComplete equ 0x0200
|
||||
UpComplete equ 0x0400
|
||||
DMAInProgress equ 0x0800 ; 1 shl 11 (DMA controller is still busy)
|
||||
CmdInProgress equ 0x1000 ; 1 shl 12 (EL3_CMD is still busy)
|
||||
|
||||
S_5_INTS equ HostError + RxEarly + UpComplete + DownComplete ; + RxComplete + TxComplete + TxAvailable
|
||||
|
||||
|
||||
S_5_INTS equ HostError + RxEarly + UpComplete + DownComplete ;+ TxComplete + RxComplete + TxAvailable
|
||||
|
||||
; Commands
|
||||
|
||||
TotalReset equ 0 shl 11
|
||||
SelectWindow equ 1 shl 11
|
||||
StartCoax equ 2 shl 11
|
||||
@ -354,29 +321,47 @@ end virtual
|
||||
StatsEnable equ 21 shl 11
|
||||
StatsDisable equ 22 shl 11
|
||||
StopCoax equ 23 shl 11
|
||||
SetFilterBit equ 25 shl 11}
|
||||
|
||||
SetFilterBit equ 25 shl 11
|
||||
|
||||
; Rx mode bits
|
||||
|
||||
RxStation equ 1
|
||||
RxMulticast equ 2
|
||||
RxBroadcast equ 4
|
||||
RxProm equ 8
|
||||
|
||||
|
||||
; RX/TX buffers sizes
|
||||
|
||||
MAX_ETH_PKT_SIZE equ 1536 ; max packet size
|
||||
NUM_RX_DESC equ 4 ; a power of 2 number
|
||||
NUM_TX_DESC equ 4 ; a power of 2 number
|
||||
RX_BUFFER_SIZE equ (MAX_ETH_FRAME_SIZE*NUM_RX_DESC)
|
||||
TX_BUFFER_SIZE equ (MAX_ETH_FRAME_SIZE*NUM_TX_DESC)
|
||||
MAX_ETH_FRAME_SIZE equ 1520 ; size of ethernet frame + bytes alignment
|
||||
|
||||
virtual at ebx
|
||||
|
||||
device:
|
||||
|
||||
ETH_DEVICE
|
||||
|
||||
.dpd_buffer rd (dpd.size*NUM_TX_DESC)/4
|
||||
.upd_buffer rd (upd.size*NUM_RX_DESC)/4
|
||||
.curr_upd dd ?
|
||||
.prev_dpd dd ?
|
||||
|
||||
.io_addr dd ?
|
||||
.pci_bus db ?
|
||||
.pci_dev db ?
|
||||
.irq_line db ?
|
||||
|
||||
.prev_tx_frame dd ?
|
||||
.ver_id db ?
|
||||
.full_bus_master db ?
|
||||
.has_hwcksm db ?
|
||||
.preamble db ?
|
||||
.dn_list_ptr_cleared db ?
|
||||
.self_directed_packet rb 20
|
||||
|
||||
.size = $ - device
|
||||
|
||||
end virtual
|
||||
|
||||
section '.flat' code readable align 16
|
||||
|
||||
@ -513,21 +498,14 @@ proc service_proc stdcall, ioctl:dword
|
||||
mov [device.pci_dev], cl
|
||||
|
||||
; Now, it's time to find the base io addres of the PCI device
|
||||
|
||||
find_io [device.pci_bus], [device.pci_dev], [device.io_addr]
|
||||
|
||||
; We've found the io address, find IRQ now
|
||||
|
||||
find_irq [device.pci_bus], [device.pci_dev], [device.irq_line]
|
||||
|
||||
DEBUGF 1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
|
||||
[device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4
|
||||
|
||||
allocate_and_clear [device.tx_buffer], (MAX_ETH_FRAME_SIZE*NUM_TX_DESC), .err
|
||||
allocate_and_clear [device.rx_buffer], (MAX_ETH_FRAME_SIZE*NUM_RX_DESC), .err
|
||||
allocate_and_clear [device.dpd_buffer], (dpd.size*NUM_TX_DESC), .err
|
||||
allocate_and_clear [device.upd_buffer], (dpd.size*NUM_RX_DESC), .err
|
||||
|
||||
; Ok, the eth_device structure is ready, let's probe the device
|
||||
call probe ; this function will output in eax
|
||||
test eax, eax
|
||||
@ -579,8 +557,6 @@ proc service_proc stdcall, ioctl:dword
|
||||
; todo: reset device into virgin state
|
||||
|
||||
.err:
|
||||
stdcall KernelFree, [device.rx_buffer]
|
||||
stdcall KernelFree, [device.tx_buffer]
|
||||
stdcall KernelFree, ebx
|
||||
|
||||
|
||||
@ -613,7 +589,7 @@ endp
|
||||
;***************************************************************************
|
||||
|
||||
align 4
|
||||
probe: ; Tested - ok
|
||||
probe:
|
||||
|
||||
DEBUGF 1,"Probing 3com card\n"
|
||||
|
||||
@ -671,6 +647,11 @@ probe: ; Tested - ok
|
||||
jnz .boomerang_func
|
||||
mov [device.transmit], vortex_transmit
|
||||
DEBUGF 1,"Device is a vortex type\n"
|
||||
DEBUGF 1,"I'm sorry but vortex code hasnt been tested yet\n"
|
||||
DEBUGF 1,"Please contact me on hidnplayr@kolibrios.org\n"
|
||||
DEBUGF 1,"If you can help me finish it!\n"
|
||||
or eax, -1
|
||||
ret
|
||||
jmp @f
|
||||
.boomerang_func: ; full bus master, so use boomerang functions
|
||||
mov [device.transmit], boomerang_transmit
|
||||
@ -812,6 +793,9 @@ reset:
|
||||
mov ecx, 6
|
||||
rep stosd
|
||||
|
||||
; Set the mtu, kernel will be able to send now
|
||||
mov [device.mtu], 1514
|
||||
|
||||
ret
|
||||
|
||||
|
||||
@ -975,13 +959,9 @@ tx_reset:
|
||||
jnz .tx_reset_loop
|
||||
.tx_set_prev:
|
||||
; init last_dpd
|
||||
mov eax, [device.dpd_buffer]
|
||||
add eax, (NUM_TX_DESC-1)*dpd.size
|
||||
lea eax, [device.dpd_buffer + (NUM_TX_DESC-1)*dpd.size]
|
||||
mov [device.prev_dpd], eax
|
||||
|
||||
mov eax, [device.tx_buffer]
|
||||
add eax, (NUM_TX_DESC-1)*MAX_ETH_FRAME_SIZE
|
||||
mov [device.prev_tx_frame], eax
|
||||
.tx_enable:
|
||||
ret
|
||||
|
||||
@ -1004,59 +984,54 @@ rx_reset:
|
||||
set_io REG_COMMAND
|
||||
mov ax, RxReset or 0x4
|
||||
out dx, ax
|
||||
|
||||
; wait for RxReset to complete
|
||||
mov ecx, 200000
|
||||
.rx_reset_loop:
|
||||
.loop:
|
||||
in ax, dx
|
||||
test ah, 10000b ; check CmdInProgress
|
||||
dec ecx
|
||||
jnz .rx_reset_loop
|
||||
jnz .loop
|
||||
|
||||
; create upd ring
|
||||
lea eax, [device.upd_buffer]
|
||||
GetRealAddr
|
||||
mov edi, eax ; real addr of first descr
|
||||
|
||||
mov eax, [device.upd_buffer]
|
||||
mov [device.curr_upd], eax
|
||||
call GetPgAddr
|
||||
mov esi, eax
|
||||
|
||||
mov eax, [device.rx_buffer]
|
||||
call GetPgAddr
|
||||
mov edi, eax
|
||||
|
||||
mov edx, [device.upd_buffer]
|
||||
add edx, (NUM_RX_DESC-1)*upd.size
|
||||
|
||||
mov eax, [device.upd_buffer]
|
||||
|
||||
push ebx
|
||||
mov ebx, [device.rx_buffer]
|
||||
lea esi, [device.upd_buffer] ; ptr to first descr
|
||||
lea edx, [device.upd_buffer + (NUM_RX_DESC-1)*upd.size] ; ptr to last descr
|
||||
|
||||
mov ecx, NUM_RX_DESC
|
||||
.upd_loop:
|
||||
mov [edx + upd.next_ptr], esi ; edx = upd buff
|
||||
|
||||
and [eax + upd.pkt_status], 0 ; eax = next upd buff
|
||||
mov [eax + upd.frag_addr], edi
|
||||
mov [eax + upd.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31)
|
||||
mov [eax + upd.realaddr], ebx
|
||||
.upd_loop:
|
||||
mov [edx + upd.next_ptr], edi
|
||||
|
||||
add edi, MAX_ETH_FRAME_SIZE
|
||||
add ebx, MAX_ETH_FRAME_SIZE
|
||||
push ecx edx
|
||||
stdcall KernelAlloc, MAX_ETH_FRAME_SIZE
|
||||
pop edx ecx
|
||||
mov [esi + upd.realaddr], eax
|
||||
call GetPgAddr
|
||||
mov [esi + upd.frag_addr], eax
|
||||
and [esi + upd.pkt_status], 0
|
||||
mov [esi + upd.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31)
|
||||
|
||||
DEBUGF 1,"UPD: lin=%x phys=%x len=%x next ptr=%x\n", [esi+upd.realaddr]:8, [esi+upd.frag_addr]:8, [esi+upd.frag_len]:8, edi
|
||||
DEBUGF 1,"UPD: cur=%x prev=%x\n", esi, edx
|
||||
|
||||
mov edx, esi
|
||||
add esi, upd.size
|
||||
mov edx, eax
|
||||
add eax, upd.size
|
||||
|
||||
add edi, upd.size
|
||||
dec ecx
|
||||
jnz .upd_loop
|
||||
|
||||
pop ebx
|
||||
|
||||
mov eax, [device.upd_buffer]
|
||||
call GetPgAddr
|
||||
lea eax, [device.upd_buffer]
|
||||
mov [device.curr_upd], eax
|
||||
GetRealAddr
|
||||
set_io 0
|
||||
set_io REG_UP_LIST_PTR
|
||||
out dx, eax
|
||||
|
||||
.rx_enable:
|
||||
.rx_enable:
|
||||
ret
|
||||
|
||||
|
||||
@ -2228,6 +2203,8 @@ vortex_transmit:
|
||||
mov ax, (10100b shl 11) + 1 ; StartDMADown
|
||||
out dx, ax
|
||||
.finish:
|
||||
call KernelFree
|
||||
add esp, 4
|
||||
ret
|
||||
|
||||
|
||||
@ -2245,26 +2222,32 @@ vortex_transmit:
|
||||
align 4
|
||||
boomerang_transmit:
|
||||
|
||||
DEBUGF 1,"Sending packet (boomerang)\n"
|
||||
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8]
|
||||
mov eax, [esp+4]
|
||||
DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
|
||||
[eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
|
||||
[eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
|
||||
[eax+13]:2,[eax+12]:2
|
||||
|
||||
cmp dword [esp+8], MAX_ETH_FRAME_SIZE
|
||||
ja .finish ; packet is too long
|
||||
jg .fail
|
||||
|
||||
call check_tx_status
|
||||
|
||||
test al, al
|
||||
jnz tx_reset
|
||||
|
||||
; calculate descriptor address
|
||||
mov eax, [device.prev_dpd]
|
||||
DEBUGF 1,"Previous DPD: %x\n", eax
|
||||
add eax, dpd.size
|
||||
mov ecx, [device.dpd_buffer]
|
||||
add ecx, NUM_TX_DESC*dpd.size
|
||||
cmp eax, ecx
|
||||
cmovae eax, [device.dpd_buffer] ; Wrap if needed
|
||||
mov esi, [device.prev_dpd]
|
||||
DEBUGF 1,"Previous DPD: %x\n", esi
|
||||
add esi, dpd.size
|
||||
lea ecx, [device.dpd_buffer + (NUM_TX_DESC)*dpd.size]
|
||||
cmp esi, ecx
|
||||
jl @f
|
||||
lea esi, [device.dpd_buffer] ; Wrap if needed
|
||||
@@:
|
||||
DEBUGF 1,"Found a free DPD: %x\n", esi
|
||||
|
||||
DEBUGF 1,"Found a free DPD: %x\n", eax
|
||||
push eax
|
||||
; check DnListPtr
|
||||
set_io 0
|
||||
set_io REG_DN_LIST_PTR
|
||||
@ -2272,91 +2255,56 @@ boomerang_transmit:
|
||||
; mark if Dn_List_Ptr is cleared
|
||||
test eax, eax
|
||||
setz [device.dn_list_ptr_cleared]
|
||||
|
||||
; finish if no more free descriptor is available - FIXME!
|
||||
cmp eax, [esp]
|
||||
pop eax
|
||||
jz .finish
|
||||
|
||||
|
||||
push eax ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
; calculate tx_buffer address
|
||||
mov edi, [device.prev_tx_frame]
|
||||
DEBUGF 1,"Previous TX frame:: %x\n", edi
|
||||
add edi, MAX_ETH_FRAME_SIZE
|
||||
|
||||
mov ecx, [device.tx_buffer]
|
||||
add ecx, NUM_TX_DESC*MAX_ETH_FRAME_SIZE
|
||||
cmp edi, ecx
|
||||
cmovae edi, [device.tx_buffer] ; Wrap if needed
|
||||
|
||||
DEBUGF 1,"Found place in TX buffer: %x\n", edi
|
||||
push edi ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
; cmp eax, esi
|
||||
; jz .finish
|
||||
|
||||
; update statistics
|
||||
inc [device.packets_tx]
|
||||
|
||||
mov ecx, [esp+8+8]
|
||||
mov ecx, [esp+8] ; buffer size
|
||||
add dword [device.bytes_tx], ecx
|
||||
adc dword [device.bytes_tx + 4], 0
|
||||
|
||||
; copy packet data
|
||||
mov esi, [esp+4+8]
|
||||
DEBUGF 1,"Copying %u bytes from %x to %x\n", ecx, esi, edi
|
||||
shr cx , 1
|
||||
jnc .nb
|
||||
movsb
|
||||
.nb:
|
||||
shr cx , 1
|
||||
jnc .nw
|
||||
movsw
|
||||
.nw:
|
||||
rep movsd
|
||||
|
||||
; program DPD
|
||||
mov eax, [esp] ; Tx buffer address
|
||||
and [esi+dpd.next_ptr], 0
|
||||
mov eax, [esp+4] ; Tx buffer address
|
||||
mov [esi+dpd.realaddr], eax
|
||||
call GetPgAddr
|
||||
mov edi, [esp]
|
||||
and edi, 4096 - 1
|
||||
or edi, eax
|
||||
|
||||
mov eax, [esp+4] ; descriptor
|
||||
DEBUGF 1,"Frag addr is: %x\n", edi
|
||||
and [eax+dpd.next_ptr], 0
|
||||
mov [eax+dpd.frag_addr], edi
|
||||
|
||||
mov ecx, [esp+8+8] ; packet size
|
||||
mov [esi+dpd.frag_addr], eax
|
||||
mov ecx, [esp+8] ; packet size
|
||||
or ecx, 0x80000000 ; last fragment
|
||||
DEBUGF 1,"Frag size + flag is: %x\n", ecx
|
||||
mov [eax+dpd.frag_len], ecx
|
||||
mov [esi+dpd.frag_len], ecx
|
||||
|
||||
mov ecx, [esp+8] ; packet size
|
||||
; or ecx, 0x8000 ; transmission complete notification
|
||||
|
||||
or ecx, 1 shl 31
|
||||
|
||||
mov ecx, [esp+8+8] ; packet size
|
||||
or ecx, 0x8000 ; transmission complete notification
|
||||
; test byte [device.has_hwcksm], 0xff
|
||||
; jz @f
|
||||
; or ecx, (1 shl 26) ; set AddTcpChecksum
|
||||
;@@:
|
||||
DEBUGF 1,"Frag start_hdr + flag is: %x\n", ecx
|
||||
mov [eax+dpd.frame_start_hdr], ecx
|
||||
mov [esi+dpd.frame_start_hdr], ecx
|
||||
|
||||
DEBUGF 1,"DPD: lin=%x phys=%x len=%x start hdr=%x\n", [esi+dpd.realaddr]:8, [esi+dpd.frag_addr]:8, [esi+dpd.frag_len]:8, [esi+dpd.frame_start_hdr]:8
|
||||
|
||||
; calculate physical address
|
||||
mov edi, eax
|
||||
call GetPgAddr
|
||||
and edi, 4096 - 1
|
||||
or eax, edi
|
||||
; calculate physical address of dpd
|
||||
mov eax, esi
|
||||
GetRealAddr
|
||||
cmp [device.dn_list_ptr_cleared], 0
|
||||
jz .add_to_list
|
||||
|
||||
DEBUGF 1,"DN list ptr: %x\n", eax
|
||||
; write Dn_List_Ptr
|
||||
DEBUGF 1,"DPD phys addr=%x\n", eax
|
||||
set_io 0
|
||||
set_io REG_DN_LIST_PTR
|
||||
out dx, eax
|
||||
jmp .finish_pop
|
||||
.add_to_list:
|
||||
jmp .finish
|
||||
|
||||
.add_to_list:
|
||||
DEBUGF 1,"Adding To list\n"
|
||||
|
||||
push eax
|
||||
; DnStall
|
||||
set_io 0
|
||||
set_io REG_COMMAND
|
||||
@ -2364,47 +2312,46 @@ boomerang_transmit:
|
||||
out dx, ax
|
||||
|
||||
; wait for DnStall to complete
|
||||
|
||||
DEBUGF 1,"Waiting for DnStall\n"
|
||||
mov ecx, 6000
|
||||
.wait_for_stall:
|
||||
.wait_for_stall:
|
||||
in ax, dx ; read REG_INT_STATUS
|
||||
test ah, 10000b
|
||||
jz .dnstall_ok
|
||||
dec ecx
|
||||
jnz .wait_for_stall
|
||||
|
||||
.dnstall_ok:
|
||||
.dnstall_ok:
|
||||
DEBUGF 1,"DnStall ok!\n"
|
||||
mov eax, [esp] ; prev_tx_frame
|
||||
mov ecx, [device.prev_dpd]
|
||||
mov [ecx+dpd.next_ptr], eax
|
||||
|
||||
set_io 0
|
||||
set_io REG_DN_LIST_PTR
|
||||
in eax, dx
|
||||
|
||||
test eax, eax
|
||||
pop eax
|
||||
jnz .dnunstall
|
||||
|
||||
; if Dn_List_Ptr has been cleared fill it up
|
||||
DEBUGF 1,"DnList Ptr has been cleared\n"
|
||||
mov eax, [esp]
|
||||
out dx, eax
|
||||
|
||||
.dnunstall:
|
||||
.dnunstall:
|
||||
; DnUnStall
|
||||
set_io 0
|
||||
set_io REG_COMMAND
|
||||
mov ax, ((110b shl 11)+3)
|
||||
out dx, ax
|
||||
|
||||
.finish_pop:
|
||||
pop [device.prev_tx_frame]
|
||||
pop [device.prev_dpd]
|
||||
|
||||
.finish:
|
||||
.finish:
|
||||
mov [device.prev_dpd], esi
|
||||
xor eax, eax
|
||||
ret
|
||||
ret 8
|
||||
|
||||
.fail:
|
||||
stdcall KernelFree, [esp+4]
|
||||
ret 8
|
||||
|
||||
|
||||
;---------------------------------
|
||||
@ -2581,7 +2528,9 @@ int_vortex:
|
||||
|
||||
.read_frame:
|
||||
; program buffer address to read in
|
||||
stdcall KernelAlloc, ecx ; Allocate a buffer to put packet into
|
||||
push ecx
|
||||
stdcall KernelAlloc, MAX_ETH_FRAME_SIZE
|
||||
pop ecx
|
||||
test eax, eax
|
||||
jz .finish
|
||||
|
||||
@ -2672,14 +2621,13 @@ int_vortex:
|
||||
align 4
|
||||
int_boomerang:
|
||||
|
||||
; DEBUGF 1,"\nIRQ %x Boomerang\n",eax:2
|
||||
DEBUGF 1,"\nIRQ %x Boomerang\n",eax:2
|
||||
|
||||
; find pointer of device wich made IRQ occur
|
||||
|
||||
mov esi, BOOMERANG_LIST
|
||||
mov ecx, [BOOMERANG_DEVICES]
|
||||
|
||||
; DEBUGF 1,"Devices: %u\n", ecx
|
||||
test ecx, ecx
|
||||
jz .fail
|
||||
.nextdevice:
|
||||
@ -2705,7 +2653,6 @@ int_boomerang:
|
||||
.got_it:
|
||||
|
||||
DEBUGF 1,"Device: %x Status: %x ", ebx, eax
|
||||
|
||||
push ax
|
||||
; disable all INTS
|
||||
|
||||
@ -2713,13 +2660,6 @@ int_boomerang:
|
||||
mov ax, SetIntrEnb
|
||||
out dx, ax
|
||||
|
||||
;; acknowledge all int sources
|
||||
;
|
||||
; mov ax, word [esp]
|
||||
; and ax, 0xff
|
||||
; or ax, AckIntr
|
||||
; out dx, ax
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
test word[esp], UpComplete
|
||||
jz .noRX
|
||||
@ -2730,75 +2670,59 @@ int_boomerang:
|
||||
DEBUGF 1,"UpComplete\n"
|
||||
|
||||
; check if packet is uploaded
|
||||
mov eax, [device.curr_upd]
|
||||
test byte [eax+upd.pkt_status+1], 0x80 ; upPktComplete
|
||||
mov esi, [device.curr_upd]
|
||||
test byte [esi+upd.pkt_status+1], 0x80 ; upPktComplete
|
||||
jz .finish
|
||||
DEBUGF 1, "Current upd: %x\n", esi
|
||||
; packet is uploaded check for any error
|
||||
.check_error:
|
||||
test byte [eax+upd.pkt_status+1], 0x40 ; upError
|
||||
test byte [esi+upd.pkt_status+1], 0x40 ; upError
|
||||
jz .copy_packet_length
|
||||
DEBUGF 1,"Error in packet\n"
|
||||
and [eax+upd.pkt_status], 0 ; mark packet as read
|
||||
and [esi+upd.pkt_status], 0 ; mark packet as read
|
||||
jmp .finish
|
||||
.copy_packet_length:
|
||||
mov ecx, [eax+upd.pkt_status]
|
||||
mov ecx, [esi+upd.pkt_status]
|
||||
and ecx, 0x1fff
|
||||
cmp ecx, MAX_ETH_PKT_SIZE
|
||||
jbe .copy_packet
|
||||
and [eax+upd.pkt_status], 0
|
||||
jmp .finish
|
||||
|
||||
.copy_packet:
|
||||
DEBUGF 1, " data hw addr:%x\n", [eax+upd.frag_addr]
|
||||
; cmp ecx, MAX_ETH_PKT_SIZE
|
||||
; jbe .copy_packet
|
||||
; and [esi+upd.pkt_status], 0
|
||||
; jmp .finish
|
||||
; .copy_packet:
|
||||
|
||||
mov esi, [eax+upd.realaddr]
|
||||
|
||||
push esi ecx
|
||||
stdcall KernelAlloc, ecx ; Allocate a buffer to put packet into
|
||||
pop ecx esi
|
||||
test eax, eax
|
||||
jz .finish
|
||||
DEBUGF 1, "Received %u bytes in buffer %x\n", ecx, [esi+upd.realaddr]:8
|
||||
|
||||
push dword .loop ;.finish
|
||||
push ecx eax
|
||||
mov edi, eax
|
||||
|
||||
DEBUGF 1, " copying %u bytes from %x to %x\n", ecx, esi, edi
|
||||
push ecx
|
||||
push [esi+upd.realaddr]
|
||||
|
||||
; update statistics
|
||||
inc [device.packets_rx]
|
||||
|
||||
add dword [device.bytes_rx], ecx
|
||||
adc dword [device.bytes_rx + 4], 0
|
||||
|
||||
; copy packet data
|
||||
shr cx , 1
|
||||
jnc .nb
|
||||
movsb
|
||||
.nb:
|
||||
shr cx , 1
|
||||
jnc .nw
|
||||
movsw
|
||||
.nw:
|
||||
rep movsd
|
||||
; update UPD (Alloc new buffer for next packet)
|
||||
stdcall KernelAlloc, MAX_ETH_FRAME_SIZE
|
||||
mov [esi + upd.realaddr], eax
|
||||
GetRealAddr
|
||||
mov [esi + upd.frag_addr], eax
|
||||
and [esi + upd.pkt_status], 0
|
||||
mov [esi + upd.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31)
|
||||
|
||||
mov eax, [device.curr_upd]
|
||||
DEBUGF 1, "current upd: %x\n", eax
|
||||
and [eax + upd.pkt_status], 0 ; clear the ring buffer entry for reuse
|
||||
mov [eax + upd.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31) ;;;
|
||||
add eax, upd.size
|
||||
|
||||
mov ecx, [device.upd_buffer]
|
||||
add ecx, (NUM_RX_DESC)*upd.size
|
||||
|
||||
cmp eax, ecx
|
||||
cmovae eax, [device.upd_buffer]
|
||||
mov [device.curr_upd], eax
|
||||
DEBUGF 1, "next upd: %x\n", eax
|
||||
; Update UPD pointer
|
||||
add esi, upd.size
|
||||
lea ecx, [device.upd_buffer+(NUM_RX_DESC)*upd.size]
|
||||
cmp esi, ecx
|
||||
jl @f
|
||||
lea esi, [device.upd_buffer]
|
||||
@@:
|
||||
mov [device.curr_upd], esi
|
||||
DEBUGF 1, "Next upd: %x\n", esi
|
||||
|
||||
jmp EthReceiver
|
||||
|
||||
.loop:
|
||||
|
||||
mov ebx, [esp]
|
||||
jmp .receive
|
||||
|
||||
@ -2811,14 +2735,38 @@ int_boomerang:
|
||||
in eax, dx
|
||||
test ah, 0x20 ; UpStalled
|
||||
jz .noUpUnStall
|
||||
|
||||
DEBUGF 1, "upUnStalling\n"
|
||||
; issue upUnStall command
|
||||
set_io REG_COMMAND
|
||||
mov ax, ((11b shl 12)+1) ; upUnStall
|
||||
out dx, ax
|
||||
DEBUGF 1, "upUnStalling\n"
|
||||
.noUpUnStall:
|
||||
|
||||
;;;; FIXME: make upunstall work
|
||||
|
||||
.noUpUnStall:
|
||||
.noRX:
|
||||
test word[esp], DownComplete
|
||||
jz .noTX
|
||||
DEBUGF 1, "Downcomplete!\n"
|
||||
|
||||
mov ecx, NUM_TX_DESC
|
||||
lea esi, [device.dpd_buffer]
|
||||
.txloop:
|
||||
test [esi+dpd.frame_start_hdr], 1 shl 31
|
||||
jz .maybenext
|
||||
|
||||
and [esi+dpd.frame_start_hdr], 0
|
||||
push ecx
|
||||
stdcall KernelFree, [esi+dpd.realaddr]
|
||||
pop ecx
|
||||
|
||||
.maybenext:
|
||||
add esi, dpd.size
|
||||
dec ecx
|
||||
jnz .txloop
|
||||
|
||||
.noTX:
|
||||
pop ax
|
||||
|
||||
set_io 0
|
||||
@ -2826,11 +2774,6 @@ int_boomerang:
|
||||
or ax, AckIntr
|
||||
out dx, ax
|
||||
|
||||
; set_io REG_COMMAND
|
||||
; mov ax, AckIntr + IntLatch
|
||||
; out dx, ax
|
||||
|
||||
|
||||
set_io REG_INT_STATUS
|
||||
in ax, dx
|
||||
test ax, S_5_INTS
|
||||
@ -2841,18 +2784,14 @@ int_boomerang:
|
||||
mov ax, SetIntrEnb + S_5_INTS
|
||||
out dx, ax
|
||||
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
; End of code
|
||||
|
||||
align 4 ; Place all initialised data here
|
||||
|
||||
|
||||
|
||||
macro strtbl name, [string]
|
||||
{
|
||||
common
|
||||
@ -2866,7 +2805,7 @@ forward
|
||||
|
||||
VORTEX_DEVICES dd 0
|
||||
BOOMERANG_DEVICES dd 0
|
||||
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
|
||||
version dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
|
||||
my_service db '3C59X',0 ; max 16 chars include zero
|
||||
|
||||
|
||||
@ -3001,7 +2940,6 @@ dw 0x9210, IS_TORNADO or HAS_NWAY or HAS_HWCKSM
|
||||
; 3c920B-EMB-WNM Tornado
|
||||
HW_VERSIONS_SIZE = $ - hw_versions
|
||||
|
||||
|
||||
include_debug_strings ; All data wich FDO uses will be included here
|
||||
|
||||
section '.data' data readable writable align 16 ; place all uninitialized data place here
|
||||
|
@ -1,43 +1,37 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; RTL8029/ne2000 driver for KolibriOS ;;
|
||||
;; ;;
|
||||
;; based on RTL8029.asm driver for menuetos ;;
|
||||
;; and realtek8029.asm for SolarOS by Eugen Brasoveanu ;;
|
||||
;; ;;
|
||||
;; Written by hidnplayr@kolibrios.org ;;
|
||||
;; with help from CleverMouse ;;
|
||||
;; ;;
|
||||
;; GNU GENERAL PUBLIC LICENSE ;;
|
||||
;; Version 2, June 1991 ;;
|
||||
;; ;;
|
||||
;; current status (september 2009) - UNSTABLE ;;
|
||||
;; ;;
|
||||
;; based on RTL8029.asm driver for menuetos ;;
|
||||
;; and realtek8029.asm for SolarOS by Eugen Brasoveanu ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;$Revision$
|
||||
|
||||
format MS COFF
|
||||
|
||||
API_VERSION equ 0x01000100
|
||||
API_VERSION equ 0x01000100
|
||||
DRIVER_VERSION equ 5
|
||||
|
||||
DEBUG equ 1
|
||||
__DEBUG__ equ 1
|
||||
__DEBUG_LEVEL__ equ 1
|
||||
MAX_DEVICES equ 16
|
||||
|
||||
DEBUG equ 1
|
||||
__DEBUG__ equ 1
|
||||
__DEBUG_LEVEL__ equ 1
|
||||
|
||||
include 'proc32.inc'
|
||||
include 'imports.inc'
|
||||
include 'fdo.inc'
|
||||
include 'netdrv.inc'
|
||||
|
||||
OS_BASE equ 0
|
||||
new_app_base equ 0x60400000
|
||||
PROC_BASE equ OS_BASE+0x0080000
|
||||
|
||||
|
||||
virtual at ebx
|
||||
|
||||
device:
|
||||
@ -68,8 +62,6 @@ public START
|
||||
public service_proc
|
||||
public version
|
||||
|
||||
MAX_DEVICES equ 16 ; Max number of devices this driver may handle
|
||||
|
||||
P0_PSTART equ 0x01
|
||||
P0_PSTOP equ 0x02
|
||||
P0_BOUND equ 0x03
|
||||
@ -234,8 +226,8 @@ proc service_proc stdcall, ioctl:dword
|
||||
|
||||
; check if the device is already listed
|
||||
|
||||
mov esi, DEVICE_LIST
|
||||
mov ecx, [DEVICES]
|
||||
mov esi, device_list
|
||||
mov ecx, [devices]
|
||||
test ecx, ecx
|
||||
jz .firstdevice_pci
|
||||
|
||||
@ -269,8 +261,8 @@ proc service_proc stdcall, ioctl:dword
|
||||
|
||||
.isa:
|
||||
|
||||
mov esi, DEVICE_LIST
|
||||
mov ecx, [DEVICES]
|
||||
mov esi, device_list
|
||||
mov ecx, [devices]
|
||||
test ecx, ecx
|
||||
jz .firstdevice_isa
|
||||
mov al , [eax+3]
|
||||
@ -305,9 +297,9 @@ proc service_proc stdcall, ioctl:dword
|
||||
test eax, eax
|
||||
jnz .err ; If an error occured, exit
|
||||
|
||||
mov eax, [DEVICES]
|
||||
mov [DEVICE_LIST+4*eax], ebx
|
||||
inc [DEVICES]
|
||||
mov eax, [devices]
|
||||
mov [device_list+4*eax], ebx
|
||||
inc [devices]
|
||||
|
||||
mov [device.type], NET_TYPE_ETH
|
||||
call NetRegDev
|
||||
@ -346,7 +338,7 @@ endp
|
||||
|
||||
create_new_struct:
|
||||
|
||||
cmp [DEVICES], MAX_DEVICES
|
||||
cmp [devices], MAX_DEVICES
|
||||
jge .fail
|
||||
|
||||
push edx
|
||||
@ -572,7 +564,7 @@ nsr_001:
|
||||
nsr_002:
|
||||
out dx, al
|
||||
|
||||
;clear remote bytes count
|
||||
; clear remote bytes count
|
||||
set_io 0
|
||||
|
||||
xor al, al
|
||||
@ -584,7 +576,7 @@ nsr_002:
|
||||
out dx, al
|
||||
|
||||
|
||||
;initialize Receive configuration register
|
||||
; initialize Receive configuration register
|
||||
set_io P0_RCR
|
||||
mov al, 0x20 ; monitor mode
|
||||
out dx, al
|
||||
@ -670,6 +662,9 @@ nsr_002:
|
||||
mov ecx, 6
|
||||
rep stosd
|
||||
|
||||
; Set the mtu, kernel will be able to send now
|
||||
mov [device.mtu], 1514
|
||||
|
||||
; Indicate that we have successfully reset the card
|
||||
DEBUGF 2,"Done!\n"
|
||||
|
||||
@ -733,10 +728,14 @@ transmit:
|
||||
adc dword [device.bytes_tx + 4], 0
|
||||
|
||||
.finish:
|
||||
call Kernelfree
|
||||
add esp, 4
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.err:
|
||||
call Kernelfree
|
||||
add esp, 4
|
||||
or eax, -1
|
||||
ret
|
||||
|
||||
@ -752,8 +751,8 @@ int_handler:
|
||||
DEBUGF 2,"IRQ %x ",eax:2
|
||||
|
||||
; find pointer of device wich made INT occur
|
||||
mov esi, DEVICE_LIST
|
||||
mov ecx, [DEVICES]
|
||||
mov esi, device_list
|
||||
mov ecx, [devices]
|
||||
.nextdevice:
|
||||
mov ebx, [esi]
|
||||
|
||||
@ -1197,8 +1196,8 @@ epw_005: ; Wait for Remote DMA Complete
|
||||
;all initialized data place here
|
||||
align 4
|
||||
|
||||
DEVICES dd 0
|
||||
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
|
||||
devices dd 0
|
||||
version dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
|
||||
my_service db 'RTL8029/ne2000',0 ;max 16 chars include zero
|
||||
|
||||
device_1 db 'Realtek 8029',0
|
||||
@ -1213,7 +1212,7 @@ include_debug_strings
|
||||
|
||||
section '.data' data readable writable align 16 ;place all uninitialized data place here
|
||||
|
||||
DEVICE_LIST rd MAX_DEVICES
|
||||
device_list rd MAX_DEVICES
|
||||
|
||||
|
||||
|
||||
|
@ -5,20 +5,22 @@
|
||||
;; ;;
|
||||
;; Realtek 8139 driver for KolibriOS ;;
|
||||
;; ;;
|
||||
;; Written by hidnplayr@kolibrios.org ;;
|
||||
;; based on RTL8139.asm driver for menuetos ;;
|
||||
;; and realtek8139.asm for SolarOS by Eugen Brasoveanu ;;
|
||||
;; ;;
|
||||
;; 0.1 - x march 2009 ;;
|
||||
;; 0.2 - 8 november 2009 ;;
|
||||
;; Written by hidnplayr@kolibrios.org ;;
|
||||
;; ;;
|
||||
;; GNU GENERAL PUBLIC LICENSE ;;
|
||||
;; Version 2, June 1991 ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
format MS COFF
|
||||
|
||||
API_VERSION equ 0x01000100
|
||||
DRIVER_VERSION equ 5
|
||||
|
||||
MAX_DEVICES equ 16
|
||||
|
||||
DEBUG equ 1
|
||||
__DEBUG__ equ 1
|
||||
@ -29,46 +31,10 @@ include 'imports.inc'
|
||||
include 'fdo.inc'
|
||||
include 'netdrv.inc'
|
||||
|
||||
OS_BASE equ 0
|
||||
new_app_base equ 0x60400000
|
||||
PROC_BASE equ OS_BASE+0x0080000
|
||||
|
||||
public START
|
||||
public service_proc
|
||||
public version
|
||||
|
||||
|
||||
virtual at ebx
|
||||
|
||||
device:
|
||||
|
||||
ETH_DEVICE
|
||||
|
||||
.rx_buffer dd ?
|
||||
.tx_buffer dd ?
|
||||
.rx_data_offset dd ?
|
||||
.io_addr dd ?
|
||||
.curr_tx_desc db ?
|
||||
.pci_bus db ?
|
||||
.pci_dev db ?
|
||||
.irq_line db ?
|
||||
.hw_ver_id db ?
|
||||
|
||||
.size = $ - device
|
||||
|
||||
end virtual
|
||||
|
||||
|
||||
; RTL8139 specific defines
|
||||
|
||||
MAX_RTL8139 equ 16 ; Max number of devices this driver may handle
|
||||
TX_TIMEOUT equ 30 ; 300 milliseconds timeout
|
||||
|
||||
PCI_REG_CMD 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
|
||||
|
||||
REG_IDR0 equ 0x00
|
||||
REG_MAR0 equ 0x08 ; multicast filter register 0
|
||||
REG_MAR4 equ 0x0c ; multicast filter register 4
|
||||
@ -169,8 +135,8 @@ end virtual
|
||||
|
||||
RX_BUFFER_SIZE equ (8192 shl RBLEN);+16
|
||||
MAX_ETH_FRAME_SIZE equ 1516 ; exactly 1514 wthout CRC
|
||||
|
||||
NUM_TX_DESC equ 4
|
||||
TX_BUF_SIZE equ 4096 ; size of one tx buffer (set to 4kb because of KolibriOS's page size)
|
||||
|
||||
EE_93C46_REG_ETH_ID equ 7 ; MAC offset
|
||||
EE_93C46_READ_CMD equ (6 shl 6) ; 110b + 6bit address
|
||||
@ -228,6 +194,30 @@ end virtual
|
||||
TSR_CRS equ 1 SHL 31
|
||||
|
||||
|
||||
virtual at ebx
|
||||
|
||||
device:
|
||||
|
||||
ETH_DEVICE
|
||||
|
||||
.rx_buffer dd ?
|
||||
.tx_buffer dd ?
|
||||
.rx_data_offset dd ?
|
||||
.io_addr dd ?
|
||||
.curr_tx_desc db ?
|
||||
.last_tx_desc db ?
|
||||
.pci_bus db ?
|
||||
.pci_dev db ?
|
||||
.irq_line db ?
|
||||
.hw_ver_id db ?
|
||||
|
||||
.TX_DESC rd NUM_TX_DESC
|
||||
|
||||
.size = $ - device
|
||||
|
||||
end virtual
|
||||
|
||||
|
||||
|
||||
section '.flat' code readable align 16
|
||||
|
||||
@ -298,8 +288,8 @@ proc service_proc stdcall, ioctl:dword
|
||||
|
||||
; check if the device is already listed
|
||||
|
||||
mov esi, RTL8139_LIST
|
||||
mov ecx, [RTL8139_DEV]
|
||||
mov esi, device_list
|
||||
mov ecx, [devices]
|
||||
test ecx, ecx
|
||||
jz .firstdevice
|
||||
|
||||
@ -315,7 +305,7 @@ proc service_proc stdcall, ioctl:dword
|
||||
|
||||
; This device doesnt have its own eth_device structure yet, lets create one
|
||||
.firstdevice:
|
||||
cmp [RTL8139_DEV], MAX_RTL8139 ; First check if the driver can handle one more card
|
||||
cmp [devices], MAX_DEVICES ; First check if the driver can handle one more card
|
||||
jge .fail
|
||||
|
||||
push edx
|
||||
@ -355,7 +345,7 @@ proc service_proc stdcall, ioctl:dword
|
||||
|
||||
|
||||
allocate_and_clear [device.rx_buffer], (RX_BUFFER_SIZE+MAX_ETH_FRAME_SIZE), .err
|
||||
allocate_and_clear [device.tx_buffer], (TX_BUF_SIZE*NUM_TX_DESC), .err
|
||||
;; allocate_and_clear [device.tx_buffer], (TX_BUF_SIZE*NUM_TX_DESC), .err
|
||||
|
||||
; Ok, the eth_device structure is ready, let's probe the device
|
||||
|
||||
@ -363,10 +353,9 @@ proc service_proc stdcall, ioctl:dword
|
||||
test eax, eax
|
||||
jnz .err ; If an error occured, exit
|
||||
|
||||
mov eax, [RTL8139_DEV] ; Add the device structure to our device list
|
||||
mov [RTL8139_LIST+4*eax], ebx ; (IRQ handler uses this list to find device)
|
||||
inc [RTL8139_DEV] ;
|
||||
|
||||
mov eax, [devices] ; Add the device structure to our device list
|
||||
mov [device_list+4*eax], ebx ; (IRQ handler uses this list to find device)
|
||||
inc [devices] ;
|
||||
|
||||
mov [device.type], NET_TYPE_ETH
|
||||
call NetRegDev
|
||||
@ -393,7 +382,7 @@ proc service_proc stdcall, ioctl:dword
|
||||
|
||||
.err:
|
||||
stdcall KernelFree, dword [device.rx_buffer]
|
||||
stdcall KernelFree, dword [device.tx_buffer]
|
||||
;; stdcall KernelFree, dword [device.tx_buffer]
|
||||
stdcall KernelFree, ebx
|
||||
|
||||
|
||||
@ -613,6 +602,7 @@ reset:
|
||||
|
||||
mov [device.rx_data_offset], eax
|
||||
mov [device.curr_tx_desc], al
|
||||
mov [device.last_tx_desc], al
|
||||
|
||||
; clear packet/byte counters
|
||||
|
||||
@ -625,21 +615,6 @@ reset:
|
||||
set_io REG_MPC
|
||||
out dx , eax
|
||||
|
||||
; Set up the 4 Txbuffer descriptors
|
||||
|
||||
set_io REG_TSAD0
|
||||
mov eax, [device.tx_buffer]
|
||||
mov ecx, 4
|
||||
.loop:
|
||||
push eax
|
||||
call GetPgAddr
|
||||
DEBUGF 1,"Desc: %x ", eax
|
||||
out dx , eax
|
||||
add dx , 4
|
||||
pop eax
|
||||
add eax, TX_BUF_SIZE
|
||||
loop .loop
|
||||
|
||||
; set RxBuffer address, init RX buffer offset
|
||||
|
||||
mov eax, [device.rx_buffer]
|
||||
@ -658,6 +633,9 @@ reset:
|
||||
|
||||
call read_mac
|
||||
|
||||
; Set the mtu, kernel will be able to send now
|
||||
mov [device.mtu], 1514
|
||||
|
||||
; Indicate that we have successfully reset the card
|
||||
|
||||
DEBUGF 2,"Done!\n"
|
||||
@ -675,7 +653,6 @@ reset:
|
||||
;; pointer to device structure in ebx ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 4
|
||||
transmit:
|
||||
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8]
|
||||
@ -686,71 +663,69 @@ transmit:
|
||||
[eax+13]:2,[eax+12]:2
|
||||
|
||||
cmp dword [esp+8], MAX_ETH_FRAME_SIZE
|
||||
jg .finish ; packet is too long
|
||||
jg .fail
|
||||
cmp dword [esp+8], 60
|
||||
jl .finish ; packet is too short
|
||||
jl .fail
|
||||
|
||||
; check descriptor
|
||||
DEBUGF 1,"Checking descriptor, "
|
||||
; check if we own the discriptor
|
||||
set_io 0
|
||||
movzx ecx, [device.curr_tx_desc]
|
||||
mov edx, [device.io_addr]
|
||||
lea edx, [edx+ecx*4+REG_TSD0]
|
||||
shl ecx, 2
|
||||
lea edx, [edx+ecx+REG_TSD0]
|
||||
in ax, dx
|
||||
test ax, 0x1fff ; or no size given
|
||||
jz .send_packet
|
||||
and ax, (1 shl BIT_TOK) or (1 shl BIT_OWN)
|
||||
cmp ax, (1 shl BIT_TOK) or (1 shl BIT_OWN)
|
||||
jz .send_packet
|
||||
; wait for timeout
|
||||
DEBUGF 1,"Waiting for timeout, "
|
||||
test ax, (1 shl BIT_OWN)
|
||||
jz .wait_to_send
|
||||
|
||||
push edx ebx ; TODO : rtl8139 internal timer should be used instead
|
||||
stdcall Sleep, TX_TIMEOUT ; ? What registers does this destroy ?
|
||||
pop ebx edx
|
||||
.send_packet:
|
||||
; Set the buffer address
|
||||
set_io 0
|
||||
lea edx, [edx+ecx+REG_TSAD0]
|
||||
mov eax, [esp+4]
|
||||
mov [device.TX_DESC+ecx], eax
|
||||
GetRealAddr
|
||||
out dx, eax
|
||||
|
||||
in ax, dx
|
||||
and ax, (1 shl BIT_TOK) or (1 shl BIT_OWN)
|
||||
cmp ax, (1 shl BIT_TOK) or (1 shl BIT_OWN)
|
||||
jz .send_packet ; if chip hung, reset it
|
||||
push dx
|
||||
call reset ; reset the card
|
||||
pop dx
|
||||
.send_packet:
|
||||
DEBUGF 1,"Sending packet, "
|
||||
|
||||
push edx
|
||||
movzx eax, [device.curr_tx_desc] ; calculate the current tx_buffer address
|
||||
mov edx, TX_BUF_SIZE ;MAX_ETH_FRAME_SIZE ;
|
||||
mul edx ;
|
||||
mov edi, [device.tx_buffer] ;
|
||||
add edi, eax ; Store it in edi
|
||||
pop edx
|
||||
|
||||
mov esi, [esp+4] ; Copy data to that address
|
||||
mov ecx, [esp+8] ;
|
||||
shr ecx, 2 ;
|
||||
rep movsd ;
|
||||
mov ecx, [esp+8] ;
|
||||
and ecx, 3 ;
|
||||
rep movsb ;
|
||||
|
||||
inc [device.packets_tx] ;
|
||||
mov eax, [esp+8] ; Get packet size in eax
|
||||
; And the size of the buffer
|
||||
set_io 0
|
||||
lea edx, [edx+ecx+REG_TSD0]
|
||||
mov eax, [esp+8]
|
||||
; or eax, (ERTXTH shl BIT_ERTXTH) ; Early threshold
|
||||
out dx , eax
|
||||
|
||||
; Update stats
|
||||
inc [device.packets_tx]
|
||||
add dword [device.bytes_tx], eax
|
||||
adc dword [device.bytes_tx + 4], 0
|
||||
|
||||
; or eax, (ERTXTH shl BIT_ERTXTH) ; Set descriptor size and the early tx treshold into the correct Transmission status register (TSD0, TSD1, TSD2 or TSD3)
|
||||
out dx , eax ;
|
||||
|
||||
; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ...
|
||||
; get next descriptor
|
||||
inc [device.curr_tx_desc]
|
||||
and [device.curr_tx_desc], 3
|
||||
|
||||
DEBUGF 1," - Packet Sent! "
|
||||
.finish:
|
||||
DEBUGF 1," - Done!\n"
|
||||
ret
|
||||
DEBUGF 1,"Packet Sent! "
|
||||
xor eax, eax
|
||||
ret 8
|
||||
|
||||
.wait_to_send:
|
||||
|
||||
DEBUGF 1,"Waiting for timeout\n"
|
||||
|
||||
mov esi, 30
|
||||
stdcall Sleep
|
||||
|
||||
in ax, dx
|
||||
test ax, (1 shl BIT_OWN)
|
||||
jnz .send_packet
|
||||
|
||||
pusha
|
||||
call reset ; if chip hung, reset it
|
||||
popa
|
||||
|
||||
jmp .send_packet
|
||||
|
||||
.fail:
|
||||
DEBUGF 1,"failed!\n"
|
||||
or eax, -1
|
||||
ret 8
|
||||
|
||||
|
||||
|
||||
@ -761,16 +736,15 @@ transmit:
|
||||
;; Interrupt handler ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 4
|
||||
int_handler:
|
||||
|
||||
DEBUGF 1,"IRQ %x ",eax:2 ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO
|
||||
DEBUGF 1,"IRQ %x\n", eax:2 ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO
|
||||
|
||||
; find pointer of device wich made IRQ occur
|
||||
|
||||
mov esi, RTL8139_LIST
|
||||
mov ecx, [RTL8139_DEV]
|
||||
mov esi, device_list
|
||||
mov ecx, [devices]
|
||||
test ecx, ecx
|
||||
jz .fail
|
||||
.nextdevice:
|
||||
@ -799,7 +773,6 @@ int_handler:
|
||||
|
||||
;----------------------------------------------------
|
||||
; Received packet ok?
|
||||
|
||||
test ax, ISR_ROK
|
||||
jz @f
|
||||
push ax
|
||||
@ -836,7 +809,6 @@ int_handler:
|
||||
test eax, eax ; Test if we allocated succesfully
|
||||
jz .abort
|
||||
|
||||
|
||||
mov edi, eax ; Where we will copy too
|
||||
|
||||
mov esi, [esp] ; The buffer we will copy from
|
||||
@ -914,60 +886,78 @@ int_handler:
|
||||
|
||||
;----------------------------------------------------
|
||||
; Transmit error ?
|
||||
|
||||
@@:
|
||||
test ax, ISR_TER
|
||||
jz @f
|
||||
|
||||
push ax
|
||||
cmp [device.curr_tx_desc], 4
|
||||
jz .notxd
|
||||
|
||||
set_io 0
|
||||
movzx ecx, [device.curr_tx_desc]
|
||||
lea edx, [edx+ecx*4+REG_TSD0]
|
||||
in eax, dx
|
||||
|
||||
.notxd:
|
||||
test eax, TSR_TUN
|
||||
jz .nobun
|
||||
DEBUGF 2, "TX: FIFO Buffer underrun!\n"
|
||||
|
||||
.nobun:
|
||||
test eax, TSR_OWC
|
||||
jz .noowc
|
||||
DEBUGF 2, "TX: OWC!\n"
|
||||
|
||||
.noowc:
|
||||
test eax, TSR_TABT
|
||||
jz .notabt
|
||||
DEBUGF 2, "TX: TABT!\n"
|
||||
|
||||
.notabt:
|
||||
test eax, TSR_CRS
|
||||
jz .nocsl
|
||||
DEBUGF 2, "TX: Carrier Sense Lost!\n"
|
||||
|
||||
.nocsl:
|
||||
; test eax, TSR_OWN or TSR_TOK
|
||||
; jz .nofd
|
||||
; DEBUGF 1, "TX: Transmit OK (desc: %u)\n", ecx
|
||||
; push ax
|
||||
; cmp [device.curr_tx_desc], 4
|
||||
; jz .notxd
|
||||
;
|
||||
; .nofd:
|
||||
pop ax
|
||||
; set_io 0
|
||||
; movzx ecx, [device.curr_tx_desc]
|
||||
; lea edx, [edx+ecx*4+REG_TSD0]
|
||||
; in eax, dx
|
||||
;
|
||||
; .notxd:
|
||||
; test eax, TSR_TUN
|
||||
; jz .nobun
|
||||
; DEBUGF 2, "TX: FIFO Buffer underrun!\n"
|
||||
;
|
||||
; .nobun:
|
||||
; test eax, TSR_OWC
|
||||
; jz .noowc
|
||||
; DEBUGF 2, "TX: OWC!\n"
|
||||
;
|
||||
; .noowc:
|
||||
; test eax, TSR_TABT
|
||||
; jz .notabt
|
||||
; DEBUGF 2, "TX: TABT!\n"
|
||||
;
|
||||
; .notabt:
|
||||
; test eax, TSR_CRS
|
||||
; jz .nocsl
|
||||
; DEBUGF 2, "TX: Carrier Sense Lost!\n"
|
||||
;
|
||||
; .nocsl:
|
||||
; pop ax
|
||||
|
||||
;----------------------------------------------------
|
||||
; Transmit ok ?
|
||||
|
||||
@@:
|
||||
test ax, ISR_TOK
|
||||
jz @f
|
||||
|
||||
DEBUGF 1, "TX: Transmit OK (desc: %u)\n", [device.curr_tx_desc]:1
|
||||
push ax
|
||||
mov si, 4
|
||||
.txdesloop:
|
||||
movzx ecx, [device.last_tx_desc]
|
||||
shl ecx, 2
|
||||
|
||||
set_io 0
|
||||
set_io REG_TSD0
|
||||
add edx, ecx
|
||||
in eax, dx
|
||||
|
||||
test eax, TSR_TOK
|
||||
jz .notthisone
|
||||
mov eax, TSR_OWN
|
||||
out dx , eax
|
||||
DEBUGF 1,"TX OK: free buffer %x\n", [device.TX_DESC+ecx]:8
|
||||
stdcall KernelFree, [device.TX_DESC+ecx]
|
||||
.notthisone:
|
||||
|
||||
inc [device.last_tx_desc]
|
||||
and [device.last_tx_desc], 3
|
||||
|
||||
dec si
|
||||
jnz .txdesloop
|
||||
|
||||
.done:
|
||||
pop ax
|
||||
|
||||
;----------------------------------------------------
|
||||
; Rx buffer overflow ?
|
||||
|
||||
@@:
|
||||
test ax, ISR_RXOVW
|
||||
jz @f
|
||||
@ -975,16 +965,14 @@ int_handler:
|
||||
push ax
|
||||
DEBUGF 2,"RX-buffer overflow!\n"
|
||||
|
||||
mov edx, [device.io_addr]
|
||||
add edx, REG_ISR
|
||||
set_io 0
|
||||
set_io REG_ISR
|
||||
mov ax , ISR_FIFOOVW or ISR_RXOVW
|
||||
out dx , ax
|
||||
pop ax
|
||||
|
||||
;----------------------------------------------------
|
||||
; Packet underrun? ?
|
||||
|
||||
|
||||
; Packet underrun?
|
||||
@@:
|
||||
test ax, ISR_PUN
|
||||
jz @f
|
||||
@ -993,23 +981,21 @@ int_handler:
|
||||
|
||||
;----------------------------------------------------
|
||||
; Receive FIFO overflow ?
|
||||
|
||||
@@:
|
||||
test ax, ISR_FIFOOVW
|
||||
jz @f
|
||||
|
||||
push ax
|
||||
DEBUGF 2,"RX fifo overflox!\n"
|
||||
DEBUGF 2,"RX fifo overflow!\n"
|
||||
|
||||
mov edx, [device.io_addr]
|
||||
add edx, REG_ISR
|
||||
set_io 0
|
||||
set_io REG_ISR
|
||||
mov ax , ISR_FIFOOVW or ISR_RXOVW
|
||||
out dx , ax
|
||||
pop ax
|
||||
|
||||
;----------------------------------------------------
|
||||
; Something about Cable changed ?
|
||||
|
||||
@@:
|
||||
test ax, ISR_LENCHG
|
||||
jz .fail
|
||||
@ -1017,11 +1003,7 @@ int_handler:
|
||||
DEBUGF 2,"Cable changed!\n"
|
||||
call cable
|
||||
|
||||
; If none of the above events happened, just exit clearing int
|
||||
|
||||
.fail:
|
||||
|
||||
DEBUGF 1,"\n"
|
||||
ret
|
||||
|
||||
|
||||
@ -1213,10 +1195,11 @@ read_eeprom:
|
||||
|
||||
; End of code
|
||||
|
||||
section '.data' data readable writable align 16 ; place all uninitialized data place here
|
||||
align 4 ; Place all initialised data here
|
||||
|
||||
RTL8139_DEV dd 0
|
||||
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
|
||||
devices dd 0
|
||||
version dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
|
||||
my_service db 'RTL8139',0 ; max 16 chars include zero
|
||||
|
||||
device_1 db 'Realtek 8139',0
|
||||
@ -1229,7 +1212,8 @@ device_7 db 'Realtek 8139CP',0
|
||||
device_8 db 'Realtek 8101',0
|
||||
device_unknown db 'Unknown RTL8139 clone', 0
|
||||
|
||||
crosslist dd device_1
|
||||
crosslist:
|
||||
dd device_1
|
||||
dd device_2
|
||||
dd device_3
|
||||
dd device_4
|
||||
@ -1239,7 +1223,8 @@ crosslist dd device_1
|
||||
dd device_8
|
||||
dd device_unknown
|
||||
|
||||
hw_ver_array db VER_RTL8139 ; This array is used by the probe routine to find out wich version of the RTL8139 we are working with
|
||||
hw_ver_array: ; This array is used by the probe routine to find out wich version of the RTL8139 we are working with
|
||||
db VER_RTL8139
|
||||
db VER_RTL8139A
|
||||
db VER_RTL8139B
|
||||
db VER_RTL8139C
|
||||
@ -1253,7 +1238,5 @@ HW_VER_ARRAY_SIZE = $-hw_ver_array
|
||||
|
||||
include_debug_strings ; All data wich FDO uses will be included here
|
||||
|
||||
section '.data' data readable writable align 16 ; place all uninitialized data place here
|
||||
|
||||
RTL8139_LIST rd MAX_RTL8139 ; This list contains all pointers to device structures the driver is handling
|
||||
device_list rd MAX_DEVICES ; This list contains all pointers to device structures the driver is handling
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; DEC 21x4x driver for KolibriOS ;;
|
||||
@ -11,8 +11,6 @@
|
||||
;; ;;
|
||||
;; Written by hidnplayr@kolibrios.org ;;
|
||||
;; ;;
|
||||
;; 0.1 - 5 june 2010 ;;
|
||||
;; ;;
|
||||
;; GNU GENERAL PUBLIC LICENSE ;;
|
||||
;; Version 2, June 1991 ;;
|
||||
;; ;;
|
||||
@ -21,6 +19,9 @@
|
||||
format MS COFF
|
||||
|
||||
API_VERSION equ 0x01000100
|
||||
DRIVER_VERSION equ 5
|
||||
|
||||
MAX_DEVICES equ 16
|
||||
|
||||
DEBUG equ 1
|
||||
__DEBUG__ equ 1
|
||||
@ -31,22 +32,16 @@ include 'imports.inc'
|
||||
include 'fdo.inc'
|
||||
include 'netdrv.inc'
|
||||
|
||||
OS_BASE equ 0
|
||||
new_app_base equ 0x60400000
|
||||
PROC_BASE equ OS_BASE+0x0080000
|
||||
|
||||
public START
|
||||
public service_proc
|
||||
public version
|
||||
|
||||
|
||||
virtual at ebx
|
||||
|
||||
device:
|
||||
|
||||
ETH_DEVICE
|
||||
|
||||
; device specific
|
||||
.rx_p_des dd ? ; descriptors ring with received packets
|
||||
.tx_p_des dd ? ; descriptors ring with 'to transmit' packets
|
||||
.tx_free_des dd ? ; Tx descriptors available
|
||||
@ -63,10 +58,6 @@ virtual at ebx
|
||||
|
||||
end virtual
|
||||
|
||||
|
||||
|
||||
MAX_DEVICES equ 16
|
||||
|
||||
;-------------------------------------------
|
||||
; configuration registers
|
||||
;-------------------------------------------
|
||||
@ -381,7 +372,7 @@ proc service_proc stdcall, ioctl:dword
|
||||
|
||||
; check if the device is already listed
|
||||
|
||||
mov esi, DEVICE_LIST
|
||||
mov esi, device_list
|
||||
mov ecx, [devices]
|
||||
test ecx, ecx
|
||||
jz .firstdevice
|
||||
@ -442,7 +433,7 @@ proc service_proc stdcall, ioctl:dword
|
||||
; Ok, the eth_device structure is ready, let's probe the device
|
||||
; Because initialization fires IRQ, IRQ handler must be aware of this device
|
||||
mov eax, [devices] ; Add the device structure to our device list
|
||||
mov [DEVICE_LIST+4*eax], ebx ; (IRQ handler uses this list to find device)
|
||||
mov [device_list+4*eax], ebx ; (IRQ handler uses this list to find device)
|
||||
inc [devices] ;
|
||||
|
||||
call probe ; this function will output in eax
|
||||
@ -771,6 +762,9 @@ reset:
|
||||
mov ecx, 6
|
||||
rep stosd
|
||||
|
||||
; Set the mtu, kernel will be able to send now
|
||||
mov [device.mtu], 1514
|
||||
|
||||
DEBUGF 1,"Reset done\n"
|
||||
|
||||
ret
|
||||
@ -1000,15 +994,18 @@ transmit:
|
||||
|
||||
DEBUGF 1,"transmit ok\n"
|
||||
xor eax, eax
|
||||
call Kernelfree
|
||||
add esp, 4
|
||||
ret
|
||||
|
||||
.fail:
|
||||
DEBUGF 1,"transmit failed\n"
|
||||
or eax, -1
|
||||
call Kernelfree
|
||||
add esp, 4
|
||||
ret
|
||||
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Interrupt handler ;;
|
||||
@ -1025,7 +1022,7 @@ int_handler:
|
||||
mov ecx, [devices]
|
||||
test ecx, ecx
|
||||
jz .fail
|
||||
mov esi, DEVICE_LIST
|
||||
mov esi, device_list
|
||||
.nextdevice:
|
||||
mov ebx, dword [esi]
|
||||
|
||||
@ -1701,17 +1698,16 @@ mdio_write: ;int phy_id: edx, int location: edi, int value: ax)
|
||||
|
||||
|
||||
; End of code
|
||||
|
||||
align 4 ; Place all initialised data here
|
||||
|
||||
devices dd 0
|
||||
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
|
||||
version dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
|
||||
my_service db 'DEC21X4X',0 ; max 16 chars include zero
|
||||
|
||||
include_debug_strings ; All data wich FDO uses will be included here
|
||||
|
||||
section '.data' data readable writable align 16 ; place all uninitialized data place here
|
||||
|
||||
DEVICE_LIST rd MAX_DEVICES ; This list contains all pointers to device structures the driver is handling
|
||||
device_list rd MAX_DEVICES ; This list contains all pointers to device structures the driver is handling
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -187,47 +187,49 @@ macro virt_to_dma { ; input is eax
|
||||
}
|
||||
|
||||
macro NET_DEVICE {
|
||||
.type dd ?
|
||||
|
||||
.type dd ? ; Type field
|
||||
.mtu dd ? ; Maximal Transmission Unit
|
||||
.name dd ? ; Ptr to 0 terminated string
|
||||
|
||||
.unload dd ? ; Ptrs to driver functions
|
||||
.reset dd ? ;
|
||||
.transmit dd ? ;
|
||||
|
||||
.bytes_tx dq ? ; Statistics, updated by the driver
|
||||
.bytes_rx dq ? ;
|
||||
.packets_tx dd ? ;
|
||||
.packets_rx dd ? ;
|
||||
|
||||
.end:
|
||||
}
|
||||
|
||||
;struc ETH_DEVICE {
|
||||
macro ETH_DEVICE {
|
||||
NET_DEVICE
|
||||
; pointers to procedures
|
||||
.unload dd ?
|
||||
.reset dd ?
|
||||
.transmit dd ?
|
||||
.set_MAC dd ?
|
||||
.get_MAC dd ?
|
||||
|
||||
.set_mode dd ?
|
||||
.get_mode dd ?
|
||||
; status
|
||||
.bytes_tx dq ?
|
||||
.bytes_rx dq ?
|
||||
.packets_tx dd ?
|
||||
.packets_rx dd ?
|
||||
|
||||
.set_MAC dd ?
|
||||
.get_MAC dd ?
|
||||
|
||||
.mode dd ?
|
||||
.name dd ?
|
||||
.mac dp ?
|
||||
dp ? ; qword alignment
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
macro SLIP_DEVICE {
|
||||
NET_DEVICE
|
||||
; pointers to procedures
|
||||
.unload dd ?
|
||||
.reset dd ?
|
||||
.transmit dd ?
|
||||
|
||||
.set_mode dd ?
|
||||
.get_mode dd ?
|
||||
; status
|
||||
.bytes_tx dq ?
|
||||
.bytes_rx dq ?
|
||||
.packets_tx dd ?
|
||||
.packets_rx dd ?
|
||||
|
||||
.mode dd ?
|
||||
.name dd ?
|
||||
|
||||
}
|
||||
|
||||
macro GetRealAddr {
|
||||
@ -235,7 +237,7 @@ macro GetRealAddr {
|
||||
push eax
|
||||
call GetPgAddr
|
||||
and dword [esp], (PAGESIZE - 1)
|
||||
add eax, dword [esp]
|
||||
or eax, dword [esp]
|
||||
add esp, 4
|
||||
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -130,18 +130,18 @@ ARP_IP_to_MAC:
|
||||
; else
|
||||
; destination is remote, so pass to gateway
|
||||
|
||||
xor edx, edx ; TODO: find device num in edx
|
||||
xor edx, edx ;;; TODO: find device num in edx
|
||||
|
||||
mov ebx, [IP_LIST+edx]
|
||||
and ebx, [SUBNET_LIST+edx]
|
||||
mov ebx, [IP_LIST + edx]
|
||||
and ebx, [SUBNET_LIST + edx]
|
||||
|
||||
mov ecx, eax
|
||||
and ecx, [SUBNET_LIST+edx]
|
||||
and ecx, [SUBNET_LIST + edx]
|
||||
|
||||
cmp ecx, ebx
|
||||
je .local
|
||||
|
||||
mov eax, [GATEWAY_LIST+edx]
|
||||
mov eax, [GATEWAY_LIST + edx]
|
||||
DEBUGF 1,"requested IP is not on subnet, using gateway\n"
|
||||
|
||||
.local:
|
||||
@ -274,7 +274,8 @@ ARP_create_request:
|
||||
DEBUGF 1,"ARP Packet for device %x created successfully\n", ebx
|
||||
|
||||
push edx ecx
|
||||
jmp NET_send
|
||||
call [ebx + NET_DEVICE.transmit]
|
||||
ret
|
||||
|
||||
.exit:
|
||||
add esp, 8
|
||||
@ -572,7 +573,8 @@ ARP_handler:
|
||||
|
||||
DEBUGF 1,"ARP_Handler - Sending reply \n"
|
||||
|
||||
jmp NET_send ; And send it!
|
||||
call [ebx + NET_DEVICE.transmit]
|
||||
ret
|
||||
|
||||
.exit:
|
||||
call kernel_free
|
||||
|
@ -172,10 +172,10 @@ IPv4_handler: ; TODO: implement handler for IP options
|
||||
cmp [edx + IPv4_Packet.DestinationAddress], -1
|
||||
je .ip_ok
|
||||
|
||||
; ; maybe it's a multicast then
|
||||
;
|
||||
; mov eax, [edx + IPv4_Packet.DestinationAddress]
|
||||
; and eax, 0xff000000
|
||||
; maybe it's a multicast then
|
||||
|
||||
mov eax, [edx + IPv4_Packet.DestinationAddress]
|
||||
and eax, 0xff000000
|
||||
; cmp eax, 224 shl 24
|
||||
; je .ip_ok
|
||||
|
||||
|
@ -16,8 +16,6 @@
|
||||
|
||||
$Revision$
|
||||
|
||||
ETH_QUEUE_SIZE equ 16
|
||||
|
||||
struct ETH_FRAME
|
||||
.DstMAC dp ? ; destination MAC-address
|
||||
.SrcMAC dp ? ; source MAC-address
|
||||
@ -28,20 +26,14 @@ ends
|
||||
virtual at NET_DEVICE.end
|
||||
|
||||
ETH_DEVICE:
|
||||
.unload dd ?
|
||||
.reset dd ?
|
||||
.transmit dd ?
|
||||
.set_MAC dd ?
|
||||
.get_MAC dd ?
|
||||
|
||||
.set_mode dd ?
|
||||
.get_mode dd ?
|
||||
|
||||
.bytes_tx dq ?
|
||||
.bytes_rx dq ?
|
||||
.packets_tx dd ?
|
||||
.packets_rx dd ?
|
||||
.set_MAC dd ?
|
||||
.get_MAC dd ?
|
||||
|
||||
.mode dd ?
|
||||
.name dd ?
|
||||
.mac dp ?
|
||||
|
||||
end virtual
|
||||
@ -108,6 +100,9 @@ ETH_receiver:
|
||||
cmp ax, ETHER_ARP
|
||||
je ARP_handler
|
||||
|
||||
; cmp ax, ETHER_PPP_DISCOVERY
|
||||
; je PPPOE_discovery
|
||||
|
||||
DEBUGF 2,"Unknown ethernet packet type %x\n", ax
|
||||
|
||||
.dump:
|
||||
@ -138,7 +133,10 @@ ETH_create_packet:
|
||||
|
||||
DEBUGF 1,"Creating Ethernet Packet (size=%u): \n", ecx
|
||||
|
||||
cmp ecx, 1500 ;;;
|
||||
push esi
|
||||
mov esi, [NET_DRV_LIST] ;;; TODO: FIXME
|
||||
cmp ecx, [esi + NET_DEVICE.mtu]
|
||||
pop esi
|
||||
jg .exit
|
||||
|
||||
push ecx di eax ebx edx
|
||||
@ -171,7 +169,7 @@ ETH_create_packet:
|
||||
mov ebx, [NET_DRV_LIST + ebx]
|
||||
|
||||
cmp edx, 46 + ETH_FRAME.Data ; If data size is less then 46, add padding bytes
|
||||
jg .continue
|
||||
jge .continue
|
||||
mov edx, 46 + ETH_FRAME.Data
|
||||
.continue:
|
||||
|
||||
@ -240,23 +238,23 @@ ETH_API:
|
||||
ret
|
||||
|
||||
.packets_tx:
|
||||
mov eax, dword [eax + ETH_DEVICE.packets_tx]
|
||||
mov eax, dword [eax + NET_DEVICE.packets_tx]
|
||||
|
||||
ret
|
||||
|
||||
.packets_rx:
|
||||
mov eax, dword [eax + ETH_DEVICE.packets_rx]
|
||||
mov eax, dword [eax + NET_DEVICE.packets_rx]
|
||||
ret
|
||||
|
||||
.bytes_tx:
|
||||
mov ebx, dword [eax + ETH_DEVICE.bytes_tx + 4]
|
||||
mov eax, dword [eax + ETH_DEVICE.bytes_tx]
|
||||
mov ebx, dword [eax + NET_DEVICE.bytes_tx + 4]
|
||||
mov eax, dword [eax + NET_DEVICE.bytes_tx]
|
||||
mov [esp+20+4], ebx ; TODO: fix this ugly code
|
||||
ret
|
||||
|
||||
.bytes_rx:
|
||||
mov ebx, dword [eax + ETH_DEVICE.bytes_rx + 4]
|
||||
mov eax, dword [eax + ETH_DEVICE.bytes_rx]
|
||||
mov ebx, dword [eax + NET_DEVICE.bytes_rx + 4]
|
||||
mov eax, dword [eax + NET_DEVICE.bytes_rx]
|
||||
mov [esp+20+4], ebx ; TODO: fix this ugly code
|
||||
ret
|
||||
|
||||
@ -270,8 +268,7 @@ ETH_API:
|
||||
.write_mac:
|
||||
push ecx
|
||||
push dx
|
||||
mov eax, [eax + ETH_DEVICE.set_MAC]
|
||||
call eax
|
||||
call [eax + ETH_DEVICE.set_MAC]
|
||||
ret
|
||||
|
||||
.in_queue:
|
||||
|
@ -209,8 +209,8 @@ ICMP_input:
|
||||
pop ecx edx ebx
|
||||
mov word [edx + ICMP_Packet.Checksum], ax
|
||||
|
||||
jmp NET_send ; Send the reply
|
||||
; and return to caller of this proc
|
||||
call [ebx + NET_DEVICE.transmit]
|
||||
ret
|
||||
|
||||
|
||||
|
||||
@ -251,7 +251,7 @@ ICMP_input:
|
||||
add esp, 4
|
||||
sub edx, esi
|
||||
mov edi, edx
|
||||
;;; jmp SOCKET_input
|
||||
jmp SOCKET_input
|
||||
|
||||
.dump:
|
||||
DEBUGF 1,"ICMP_Handler - dumping\n"
|
||||
@ -264,11 +264,9 @@ ICMP_input:
|
||||
|
||||
;-----------------------------------------------------------------
|
||||
;
|
||||
; Note: ICMP only works on top of IP protocol :)
|
||||
; ICMP_output
|
||||
;
|
||||
; inputs:
|
||||
;
|
||||
; eax = dest ip
|
||||
; IN: eax = dest ip
|
||||
; ebx = source ip
|
||||
; ecx = data length
|
||||
; dh = type
|
||||
@ -281,7 +279,7 @@ ICMP_input:
|
||||
align 4
|
||||
ICMP_output:
|
||||
|
||||
DEBUGF 1,"Create ICMP Packet\n"
|
||||
DEBUGF 1,"Creating ICMP Packet\n"
|
||||
|
||||
push esi edi edx
|
||||
|
||||
@ -320,11 +318,10 @@ ICMP_output:
|
||||
rep movsb
|
||||
|
||||
sub edi, edx ;;; TODO: find a better way to remember start of packet
|
||||
mov ecx, [ebx + ETH_DEVICE.transmit]
|
||||
push edx edi ecx
|
||||
push edx edi
|
||||
DEBUGF 1,"Sending ICMP Packet\n"
|
||||
ret ; Send the packet (create_packet routine outputs pointer to routine to send packet in eax)
|
||||
|
||||
call [ebx + NET_DEVICE.transmit]
|
||||
ret
|
||||
.exit:
|
||||
DEBUGF 1,"Creating ICMP Packet failed\n"
|
||||
add esp, 3*4
|
||||
|
@ -74,7 +74,6 @@ virtual at IP_SOCKET.end
|
||||
.OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state)
|
||||
|
||||
.t_state dd ? ; TCB state
|
||||
.t_timer dd ? ; TCB timer (seconds)
|
||||
.t_rxtshift dd ?
|
||||
.t_rxtcur dd ?
|
||||
.t_dupacks dd ?
|
||||
@ -144,6 +143,16 @@ virtual at IP_SOCKET.end
|
||||
.ts_recent_age dd ?
|
||||
.last_ack_sent dd ?
|
||||
|
||||
|
||||
;-------
|
||||
; Timers
|
||||
|
||||
.timer_retransmission dw ? ; rexmt
|
||||
.timer_ack dw ?
|
||||
.timer_persist dw ?
|
||||
.timer_keepalive dw ? ; keepalive/syn timeout
|
||||
.timer_timed_wait dw ? ; also used as 2msl timer
|
||||
|
||||
.end:
|
||||
end virtual
|
||||
|
||||
@ -335,7 +344,7 @@ SOCKET_bind:
|
||||
jz s_error
|
||||
|
||||
.got_port:
|
||||
DEBUGF 1,"using local port: %u", bx
|
||||
DEBUGF 1,"using local port: %u\n", bx
|
||||
mov word [eax + UDP_SOCKET.LocalPort], bx
|
||||
|
||||
mov ebx, dword [edx + 4]
|
||||
@ -391,7 +400,7 @@ SOCKET_connect:
|
||||
mov bx , word [edx + 2]
|
||||
mov word [eax + UDP_SOCKET.RemotePort], bx
|
||||
mov [eax + UDP_SOCKET.firstpacket], 0
|
||||
DEBUGF 1,"remote port: %u ",bx
|
||||
DEBUGF 1,"remote port: %u\n",bx
|
||||
|
||||
mov ebx, dword [edx + 4]
|
||||
mov dword [eax + IP_SOCKET.RemoteIP], ebx
|
||||
@ -408,6 +417,8 @@ SOCKET_connect:
|
||||
add [TCP_sequence_num], 6400
|
||||
mov [eax + TCP_SOCKET.ISS], ebx
|
||||
|
||||
mov [eax + TCP_SOCKET.timer_keepalive], 120 ; 120*630ms => 75,6 seconds
|
||||
|
||||
lea ebx, [eax + SOCKET.lock]
|
||||
call wait_mutex
|
||||
|
||||
@ -417,7 +428,7 @@ SOCKET_connect:
|
||||
|
||||
mov bx , word [edx + 2]
|
||||
mov [eax + TCP_SOCKET.RemotePort], bx
|
||||
DEBUGF 1,"remote port: %u ",bx
|
||||
DEBUGF 1,"remote port: %u\n", bx
|
||||
|
||||
mov ebx, dword [edx + 4]
|
||||
mov [eax + IP_SOCKET.RemoteIP], ebx
|
||||
@ -435,6 +446,8 @@ SOCKET_connect:
|
||||
call SOCKET_find_port
|
||||
@@:
|
||||
|
||||
DEBUGF 1,"remote port: %u\n", [eax + TCP_SOCKET.LocalPort]:2
|
||||
|
||||
; mov [eax + TCP_SOCKET.t_state], TCB_SYN_SENT
|
||||
call TCP_output
|
||||
|
||||
|
@ -37,6 +37,8 @@ MAX_EPHEMERAL_PORT equ 61000
|
||||
; Ethernet protocol numbers
|
||||
ETHER_ARP equ 0x0608
|
||||
ETHER_IPv4 equ 0x0008 ; Reversed from 0800 for intel
|
||||
ETHER_PPP_DISCOVERY equ 0x6388
|
||||
ETHER_PPP_SESSION equ 0x6488
|
||||
|
||||
;Protocol family
|
||||
AF_UNSPEC equ 0
|
||||
@ -76,7 +78,20 @@ NET_TYPE_SLIP equ 2
|
||||
virtual at 0
|
||||
|
||||
NET_DEVICE:
|
||||
.type dd ?
|
||||
|
||||
.type dd ? ; Type field
|
||||
.mtu dd ? ; Maximal Transmission Unit
|
||||
.name dd ? ; Ptr to 0 terminated string
|
||||
|
||||
.unload dd ? ; Ptrs to driver functions
|
||||
.reset dd ? ;
|
||||
.transmit dd ? ;
|
||||
|
||||
.bytes_tx dq ? ; Statistics, updated by the driver
|
||||
.bytes_rx dq ? ;
|
||||
.packets_tx dd ? ;
|
||||
.packets_rx dd ? ;
|
||||
|
||||
.end:
|
||||
|
||||
end virtual
|
||||
@ -193,26 +208,17 @@ stack_handler:
|
||||
je .exit
|
||||
mov [net_10ms], eax
|
||||
|
||||
if ETH_QUEUE
|
||||
call ETH_handler
|
||||
call ETH_send_queued
|
||||
end if
|
||||
call TCP_10ms
|
||||
test [net_10ms], 0x0f ; 160ms
|
||||
jnz .exit
|
||||
|
||||
inc [net_tmr_count]
|
||||
cmp [net_tmr_count], 50
|
||||
je .500ms
|
||||
cmp [net_tmr_count], 100
|
||||
jne .exit
|
||||
; call TCP_timer_160ms
|
||||
|
||||
test [net_10ms], 0x3f ; 640ms
|
||||
jnz .exit
|
||||
|
||||
; call TCP_timer_640ms
|
||||
call ARP_decrease_entry_ttls
|
||||
call IPv4_decrease_fragment_ttls
|
||||
call TCP_timer_1000ms
|
||||
|
||||
mov [net_tmr_count], 0
|
||||
|
||||
.500ms:
|
||||
call TCP_500ms
|
||||
|
||||
.exit:
|
||||
ret
|
||||
@ -380,34 +386,6 @@ NET_ptr_to_num:
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
;--------------------------
|
||||
;
|
||||
; NET_send
|
||||
;
|
||||
; IN: ebx = ptr to device struct
|
||||
; [esp] = data ptr
|
||||
; [esp + 4] = data size
|
||||
;
|
||||
; OUT: /
|
||||
;
|
||||
;--------------------------
|
||||
align 4
|
||||
NET_send:
|
||||
|
||||
call [ebx + ETH_DEVICE.transmit] ;;;;
|
||||
|
||||
;;; TODO:check if packet was sent ok
|
||||
|
||||
call kernel_free
|
||||
add esp, 4
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
;-----------------------------------------------------------------
|
||||
;
|
||||
; checksum_1
|
||||
@ -563,7 +541,7 @@ sys_network:
|
||||
jnz @f
|
||||
|
||||
mov esi, [esi + NET_DRV_LIST]
|
||||
mov esi, [esi + ETH_DEVICE.name]
|
||||
mov esi, [esi + NET_DEVICE.name]
|
||||
mov edi, ecx
|
||||
|
||||
mov ecx, 64 ; max length
|
||||
@ -578,7 +556,7 @@ sys_network:
|
||||
jnz @f
|
||||
|
||||
mov esi, [esi + NET_DRV_LIST]
|
||||
call [esi + ETH_DEVICE.reset]
|
||||
call [esi + NET_DEVICE.reset]
|
||||
jmp .return
|
||||
|
||||
@@:
|
||||
@ -587,7 +565,7 @@ sys_network:
|
||||
jnz @f
|
||||
|
||||
mov esi, [esi + NET_DRV_LIST]
|
||||
call [esi + ETH_DEVICE.unload]
|
||||
call [esi + NET_DEVICE.unload]
|
||||
jmp .return
|
||||
|
||||
@@:
|
||||
@ -645,13 +623,13 @@ sys_protocols:
|
||||
cmp ax , ETHER_ARP
|
||||
je ARP_API
|
||||
|
||||
cmp ax , 1337
|
||||
cmp ax , 1337 ;;;;;
|
||||
je ETH_API
|
||||
|
||||
add esp, 4 ; if we reached here, no function was called, so we need to balance stack
|
||||
|
||||
.doesnt_exist:
|
||||
DEBUGF 1,"sys_protocols: protocol %u doesnt exist on device %u!\n",ax, bh
|
||||
DEBUGF 1,"sys_protocols: protocol %u doesnt exist on device %u!\n", ax, bh
|
||||
mov eax, -1
|
||||
|
||||
.return:
|
||||
|
@ -58,6 +58,22 @@ TCP_OPT_MAXSEG equ 2 ; Maximum Segment Size.
|
||||
TCP_OPT_WINDOW equ 3 ; window scale
|
||||
TCP_OPT_TIMESTAMP equ 8
|
||||
|
||||
; Fundamental timer values
|
||||
TCP_time_MSL equ 47 ; max segment lifetime (30s)
|
||||
TCP_time_re_min equ 2 ; min retransmission (1,28s)
|
||||
TCP_time_re_max equ 100 ; max retransmission (64s)
|
||||
TCP_time_pers_min equ 8 ; min persist (5,12s)
|
||||
TCP_time_pers_max equ 94 ; max persist (60,16s)
|
||||
TCP_time_keep_init equ 118 ; connectione stablishment (75,52s)
|
||||
TCP_time_keep_idle equ 4608 ; idle time before 1st probe (2h)
|
||||
TCP_time_keep_interval equ 118 ; between probes when no response (75,52s)
|
||||
TCP_time_rtt_default equ 5 ; default Round Trip Time (3,2s)
|
||||
|
||||
; timer constants
|
||||
TCP_max_rxtshift equ 12 ; max retransmissions waiting for ACK
|
||||
TCP_max_keepcnt equ 8 ; max keepalive probes
|
||||
|
||||
|
||||
struct TCP_segment
|
||||
.SourcePort dw ?
|
||||
.DestinationPort dw ?
|
||||
@ -113,24 +129,56 @@ TCP_init:
|
||||
mov ecx, (6*IP_MAX_INTERFACES)
|
||||
rep stosd
|
||||
|
||||
mov [TCP_sequence_num],1
|
||||
mov [TCP_sequence_num], 1
|
||||
|
||||
ret
|
||||
|
||||
|
||||
;----------------------
|
||||
;
|
||||
;
|
||||
;----------------------
|
||||
align 4
|
||||
TCP_timer_160ms:
|
||||
|
||||
mov eax, net_sockets
|
||||
.loop:
|
||||
mov eax, [eax + SOCKET.NextPtr]
|
||||
or eax, eax
|
||||
jz .exit
|
||||
|
||||
cmp [eax + SOCKET.Type], IP_PROTO_TCP
|
||||
jne .loop
|
||||
|
||||
dec [eax + TCP_SOCKET.timer_ack]
|
||||
jnz .loop
|
||||
|
||||
DEBUGF 1,"TCP ack for socket %x expired, time to piggyback!\n", eax
|
||||
|
||||
push eax
|
||||
call TCP_respond
|
||||
pop eax
|
||||
|
||||
jmp .loop
|
||||
|
||||
.exit:
|
||||
|
||||
ret
|
||||
|
||||
|
||||
;-----------------------------------------------------------------
|
||||
;
|
||||
; decrease socket ttls
|
||||
;
|
||||
; IN: /
|
||||
; OUT: /
|
||||
;
|
||||
; destroys: eax
|
||||
;
|
||||
;-----------------------------------------------------------------
|
||||
align 4
|
||||
TCP_timer_1000ms:
|
||||
; scan through all the active TCP sockets, decrementing active timers
|
||||
TCP_timer_640ms:
|
||||
|
||||
; Update TCP sequence number
|
||||
|
||||
add [TCP_sequence_num], 64000
|
||||
|
||||
; scan through all the active TCP sockets, decrementing ALL timers
|
||||
; timers do not have the chance to wrap because of the keepalive timer will kill the socket when it expires
|
||||
|
||||
mov eax, net_sockets
|
||||
.loop:
|
||||
@ -142,62 +190,40 @@ TCP_timer_1000ms:
|
||||
cmp [eax + SOCKET.Type], IP_PROTO_TCP
|
||||
jne .loop
|
||||
|
||||
cmp [eax + TCP_SOCKET.t_timer], 0
|
||||
jne .decrement_tcb
|
||||
;;;;;; cmp [eax + TCP_SOCKET.wndsizeTimer], 0
|
||||
jne .decrement_wnd
|
||||
jmp .loop
|
||||
dec [eax + TCP_SOCKET.timer_retransmission]
|
||||
jnz .check_more2
|
||||
|
||||
.decrement_tcb:
|
||||
; decrement it, delete socket if TCB timer = 0 & socket in timewait state
|
||||
dec [eax + TCP_SOCKET.t_timer]
|
||||
DEBUGF 1,"socket %x: Retransmission timer expired\n", eax
|
||||
|
||||
push eax
|
||||
call TCP_output
|
||||
pop eax
|
||||
|
||||
.check_more2:
|
||||
dec [eax + TCP_SOCKET.timer_keepalive]
|
||||
jnz .check_more3
|
||||
|
||||
DEBUGF 1,"socket %x: Keepalive expired\n", eax
|
||||
|
||||
;;; TODO: check socket state and handle accordingly
|
||||
|
||||
.check_more3:
|
||||
dec [eax + TCP_SOCKET.timer_timed_wait]
|
||||
jnz .check_more5
|
||||
|
||||
DEBUGF 1,"socket %x: 2MSL timer expired\n", eax
|
||||
|
||||
.check_more5:
|
||||
dec [eax + TCP_SOCKET.timer_persist]
|
||||
jnz .loop
|
||||
|
||||
cmp [eax + TCP_SOCKET.t_state], TCB_TIMED_WAIT
|
||||
jne .loop
|
||||
|
||||
push [eax + SOCKET.NextPtr]
|
||||
call SOCKET_free
|
||||
pop eax
|
||||
jmp .check_only
|
||||
|
||||
.decrement_wnd:
|
||||
;;;;;; dec [eax + TCP_SOCKET.wndsizeTimer]
|
||||
DEBUGF 1,"socket %x: persist timer expired\n", eax
|
||||
|
||||
jmp .loop
|
||||
.exit:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
;----------------------
|
||||
;
|
||||
; TCP_500ms
|
||||
;
|
||||
;----------------------
|
||||
align 4
|
||||
TCP_500ms:
|
||||
|
||||
add [TCP_sequence_num], 64000
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
||||
;----------------------
|
||||
;
|
||||
; TCP_10ms
|
||||
;
|
||||
;----------------------
|
||||
align 4
|
||||
TCP_10ms:
|
||||
|
||||
; todo: decrease timers
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
;-----------------------------------------------------------------
|
||||
;
|
||||
; TCP_input:
|
||||
@ -374,8 +400,9 @@ TCP_input:
|
||||
;-------------------------------------
|
||||
; Reset idle timer and keepalive timer
|
||||
|
||||
;;;; TODO: idle timer?
|
||||
|
||||
; TODO
|
||||
mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval
|
||||
|
||||
;-----------------------------------------
|
||||
; Process TCP options if not in LISTEN state
|
||||
@ -475,13 +502,14 @@ TCP_input:
|
||||
; Delete acknowledged bytes from send buffer
|
||||
|
||||
; Stop retransmit timer
|
||||
mov [ebx + TCP_SOCKET.timer_ack], 0
|
||||
|
||||
; Awaken waiting processes
|
||||
mov eax, ebx
|
||||
call SOCKET_notify_owner
|
||||
|
||||
; Generate more output
|
||||
|
||||
|
||||
|
||||
call TCP_output
|
||||
|
||||
jmp .drop
|
||||
|
||||
@ -518,8 +546,9 @@ TCP_input:
|
||||
add [ebx + TCP_SOCKET.RCV_NXT], ecx
|
||||
|
||||
; Add the data to the socket buffer
|
||||
|
||||
; The receiving process is awakened (by sorwakeup).
|
||||
mov eax, ebx
|
||||
;;; mov...
|
||||
call SOCKET_input
|
||||
|
||||
; The delayed-ACK flag is set and the input processing is complete.
|
||||
|
||||
@ -679,8 +708,8 @@ align 4
|
||||
jle @f
|
||||
mov [ebx + TCP_SOCKET.SND_NXT], eax
|
||||
|
||||
|
||||
; TODO: turn off retransmission timer
|
||||
mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval
|
||||
mov [ebx + TCP_SOCKET.timer_retransmission], 0
|
||||
|
||||
mov eax, [edx + TCP_segment.SequenceNumber]
|
||||
mov [ebx + TCP_SOCKET.IRS], eax
|
||||
@ -937,18 +966,6 @@ align 4
|
||||
jg .ack_dup
|
||||
jl .ack_nodup
|
||||
|
||||
; dd .ack_nodup ;TCB_CLOSED
|
||||
; dd .ack_nodup ;TCB_LISTEN
|
||||
; dd .ack_nodup ;TCB_SYN_SENT
|
||||
; dd .ack_syn_rcvd ;TCB_SYN_RECEIVED
|
||||
; dd .ack_dup ;TCB_ESTABLISHED
|
||||
; dd .ack_dup ;TCB_CLOSE_WAIT
|
||||
; dd .ack_dup ;TCB_FIN_WAIT_1
|
||||
; dd .ack_dup ;TCB_CLOSING
|
||||
; dd .ack_dup ;TCB_LAST_ACK
|
||||
; dd .ack_dup ;TCB_FIN_WAIT_2
|
||||
; dd .ack_dup ;TCB_TIMED_WAIT
|
||||
|
||||
;;;;;
|
||||
|
||||
.ack_dup:
|
||||
@ -960,7 +977,7 @@ align 4
|
||||
;;;; 887
|
||||
|
||||
;-------------------------------------------------
|
||||
; If the congestion window was infalted to account
|
||||
; If the congestion window was inflated to account
|
||||
; for the other side's cached packets, retrace it
|
||||
|
||||
;;;; 888 - 902
|
||||
@ -971,6 +988,14 @@ align 4
|
||||
|
||||
;;;;; 903 - 926
|
||||
|
||||
mov [ebx + TCP_SOCKET.timer_retransmission], 0
|
||||
|
||||
mov eax, [ebx + TCP_SOCKET.SND_MAX]
|
||||
cmp eax, [edx + TCP_segment.AckNumber]
|
||||
je .all_outstanding
|
||||
mov [ebx + TCP_SOCKET.timer_retransmission], 120 ;;;; TODO: correct this value
|
||||
.all_outstanding:
|
||||
|
||||
|
||||
;-------------------------------------------
|
||||
; Open congestion window in response to ACKs
|
||||
@ -1614,7 +1639,7 @@ TCP_output:
|
||||
|
||||
.enter_persist:
|
||||
|
||||
DEBUGF 1,"Entering pesist state\n"
|
||||
DEBUGF 1,"Entering persist state\n"
|
||||
|
||||
|
||||
|
||||
@ -1748,7 +1773,7 @@ TCP_output:
|
||||
;;;; jz .fail
|
||||
|
||||
push edx eax
|
||||
call NET_send
|
||||
call [ebx + NET_DEVICE.transmit]
|
||||
ret
|
||||
|
||||
;----------------
|
||||
@ -1831,12 +1856,9 @@ TCP_output:
|
||||
|
||||
|
||||
DEBUGF 1,"Sending TCP Packet to device %x\n", ebx
|
||||
mov esi, [ebx + ETH_DEVICE.transmit]
|
||||
|
||||
call [ebx + NET_DEVICE.transmit]
|
||||
ret
|
||||
|
||||
|
||||
|
||||
;-------------------------
|
||||
;
|
||||
; TCP_outflags
|
||||
@ -1902,11 +1924,14 @@ TCP_drop:
|
||||
|
||||
;---------------------------------------
|
||||
;
|
||||
; TCP_respond
|
||||
; TCP_ack
|
||||
;
|
||||
; The easy way to send a RST/ACK segment
|
||||
; The easy way to send an ACK/RST/keepalive segment
|
||||
;
|
||||
; IN: eax = socket ptr
|
||||
; -or-
|
||||
; edx = packet ptr (eax must be 0)
|
||||
; cl = flags
|
||||
;
|
||||
; OUT: /
|
||||
;
|
||||
@ -1916,6 +1941,113 @@ TCP_respond:
|
||||
|
||||
DEBUGF 1,"TCP_respond\n"
|
||||
|
||||
;---------------------
|
||||
; Create the IP packet
|
||||
|
||||
push cx eax edx
|
||||
mov ebx, [eax + IP_SOCKET.LocalIP]
|
||||
mov eax, [eax + IP_SOCKET.RemoteIP]
|
||||
mov ecx, TCP_segment.Data
|
||||
mov di , IP_PROTO_TCP
|
||||
call IPv4_create_packet
|
||||
test edi, edi
|
||||
jz .error
|
||||
|
||||
;---------------------------
|
||||
; Now fill in the TCP header
|
||||
|
||||
pop ecx
|
||||
pop esi
|
||||
|
||||
test esi, esi
|
||||
; jz
|
||||
|
||||
|
||||
push edx eax
|
||||
|
||||
push dword .checksum
|
||||
je .use_segment
|
||||
jmp .use_socket
|
||||
|
||||
;---------------------
|
||||
; Fill in the checksum
|
||||
|
||||
.checksum:
|
||||
|
||||
push [esi + IP_SOCKET.LocalIP]
|
||||
push [esi + IP_SOCKET.RemoteIP]
|
||||
lea esi, [edi - 20]
|
||||
xor ecx, ecx
|
||||
call TCP_checksum
|
||||
|
||||
;--------------------
|
||||
; And send the segment
|
||||
|
||||
call [ebx + NET_DEVICE.transmit]
|
||||
ret
|
||||
|
||||
.error:
|
||||
DEBUGF 1,"TCP_ack failed\n"
|
||||
add esp, 4
|
||||
|
||||
ret
|
||||
|
||||
;---------------------------------------------------
|
||||
; Fill in the TCP header by using a received segment
|
||||
|
||||
.use_segment:
|
||||
|
||||
mov ax, [esi + TCP_segment.DestinationPort]
|
||||
rol ax, 8
|
||||
stosw
|
||||
mov ax, [esi + TCP_segment.SourcePort]
|
||||
rol ax, 8
|
||||
stosw
|
||||
mov eax, [esi + TCP_segment.AckNumber]
|
||||
bswap eax
|
||||
stosd
|
||||
xor eax, eax
|
||||
stosd
|
||||
mov al, 0x50 ; Dataoffset: 20 bytes
|
||||
stosb
|
||||
mov al, cl
|
||||
stosb
|
||||
mov ax, 1280
|
||||
rol ax, 8
|
||||
stosw ; window
|
||||
xor eax, eax
|
||||
stosd ; checksum + urgentpointer
|
||||
|
||||
ret
|
||||
|
||||
|
||||
;-----------------------------------------------
|
||||
; Fill in the TCP header by using the socket ptr
|
||||
|
||||
.use_socket:
|
||||
|
||||
mov ax, [esi + TCP_SOCKET.LocalPort]
|
||||
rol ax, 8
|
||||
stosw
|
||||
mov ax, [esi + TCP_SOCKET.RemotePort]
|
||||
rol ax, 8
|
||||
stosw
|
||||
mov eax, [esi + TCP_SOCKET.SND_NXT]
|
||||
bswap eax
|
||||
stosd
|
||||
mov eax, [esi + TCP_SOCKET.RCV_NXT]
|
||||
bswap eax
|
||||
stosd
|
||||
mov al, 0x50 ; Dataoffset: 20 bytes
|
||||
stosb
|
||||
mov al, cl
|
||||
stosb
|
||||
mov ax, [esi + TCP_SOCKET.RCV_WND]
|
||||
rol ax, 8
|
||||
stosw ; window
|
||||
xor eax, eax
|
||||
stosd ; checksum + urgentpointer
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
@ -252,8 +252,8 @@ UDP_output:
|
||||
|
||||
DEBUGF 1,"Sending UDP Packet to device %x\n", ebx
|
||||
|
||||
jmp NET_send
|
||||
|
||||
call [ebx + NET_DEVICE.transmit]
|
||||
ret
|
||||
.fail:
|
||||
add esp, 8+8
|
||||
ret
|
||||
|
Loading…
Reference in New Issue
Block a user