Subversion Repositories Kolibri OS

Compare Revisions

Ignore whitespace Rev 1253 → Rev 1254

/kernel/branches/net/drivers/RTL8029.asm
758,7 → 758,7
;***************************************************************************
; Function
; transmit
; buffer in [esp], size in [esp+4], pointer to device struct in ebx
; buffer in [esp+4], size in [esp+8], pointer to device struct in ebx
;***************************************************************************
 
align 4
765,14 → 765,14
transmit:
mov ebp, ebx
 
mov esi, [esp]
mov ecx, [esp + 4]
mov esi, [esp + 4]
mov ecx, [esp + 8]
DEBUGF 2,"Transmitting packet, buffer:%x, size:%u\n",esi, ecx
DEBUGF 2,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",[esi+0]:2,[esi+1]:2,[esi+2]:2,[esi+3]:2,[esi+4]:2,[esi+5]:2,[esi+6]:2,[esi+7]:2,[esi+8]:2,[esi+9]:2,[esi+10]:2,[esi+11]:2,[esi+13]:2,[esi+12]:2
 
cmp dword [esp+4], ETH_FRAME_LEN
cmp dword [esp + 8], ETH_FRAME_LEN
jg .finish ; packet is too long
cmp dword [esp+4], 60
cmp dword [esp + 8], 60
jl .finish ; packet is too short
 
xor bl, bl
804,15 → 804,12
DEBUGF 2," - Packet Sent!\n"
 
inc [ebp+device.packets_tx] ;
mov eax, [esp+4] ; Get packet size in eax
mov eax, [esp + 8] ; Get packet size in eax
 
add dword [ebp + device.bytes_tx], eax
adc dword [ebp + device.bytes_tx + 4], 0
.finish:
mov ebx, ebp
 
call KernelFree
add esp, 4 ; pop (balance stack)
xor eax, eax
 
ret
/kernel/branches/net/drivers/RTL8139.asm
7,7 → 7,8
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; v0.1 - march 2009 ;;
;; 0.1 - x march 2009 ;;
;; 0.2 - 8 november 2009 ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
14,8 → 15,6
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
format MS COFF
 
API_VERSION equ 0x01000100
766,8 → 765,8
;; ;;
;; Transmit ;;
;; ;;
;; In: buffer pointer in [esp] ;;
;; size of buffer in [esp+4] ;;
;; In: buffer pointer in [esp+4] ;;
;; size of buffer in [esp+8] ;;
;; pointer to device structure in ebx ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
774,16 → 773,16
 
align 4
transmit:
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n",[esp],[esp+4]
mov eax, [esp]
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+4], MAX_ETH_FRAME_SIZE
cmp dword [esp+8], MAX_ETH_FRAME_SIZE
jg .finish ; packet is too long
cmp dword [esp+4], 60
cmp dword [esp+8], 60
jl .finish ; packet is too short
 
; check descriptor
822,16 → 821,16
add edi, eax ; Store it in edi
pop edx
 
mov esi, [esp] ; Copy data to that address
mov ecx, [esp+4] ;
mov esi, [esp+4] ; Copy data to that address
mov ecx, [esp+8] ;
shr ecx, 2 ;
rep movsd ;
mov ecx, [esp+4] ;
mov ecx, [esp+8] ;
and ecx, 3 ;
rep movsb ;
 
inc [ebx+device.packets_tx] ;
mov eax, [esp+4] ; Get packet size in eax
mov eax, [esp+8] ; Get packet size in eax
 
add dword [ebx + device.bytes_tx], eax
adc dword [ebx + device.bytes_tx + 4], 0
846,9 → 845,6
DEBUGF 2," - Packet Sent! "
.finish:
DEBUGF 2," - Done!\n"
call KernelFree
add esp, 4 ; pop (balance stack)
 
ret
 
 
/kernel/branches/net/drivers/pcnet32.asm
1138,8 → 1138,8
;; ;;
;; Transmit ;;
;; ;;
;; In: buffer pointer in [esp] ;;
;; size of buffer in [esp+4] ;;
;; In: buffer pointer in [esp+4] ;;
;; size of buffer in [esp+8] ;;
;; pointer to device structure in ebx ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1147,15 → 1147,15
align 4
transmit:
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n",[esp],[esp+4]
mov eax, [esp]
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+4], 1514
cmp dword [esp+8], 1514
jg .finish ; packet is too long
cmp dword [esp+4], 60
cmp dword [esp+8], 60
jl .finish ; packet is too short
 
; check descriptor
1167,8 → 1167,8
test byte [eax + buf_head.status + 1], 80h
jnz .nospace
; descriptor is free, copy data
mov esi, [esp]
mov ecx, [esp+4]
mov esi, [esp+4]
mov ecx, [esp+8]
mov edx, ecx
shr ecx, 2
and edx, 3
1176,7 → 1176,7
mov ecx, edx
rep movsb
; set length
mov ecx, [esp+4]
mov ecx, [esp+8]
neg ecx
mov [eax + buf_head.length], cx
; put to transfer queue
1195,15 → 1195,11
 
.finish:
DEBUGF 2," - Done!\n"
;;; call KernelFree
add esp, 4+4 ; pop (balance stack)
 
ret
 
.nospace:
DEBUGF 1, 'ERROR: no free transmit descriptors\n'
; todo: maybe somehow notify the kernel about the error?
add esp, 4+4
ret
 
 
/kernel/branches/net/drivers/sis900.asm
53,10 → 53,10
IOCTL IOCTL
end virtual
 
NUM_RX_DESC equ 4 ;* Number of RX descriptors *
NUM_TX_DESC equ 1 ;* Number of TX descriptors *
RX_BUFF_SZ equ 1520 ;* Buffer size for each Rx buffer *
TX_BUFF_SZ equ 1516 ;* Buffer size for each Tx buffer *
NUM_RX_DESC equ 4 ;* Number of RX descriptors *
NUM_TX_DESC equ 1 ;* Number of TX descriptors *
RX_BUFF_SZ equ 1520 ;* Buffer size for each Rx buffer *
TX_BUFF_SZ equ 1516 ;* Buffer size for each Tx buffer *
MAX_ETH_FRAME_SIZE equ 1516
 
TOTAL_BUFFERS_SIZE equ NUM_RX_DESC*RX_BUFF_SZ + NUM_TX_DESC*TX_BUFF_SZ
84,10 → 84,10
.pci_dev db ?
.irq_line db ?
.cur_rx db ?
.pci_revision db ?
.table_entries: db ?
.pci_revision db ?
.table_entries: db ?
align 4
.special_func: dd 0
.special_func: dd 0
.txd: times (3 * NUM_TX_DESC) dd 0
.rxd: times (3 * NUM_RX_DESC) dd 0
.size:
120,7 → 120,7
START:
cmp dword [esp+4], 1
jne .exit
stdcall RegService, my_service, service_proc
stdcall RegService, my_service, service_proc
ret 4
.exit:
xor eax, eax
130,7 → 130,7
; Currently handled requests are: SRV_GETVERSION = 0 and SRV_HOOK = 1.
service_proc:
; 1. Get parameter from the stack: [esp+4] is the first parameter,
; pointer to IOCTL structure.
; pointer to IOCTL structure.
mov edx, [esp+4] ; edx -> IOCTL
; 2. Get request code and select a handler for the code.
mov eax, [ebx+IOCTL.io_code]
151,7 → 151,7
jnz .fail
; 4. This is SRV_HOOK request, input defines the device to hook, no output.
; 4a. The driver works only with PCI devices,
; so input must be at least 3 bytes long.
; so input must be at least 3 bytes long.
cmp [edx + IOCTL.inp_size], 3
jl .fail
; 4b. First byte of input is bus type, 1 stands for PCI.
159,10 → 159,10
cmp byte [eax], 1
jne .fail
; 4c. Second and third bytes of the input define the device: bus and dev.
; Word in bx holds both bytes.
; Word in bx holds both bytes.
mov bx, [eax+1]
; 4d. Check if the device was already hooked,
; scan through the list of known devices.
; scan through the list of known devices.
mov esi, DEV_LIST
mov ecx, [NUM_DEV]
test ecx, ecx
195,7 → 195,7
; Note that get_MAC pointer is filled in initialization by SIS900_probe.
mov dword [ebx+device.reset], sis900_init
mov dword [ebx+device.transmit], transmit
; mov dword [ebx+device.get_MAC], read_mac
; mov dword [ebx+device.get_MAC], read_mac
mov dword [ebx+device.set_MAC], write_mac
mov dword [ebx+device.unload], unload
mov dword [ebx+device.name], my_service
206,7 → 206,7
mov edx, PCI_BASE_ADDRESS_0
.reg_check:
push edx
stdcall PciRead16, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], edx
stdcall PciRead16, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], edx
pop edx
test al, PCI_BASE_ADDRESS_SPACE_IO
jz .inc_reg
223,7 → 223,7
mov [ebx+device.io_addr], eax
 
; 4l. We've found the io address, find IRQ now
stdcall PciRead8, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x3c
stdcall PciRead8, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x3c
mov byte [ebx+device.irq_line], al
 
; 4m. Add new device to the list (required for int_handler).
320,21 → 320,21
; so it's worth to comment it out.
; SIS900_DEBUG equ 1
 
SIS900_ETH_ALEN equ 6 ;* Size of Ethernet address *
SIS900_ETH_HLEN equ 14 ;* Size of ethernet header *
SIS900_ETH_ZLEN equ 60 ;* Minimum packet length *
SIS900_ETH_ALEN equ 6 ;* Size of Ethernet address *
SIS900_ETH_HLEN equ 14 ;* Size of ethernet header *
SIS900_ETH_ZLEN equ 60 ;* Minimum packet length *
SIS900_DSIZE equ 0x00000fff
SIS900_CRC_SIZE equ 4
SIS900_RFADDR_shift equ 16
;SIS900 Symbolic offsets to registers.
SIS900_cr equ 0x0 ; Command Register
SIS900_cfg equ 0x4 ; Configuration Register
SIS900_cr equ 0x0 ; Command Register
SIS900_cfg equ 0x4 ; Configuration Register
SIS900_mear equ 0x8 ; EEPROM Access Register
SIS900_ptscr equ 0xc ; PCI Test Control Register
SIS900_isr equ 0x10 ; Interrupt Status Register
SIS900_imr equ 0x14 ; Interrupt Mask Register
SIS900_ier equ 0x18 ; Interrupt Enable Register
SIS900_epar equ 0x18 ; Enhanced PHY Access Register
SIS900_isr equ 0x10 ; Interrupt Status Register
SIS900_imr equ 0x14 ; Interrupt Mask Register
SIS900_ier equ 0x18 ; Interrupt Enable Register
SIS900_epar equ 0x18 ; Enhanced PHY Access Register
SIS900_txdp equ 0x20 ; Transmit Descriptor Pointer Register
SIS900_txcfg equ 0x24 ; Transmit Configuration Register
SIS900_rxdp equ 0x30 ; Receive Descriptor Pointer Register
344,32 → 344,32
SIS900_rfcr equ 0x48 ; Receive Filter Control Register
SIS900_rfdr equ 0x4C ; Receive Filter Data Register
SIS900_pmctrl equ 0xB0 ; Power Management Control Register
SIS900_pmer equ 0xB4 ; Power Management Wake-up Event Register
SIS900_pmer equ 0xB4 ; Power Management Wake-up Event Register
;SIS900 Command Register Bits
SIS900_RELOAD equ 0x00000400
SIS900_ACCESSMODE equ 0x00000200
SIS900_RESET equ 0x00000100
SIS900_SWI equ 0x00000080
SIS900_RxRESET equ 0x00000020
SIS900_TxRESET equ 0x00000010
SIS900_RxDIS equ 0x00000008
SIS900_RxENA equ 0x00000004
SIS900_TxDIS equ 0x00000002
SIS900_TxENA equ 0x00000001
SIS900_RELOAD equ 0x00000400
SIS900_ACCESSMODE equ 0x00000200
SIS900_RESET equ 0x00000100
SIS900_SWI equ 0x00000080
SIS900_RxRESET equ 0x00000020
SIS900_TxRESET equ 0x00000010
SIS900_RxDIS equ 0x00000008
SIS900_RxENA equ 0x00000004
SIS900_TxDIS equ 0x00000002
SIS900_TxENA equ 0x00000001
;SIS900 Configuration Register Bits
SIS900_DESCRFMT equ 0x00000100 ; 7016 specific
SIS900_REQALG equ 0x00000080
SIS900_SB equ 0x00000040
SIS900_POW equ 0x00000020
SIS900_EXD equ 0x00000010
SIS900_PESEL equ 0x00000008
SIS900_LPM equ 0x00000004
SIS900_BEM equ 0x00000001
SIS900_RND_CNT equ 0x00000400
SIS900_FAIR_BACKOFF equ 0x00000200
SIS900_EDB_MASTER_EN equ 0x00002000
SIS900_DESCRFMT equ 0x00000100 ; 7016 specific
SIS900_REQALG equ 0x00000080
SIS900_SB equ 0x00000040
SIS900_POW equ 0x00000020
SIS900_EXD equ 0x00000010
SIS900_PESEL equ 0x00000008
SIS900_LPM equ 0x00000004
SIS900_BEM equ 0x00000001
SIS900_RND_CNT equ 0x00000400
SIS900_FAIR_BACKOFF equ 0x00000200
SIS900_EDB_MASTER_EN equ 0x00002000
;SIS900 Eeprom Access Reigster Bits
SIS900_MDC equ 0x00000040
SIS900_MDC equ 0x00000040
SIS900_MDDIR equ 0x00000020
SIS900_MDIO equ 0x00000010 ; 7016 specific
SIS900_EECS equ 0x00000008
377,56 → 377,56
SIS900_EEDO equ 0x00000002
SIS900_EEDI equ 0x00000001
;SIS900 TX Configuration Register Bits
SIS900_ATP equ 0x10000000 ;Automatic Transmit Padding
SIS900_MLB equ 0x20000000 ;Mac Loopback Enable
SIS900_HBI equ 0x40000000 ;HeartBeat Ignore (Req for full-dup)
SIS900_CSI equ 0x80000000 ;CarrierSenseIgnore (Req for full-du
SIS900_ATP equ 0x10000000 ;Automatic Transmit Padding
SIS900_MLB equ 0x20000000 ;Mac Loopback Enable
SIS900_HBI equ 0x40000000 ;HeartBeat Ignore (Req for full-dup)
SIS900_CSI equ 0x80000000 ;CarrierSenseIgnore (Req for full-du
;SIS900 RX Configuration Register Bits
SIS900_AJAB equ 0x08000000 ;
SIS900_ATX equ 0x10000000 ;Accept Transmit Packets
SIS900_ARP equ 0x40000000 ;accept runt packets (<64bytes)
SIS900_AEP equ 0x80000000 ;accept error packets
SIS900_ATX equ 0x10000000 ;Accept Transmit Packets
SIS900_ARP equ 0x40000000 ;accept runt packets (<64bytes)
SIS900_AEP equ 0x80000000 ;accept error packets
;SIS900 Interrupt Reigster Bits
SIS900_WKEVT equ 0x10000000
SIS900_TxPAUSEEND equ 0x08000000
SIS900_TxPAUSE equ 0x04000000
SIS900_TxRCMP equ 0x02000000
SIS900_RxRCMP equ 0x01000000
SIS900_DPERR equ 0x00800000
SIS900_SSERR equ 0x00400000
SIS900_RMABT equ 0x00200000
SIS900_RTABT equ 0x00100000
SIS900_RxSOVR equ 0x00010000
SIS900_HIBERR equ 0x00008000
SIS900_SWINT equ 0x00001000
SIS900_MIBINT equ 0x00000800
SIS900_TxURN equ 0x00000400
SIS900_TxIDLE equ 0x00000200
SIS900_TxERR equ 0x00000100
SIS900_TxDESC equ 0x00000080
SIS900_TxOK equ 0x00000040
SIS900_RxORN equ 0x00000020
SIS900_RxIDLE equ 0x00000010
SIS900_RxEARLY equ 0x00000008
SIS900_RxERR equ 0x00000004
SIS900_RxDESC equ 0x00000002
SIS900_RxOK equ 0x00000001
SIS900_WKEVT equ 0x10000000
SIS900_TxPAUSEEND equ 0x08000000
SIS900_TxPAUSE equ 0x04000000
SIS900_TxRCMP equ 0x02000000
SIS900_RxRCMP equ 0x01000000
SIS900_DPERR equ 0x00800000
SIS900_SSERR equ 0x00400000
SIS900_RMABT equ 0x00200000
SIS900_RTABT equ 0x00100000
SIS900_RxSOVR equ 0x00010000
SIS900_HIBERR equ 0x00008000
SIS900_SWINT equ 0x00001000
SIS900_MIBINT equ 0x00000800
SIS900_TxURN equ 0x00000400
SIS900_TxIDLE equ 0x00000200
SIS900_TxERR equ 0x00000100
SIS900_TxDESC equ 0x00000080
SIS900_TxOK equ 0x00000040
SIS900_RxORN equ 0x00000020
SIS900_RxIDLE equ 0x00000010
SIS900_RxEARLY equ 0x00000008
SIS900_RxERR equ 0x00000004
SIS900_RxDESC equ 0x00000002
SIS900_RxOK equ 0x00000001
;SIS900 Interrupt Enable Reigster Bits
SIS900_IE equ 0x00000001
SIS900_IE equ 0x00000001
;SIS900 Revision ID
SIS900B_900_REV equ 0x03
SIS630A_900_REV equ 0x80
SIS630E_900_REV equ 0x81
SIS630S_900_REV equ 0x82
SIS630EA1_900_REV equ 0x83
SIS630ET_900_REV equ 0x84
SIS635A_900_REV equ 0x90
SIS900_960_REV equ 0x91
SIS900B_900_REV equ 0x03
SIS630A_900_REV equ 0x80
SIS630E_900_REV equ 0x81
SIS630S_900_REV equ 0x82
SIS630EA1_900_REV equ 0x83
SIS630ET_900_REV equ 0x84
SIS635A_900_REV equ 0x90
SIS900_960_REV equ 0x91
;SIS900 Receive Filter Control Register Bits
SIS900_RFEN equ 0x80000000
SIS900_RFAAB equ 0x40000000
SIS900_RFAAM equ 0x20000000
SIS900_RFAAP equ 0x10000000
SIS900_RFEN equ 0x80000000
SIS900_RFAAB equ 0x40000000
SIS900_RFAAM equ 0x20000000
SIS900_RFAAP equ 0x10000000
SIS900_RFPromiscuous equ 0x70000000
;SIS900 Reveive Filter Data Mask
SIS900_RFDAT equ 0x0000FFFF
438,19 → 438,19
SIS900_EEPROMChecksum equ 0x0b
;The EEPROM commands include the alway-set leading bit.
;SIS900 Eeprom Command
SIS900_EEread equ 0x0180
SIS900_EEwrite equ 0x0140
SIS900_EEerase equ 0x01C0
SIS900_EEread equ 0x0180
SIS900_EEwrite equ 0x0140
SIS900_EEerase equ 0x01C0
SIS900_EEwriteEnable equ 0x0130
SIS900_EEwriteDisable equ 0x0100
SIS900_EEeraseAll equ 0x0120
SIS900_EEwriteAll equ 0x0110
SIS900_EEaddrMask equ 0x013F
SIS900_EEcmdShift equ 16
SIS900_EEeraseAll equ 0x0120
SIS900_EEwriteAll equ 0x0110
SIS900_EEaddrMask equ 0x013F
SIS900_EEcmdShift equ 16
;For SiS962 or SiS963, request the eeprom software access
SIS900_EEREQ equ 0x00000400
SIS900_EEDONE equ 0x00000200
SIS900_EEGNT equ 0x00000100
SIS900_EEREQ equ 0x00000400
SIS900_EEDONE equ 0x00000200
SIS900_EEGNT equ 0x00000100
 
SIS900_pci_revision equ ebx+device.pci_revision
sis900_get_mac_func equ ebx+device.get_MAC
476,41 → 476,41
call SIS900_adjust_pci_device
;*****Get Card Revision******
stdcall PciRead8, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x08
mov [SIS900_pci_revision], al ;save the revision for later use
mov [SIS900_pci_revision], al ;save the revision for later use
;****** Look up through the sis900_specific_table
mov esi,sis900_specific_table
mov esi,sis900_specific_table
.probe_loop:
cmp dword [esi],0 ; Check if we reached end of the list
je .probe_loop_failed
cmp al,[esi] ; Check if revision is OK
je .probe_loop_ok
add esi,12 ; Advance to next entry
jmp .probe_loop
cmp dword [esi],0 ; Check if we reached end of the list
je .probe_loop_failed
cmp al,[esi] ; Check if revision is OK
je .probe_loop_ok
add esi,12 ; Advance to next entry
jmp .probe_loop
.probe_loop_failed:
jmp SIS900_Probe_Unsupported
jmp SIS900_Probe_Unsupported
;*********Find Get Mac Function*********
.probe_loop_ok:
mov eax,[esi+4] ; Get pointer to "get MAC" function
mov [sis900_get_mac_func],eax
mov eax,[esi+8] ; Get pointer to special initialization fn
mov [sis900_special_func],eax
mov eax,[esi+4] ; Get pointer to "get MAC" function
mov [sis900_get_mac_func],eax
mov eax,[esi+8] ; Get pointer to special initialization fn
mov [sis900_special_func],eax
;******** Get MAC ********
call dword [sis900_get_mac_func]
;******** Call special initialization fn if requested ********
cmp dword [sis900_special_func],0
je .no_special_init
cmp dword [sis900_special_func],0
je .no_special_init
call dword [sis900_special_func]
.no_special_init:
;******** Set table entries ********
mov al,[SIS900_pci_revision]
cmp al,SIS635A_900_REV
jae .ent16
cmp al,SIS900B_900_REV
je .ent16
mov byte [sis900_table_entries],8
jmp .ent8
mov al,[SIS900_pci_revision]
cmp al,SIS635A_900_REV
jae .ent16
cmp al,SIS900B_900_REV
je .ent16
mov byte [sis900_table_entries],8
jmp .ent8
.ent16:
mov byte [sis900_table_entries],16
mov byte [sis900_table_entries],16
.ent8:
;*******Probe for mii transceiver*******
;TODO!!*********************
520,10 → 520,10
 
SIS900_Probe_Unsupported:
if defined SIS900_DEBUG
mov esi, SIS900_Debug_Str_Unsupported
mov esi, SIS900_Debug_Str_Unsupported
call sys_msg_board_str
end if
or eax, -1
or eax, -1
ret
;***************************************************************************
; Function: sis900_init
537,10 → 537,10
;not done
;***************************************************************************
sis900_init:
call SIS900_reset ;Done
call SIS900_reset ;Done
call SIS900_init_rxfilter ;Done
call SIS900_init_txd ;Done
call SIS900_init_rxd ;Done
call SIS900_init_rxd ;Done
call SIS900_set_rx_mode ;done
call SIS900_set_tx_mode
;call SIS900_check_mode
552,7 → 552,7
out dx, eax
; globally enable interrupts
add edx, SIS900_ier-SIS900_imr
out dx, eax ; eax is still 1
out dx, eax ; eax is still 1
xor eax, eax
ret
 
569,37 → 569,37
end if
SIS900_reset:
movzx eax, [ebx+device.irq_line]
stdcall AttachIntHandler, eax, int_handler, 0
stdcall AttachIntHandler, eax, int_handler, 0
push ebp
mov ebp, [ebx+device.io_addr] ; base address
mov ebp, [ebx+device.io_addr] ; base address
;******Disable Interrupts and reset Receive Filter*******
xor eax, eax ; 0 to initialize
lea edx,[ebp+SIS900_ier]
out dx, eax ; Write 0 to location
lea edx,[ebp+SIS900_imr]
out dx, eax ; Write 0 to location
lea edx,[ebp+SIS900_rfcr]
out dx, eax ; Write 0 to location
xor eax, eax ; 0 to initialize
lea edx,[ebp+SIS900_ier]
out dx, eax ; Write 0 to location
lea edx,[ebp+SIS900_imr]
out dx, eax ; Write 0 to location
lea edx,[ebp+SIS900_rfcr]
out dx, eax ; Write 0 to location
;*******Reset Card***********************************************
lea edx,[ebp+SIS900_cr]
in eax, dx ; Get current Command Register
or eax, SIS900_RESET ; set flags
or eax, SIS900_RxRESET ;
or eax, SIS900_TxRESET ;
out dx, eax ; Write new Command Register
lea edx,[ebp+SIS900_cr]
in eax, dx ; Get current Command Register
or eax, SIS900_RESET ; set flags
or eax, SIS900_RxRESET ;
or eax, SIS900_TxRESET ;
out dx, eax ; Write new Command Register
;*******Wait Loop************************************************
push ebx
lea edx,[ebp+SIS900_isr]
mov ecx, 0x03000000 ; Status we would like to see from card
mov ebx, 2001 ; only loop 1000 times
lea edx,[ebp+SIS900_isr]
mov ecx, 0x03000000 ; Status we would like to see from card
mov ebx, 2001 ; only loop 1000 times
SIS900_Wait:
dec ebx ; 1 less loop
jz SIS900_DoneWait_e ; 1000 times yet?
in eax, dx ; move interrup status to eax
and eax, ecx
xor ecx, eax
jz SIS900_DoneWait
jmp SIS900_Wait
dec ebx ; 1 less loop
jz SIS900_DoneWait_e ; 1000 times yet?
in eax, dx ; move interrup status to eax
and eax, ecx
xor ecx, eax
jz SIS900_DoneWait
jmp SIS900_Wait
SIS900_DoneWait_e:
if defined SIS900_DEBUG
mov esi, SIS900_Debug_Reset_Failed
606,23 → 606,23
call sys_msg_board_str
end if
SIS900_DoneWait:
pop ebx
pop ebx
;*******Set Configuration Register depending on Card Revision********
lea edx,[ebp+SIS900_cfg]
mov eax, SIS900_PESEL ; Configuration Register Bit
mov cl, [SIS900_pci_revision] ; card revision
cmp cl, SIS635A_900_REV
je SIS900_RevMatch
cmp cl, SIS900B_900_REV ; Check card revision
je SIS900_RevMatch
out dx, eax ; no revision match
jmp SIS900_Reset_Complete
SIS900_RevMatch: ; Revision match
or eax, SIS900_RND_CNT ; Configuration Register Bit
out dx, eax
lea edx,[ebp+SIS900_cfg]
mov eax, SIS900_PESEL ; Configuration Register Bit
mov cl, [SIS900_pci_revision] ; card revision
cmp cl, SIS635A_900_REV
je SIS900_RevMatch
cmp cl, SIS900B_900_REV ; Check card revision
je SIS900_RevMatch
out dx, eax ; no revision match
jmp SIS900_Reset_Complete
SIS900_RevMatch: ; Revision match
or eax, SIS900_RND_CNT ; Configuration Register Bit
out dx, eax
SIS900_Reset_Complete:
xor eax, eax
pop ebp
xor eax, eax
pop ebp
ret
 
;***************************************************************************
637,36 → 637,36
;***************************************************************************
SIS900_init_rxfilter:
push ebp
mov ebp, [ebx+device.io_addr] ; base address
mov ebp, [ebx+device.io_addr] ; base address
;****Get Receive Filter Control Register ********
lea edx,[ebp+SIS900_rfcr]
in eax, dx ; get register
lea edx,[ebp+SIS900_rfcr]
in eax, dx ; get register
push eax
;****disable packet filtering before setting filter*******
mov eax, SIS900_RFEN ;move receive filter enable flag
not eax ;1s complement
and eax, [esp] ;disable receiver
out dx, eax ;set receive disabled
mov eax, SIS900_RFEN ;move receive filter enable flag
not eax ;1s complement
and eax, [esp] ;disable receiver
out dx, eax ;set receive disabled
;********load MAC addr to filter data register*********
xor ecx, ecx
xor ecx, ecx
SIS900_RXINT_Mac_Write:
;high word of eax tells card which mac byte to write
mov eax, ecx
lea edx,[ebp+SIS900_rfcr]
shl eax, 16 ;
out dx, eax ;
lea edx,[ebp+SIS900_rfdr]
mov ax, word [ebx+device.mac+ecx*2] ; Get Mac ID word
out dx, ax ; Send Mac ID
inc cl ; send next word
cmp cl, 3 ; more to send?
jne SIS900_RXINT_Mac_Write
mov eax, ecx
lea edx,[ebp+SIS900_rfcr]
shl eax, 16 ;
out dx, eax ;
lea edx,[ebp+SIS900_rfdr]
mov ax, word [ebx+device.mac+ecx*2] ; Get Mac ID word
out dx, ax ; Send Mac ID
inc cl ; send next word
cmp cl, 3 ; more to send?
jne SIS900_RXINT_Mac_Write
;********enable packet filitering *****
pop eax ;old register value
lea edx,[ebp+SIS900_rfcr]
or eax, SIS900_RFEN ;enable filtering
out dx, eax ;set register
pop ebp
pop eax ;old register value
lea edx,[ebp+SIS900_rfcr]
or eax, SIS900_RFEN ;enable filtering
out dx, eax ;set register
pop ebp
ret
 
;***************************************************************************
682,16 → 682,16
;***************************************************************************
SIS900_init_txd:
;********** initialize TX descriptor **************
mov [ebx+device.txd], dword 0 ;put link to next descriptor in link field
mov [ebx+device.txd+4],dword 0 ;clear status field
lea eax, [ebx+0x1000]
mov [ebx+device.txd], dword 0 ;put link to next descriptor in link field
mov [ebx+device.txd+4],dword 0 ;clear status field
lea eax, [ebx+0x1000]
call GetPgAddr
mov [ebx+device.txd+8], eax ;save address to buffer ptr field
mov [ebx+device.txd+8], eax ;save address to buffer ptr field
;*************** load Transmit Descriptor Register ***************
mov edx, [ebx+device.io_addr] ; base address
add edx, SIS900_txdp ; TX Descriptor Pointer
add eax, device.txd - 0x1000 ; First Descriptor
out dx, eax ; move the pointer
mov edx, [ebx+device.io_addr] ; base address
add edx, SIS900_txdp ; TX Descriptor Pointer
add eax, device.txd - 0x1000 ; First Descriptor
out dx, eax ; move the pointer
ret
 
;***************************************************************************
705,32 → 705,32
;*done
;***************************************************************************
SIS900_init_rxd:
xor ecx,ecx
mov [cur_rx], cl ;Set cuurent rx discriptor to 0
mov eax, ebx
xor ecx,ecx
mov [cur_rx], cl ;Set cuurent rx discriptor to 0
mov eax, ebx
call GetPgAddr
mov esi, eax
mov esi, eax
;******** init RX descriptors ********
SIS900_init_rxd_Loop:
mov edx, ecx ;current descriptor
imul edx, 12 ;
mov eax, ecx ;determine next link descriptor
inc eax ;
cmp eax, NUM_RX_DESC ;
jne SIS900_init_rxd_Loop_0 ;
xor eax, eax ;
SIS900_init_rxd_Loop_0: ;
imul eax, 12 ;
mov edx, ecx ;current descriptor
imul edx, 12 ;
mov eax, ecx ;determine next link descriptor
inc eax ;
cmp eax, NUM_RX_DESC ;
jne SIS900_init_rxd_Loop_0 ;
xor eax, eax ;
SIS900_init_rxd_Loop_0: ;
imul eax, 12 ;
lea eax, [eax+esi+device.rxd]
mov [ebx+device.rxd+edx], eax ;save link to next descriptor
mov [ebx+device.rxd+edx+4],dword RX_BUFF_SZ ;status bits init to buf size
mov eax, ecx ;find where the buf is located
imul eax,RX_BUFF_SZ ;
mov [ebx+device.rxd+edx], eax ;save link to next descriptor
mov [ebx+device.rxd+edx+4],dword RX_BUFF_SZ ;status bits init to buf size
mov eax, ecx ;find where the buf is located
imul eax,RX_BUFF_SZ ;
lea eax, [eax+esi+0x1000+NUM_TX_DESC*TX_BUFF_SZ]
mov [ebx+device.rxd+edx+8], eax ;save buffer pointer
inc ecx ;next descriptor
cmp ecx, NUM_RX_DESC ;
jne SIS900_init_rxd_Loop ;
mov [ebx+device.rxd+edx+8], eax ;save buffer pointer
inc ecx ;next descriptor
cmp ecx, NUM_RX_DESC ;
jne SIS900_init_rxd_Loop ;
;********* load Receive Descriptor Register with address of first
; descriptor*********
mov edx, [ebx+device.io_addr]
764,20 → 764,20
;***************************************************************************
SIS900_set_tx_mode:
push ebp
mov ebp,[ebx+device.io_addr]
lea edx,[ebp+SIS900_cr]
in eax, dx ; Get current Command Register
or eax, SIS900_TxENA ;Enable Receive
out dx, eax
lea edx,[ebp+SIS900_txcfg]; Transmit config Register offset
mov eax, SIS900_ATP ;allow automatic padding
or eax, SIS900_HBI ;allow heartbeat ignore
or eax, SIS900_CSI ;allow carrier sense ignore
or eax, 0x00600000 ;Max DMA Burst
or eax, 0x00000100 ;TX Fill Threshold
or eax, 0x00000020 ;TX Drain Threshold
out dx, eax
pop ebp
mov ebp,[ebx+device.io_addr]
lea edx,[ebp+SIS900_cr]
in eax, dx ; Get current Command Register
or eax, SIS900_TxENA ;Enable Receive
out dx, eax
lea edx,[ebp+SIS900_txcfg]; Transmit config Register offset
mov eax, SIS900_ATP ;allow automatic padding
or eax, SIS900_HBI ;allow heartbeat ignore
or eax, SIS900_CSI ;allow carrier sense ignore
or eax, 0x00600000 ;Max DMA Burst
or eax, 0x00000100 ;TX Fill Threshold
or eax, 0x00000020 ;TX Drain Threshold
out dx, eax
pop ebp
ret
 
;***************************************************************************
806,43 → 806,43
;***************************************************************************
SIS900_set_rx_mode:
push ebp
mov ebp,[ebx+device.io_addr]
mov ebp,[ebx+device.io_addr]
;**************update Multicast Hash Table in Receive Filter
xor cl, cl
xor cl, cl
SIS900_set_rx_mode_Loop:
mov eax, ecx
shl eax, 1
lea edx,[ebp+SIS900_rfcr] ; Receive Filter Control Reg offset
mov eax, 4 ;determine table entry
add al, cl
shl eax, 16
out dx, eax ;tell card which entry to modify
lea edx,[ebp+SIS900_rfdr] ; Receive Filter Control Reg offset
mov eax, 0xffff ;entry value
out dx, ax ;write value to table in card
inc cl ;next entry
cmp cl,[sis900_table_entries] ;
jl SIS900_set_rx_mode_Loop
mov eax, ecx
shl eax, 1
lea edx,[ebp+SIS900_rfcr] ; Receive Filter Control Reg offset
mov eax, 4 ;determine table entry
add al, cl
shl eax, 16
out dx, eax ;tell card which entry to modify
lea edx,[ebp+SIS900_rfdr] ; Receive Filter Control Reg offset
mov eax, 0xffff ;entry value
out dx, ax ;write value to table in card
inc cl ;next entry
cmp cl,[sis900_table_entries] ;
jl SIS900_set_rx_mode_Loop
;*******Set Receive Filter Control Register*************
lea edx,[ebp+SIS900_rfcr] ; Receive Filter Control Register offset
mov eax, SIS900_RFAAB ;accecpt all broadcast packets
or eax, SIS900_RFAAM ;accept all multicast packets
or eax, SIS900_RFAAP ;Accept all packets
or eax, SIS900_RFEN ;enable receiver filter
out dx, eax
lea edx,[ebp+SIS900_rfcr] ; Receive Filter Control Register offset
mov eax, SIS900_RFAAB ;accecpt all broadcast packets
or eax, SIS900_RFAAM ;accept all multicast packets
or eax, SIS900_RFAAP ;Accept all packets
or eax, SIS900_RFEN ;enable receiver filter
out dx, eax
;******Enable Receiver************
lea edx,[ebp+SIS900_cr] ; Command Register offset
in eax, dx ; Get current Command Register
or eax, SIS900_RxENA ;Enable Receive
out dx, eax
lea edx,[ebp+SIS900_cr] ; Command Register offset
in eax, dx ; Get current Command Register
or eax, SIS900_RxENA ;Enable Receive
out dx, eax
;*********Set
lea edx,[ebp+SIS900_rxcfg] ; Receive Config Register offset
mov eax, SIS900_ATX ;Accept Transmit Packets
; (Req for full-duplex and PMD Loopback)
or eax, 0x00600000 ;Max DMA Burst
or eax, 0x00000002 ;RX Drain Threshold, 8X8 bytes or 64bytes
out dx, eax ;
pop ebp
lea edx,[ebp+SIS900_rxcfg] ; Receive Config Register offset
mov eax, SIS900_ATX ;Accept Transmit Packets
; (Req for full-duplex and PMD Loopback)
or eax, 0x00600000 ;Max DMA Burst
or eax, 0x00000002 ;RX Drain Threshold, 8X8 bytes or 64bytes
out dx, eax ;
pop ebp
ret
 
;***************************************************************************
872,21 → 872,21
end if
SIS960_get_mac_addr:
push ebp
mov ebp,[ebx+device.io_addr]
mov ebp,[ebx+device.io_addr]
;**********Send Request for eeprom access*********************
lea edx,[ebp+SIS900_mear] ; Eeprom access register
mov eax, SIS900_EEREQ ; Request access to eeprom
out dx, eax ; Send request
xor ecx,ecx ;
lea edx,[ebp+SIS900_mear] ; Eeprom access register
mov eax, SIS900_EEREQ ; Request access to eeprom
out dx, eax ; Send request
xor ecx,ecx ;
;******Loop 4000 times and if access not granted error out*****
SIS96X_Get_Mac_Wait:
in eax, dx ;get eeprom status
and eax, SIS900_EEGNT ;see if eeprom access granted flag is set
jnz SIS900_Got_EEP_Access ;if it is, go access the eeprom
inc ecx ;else keep waiting
cmp ecx, 4000 ;have we tried 4000 times yet?
jl SIS96X_Get_Mac_Wait ;if not ask again
xor eax, eax ;return zero in eax indicating failure
in eax, dx ;get eeprom status
and eax, SIS900_EEGNT ;see if eeprom access granted flag is set
jnz SIS900_Got_EEP_Access ;if it is, go access the eeprom
inc ecx ;else keep waiting
cmp ecx, 4000 ;have we tried 4000 times yet?
jl SIS96X_Get_Mac_Wait ;if not ask again
xor eax, eax ;return zero in eax indicating failure
;*******Debug **********************
if defined SIS900_DEBUG
mov esi,SIS900_Debug_Str_GetMac_Failed
896,17 → 896,17
;**********EEprom access granted, read MAC from card*************
SIS900_Got_EEP_Access:
; zero based so 3-16 bit reads will take place
mov ecx, 2
mov ecx, 2
SIS96x_mac_read_loop:
mov eax, SIS900_EEPROMMACAddr ;Base Mac Address
add eax, ecx ;Current Mac Byte Offset
mov eax, SIS900_EEPROMMACAddr ;Base Mac Address
add eax, ecx ;Current Mac Byte Offset
push ecx
call sis900_read_eeprom ;try to read 16 bits
pop ecx
mov word [ebx+device.mac+ecx*2], ax ;save 16 bits to the MAC ID varible
dec ecx ;one less word to read
jns SIS96x_mac_read_loop ;if more read more
mov eax, 1 ;return non-zero indicating success
call sis900_read_eeprom ;try to read 16 bits
pop ecx
mov word [ebx+device.mac+ecx*2], ax ;save 16 bits to the MAC ID varible
dec ecx ;one less word to read
jns SIS96x_mac_read_loop ;if more read more
mov eax, 1 ;return non-zero indicating success
;*******Debug Print MAC ID to debug window**********************
if defined SIS900_DEBUG
mov esi,SIS900_Debug_Str_GetMac_Address2
916,10 → 916,10
end if
;**********Tell EEPROM We are Done Accessing It*********************
SIS960_get_mac_addr_done:
lea edx,[ebp+SIS900_mear] ; Eeprom access register
mov eax, SIS900_EEDONE ;tell eeprom we are done
out dx,eax
pop ebp
lea edx,[ebp+SIS900_mear] ; Eeprom access register
mov eax, SIS900_EEDONE ;tell eeprom we are done
out dx,eax
pop ebp
ret
;***************************************************************************
;* sis900_get_mac_addr: - Get MAC address for stand alone SiS900 model
937,8 → 937,8
call sys_msg_board_str
end if
;******** check to see if we have sane EEPROM *******
mov eax, SIS900_EEPROMSignature ;Base Eeprom Signature
call sis900_read_eeprom ;try to read 16 bits
mov eax, SIS900_EEPROMSignature ;Base Eeprom Signature
call sis900_read_eeprom ;try to read 16 bits
cmp ax, 0xffff
je SIS900_Bad_Eeprom
cmp ax, 0
945,17 → 945,17
je SIS900_Bad_Eeprom
;**************Read MacID**************
; zero based so 3-16 bit reads will take place
mov ecx, 2
mov ecx, 2
SIS900_mac_read_loop:
mov eax, SIS900_EEPROMMACAddr ;Base Mac Address
add eax, ecx ;Current Mac Byte Offset
mov eax, SIS900_EEPROMMACAddr ;Base Mac Address
add eax, ecx ;Current Mac Byte Offset
push ecx
call sis900_read_eeprom ;try to read 16 bits
pop ecx
mov word [ebx+device.mac+ecx*2], ax ;save 16 bits to the MAC ID storage
dec ecx ;one less word to read
jns SIS900_mac_read_loop ;if more read more
mov eax, 1 ;return non-zero indicating success
call sis900_read_eeprom ;try to read 16 bits
pop ecx
mov word [ebx+device.mac+ecx*2], ax ;save 16 bits to the MAC ID storage
dec ecx ;one less word to read
jns SIS900_mac_read_loop ;if more read more
mov eax, 1 ;return non-zero indicating success
;*******Debug Print MAC ID to debug window**********************
if defined SIS900_DEBUG
mov esi,SIS900_Debug_Str_GetMac_Address
986,10 → 986,10
push ebp
mov ebp,[ebx+device.io_addr]
lea edx,[ebp+SIS900_rfcr]
in eax,dx
in eax,dx
mov edi,eax ; EDI=rfcrSave
lea edx,[ebp+SIS900_cr]
or eax,SIS900_RELOAD
or eax,SIS900_RELOAD
out dx,eax
xor eax,eax
out dx,eax
1007,7 → 1007,7
shl eax,SIS900_RFADDR_shift
out dx,eax
lea edx,[ebp+SIS900_rfdr]
in eax,dx
in eax,dx
mov [esi],ax
add esi,2
inc ecx
1046,72 → 1046,72
push ecx
push ebx
push ebp
mov ebp,[ebx+device.io_addr]
mov ebx, eax ;location of Mac byte to read
or ebx, SIS900_EEread ;
lea edx,[ebp+SIS900_mear] ; Eeprom access register
xor eax, eax ; start send
out dx,eax
mov ebp,[ebx+device.io_addr]
mov ebx, eax ;location of Mac byte to read
or ebx, SIS900_EEread ;
lea edx,[ebp+SIS900_mear] ; Eeprom access register
xor eax, eax ; start send
out dx,eax
call SIS900_Eeprom_Delay_1
mov eax, SIS900_EECLK
out dx, eax
mov eax, SIS900_EECLK
out dx, eax
call SIS900_Eeprom_Delay_1
;************ Shift the read command (9) bits out. *********
mov cl, 8 ;
mov cl, 8 ;
sis900_read_eeprom_Send:
mov eax, 1
shl eax, cl
and eax, ebx
mov eax, 1
shl eax, cl
and eax, ebx
jz SIS900_Read_Eeprom_8
mov eax, 9
jmp SIS900_Read_Eeprom_9
mov eax, 9
jmp SIS900_Read_Eeprom_9
SIS900_Read_Eeprom_8:
mov eax, 8
mov eax, 8
SIS900_Read_Eeprom_9:
out dx, eax
out dx, eax
call SIS900_Eeprom_Delay_1
or eax, SIS900_EECLK
out dx, eax
or eax, SIS900_EECLK
out dx, eax
call SIS900_Eeprom_Delay_1
cmp cl, 0
je sis900_read_eeprom_Send_Done
dec cl
jmp sis900_read_eeprom_Send
cmp cl, 0
je sis900_read_eeprom_Send_Done
dec cl
jmp sis900_read_eeprom_Send
;*********************
sis900_read_eeprom_Send_Done:
mov eax, SIS900_EECS ;
out dx, eax
mov eax, SIS900_EECS ;
out dx, eax
call SIS900_Eeprom_Delay_1
;********** Read 16-bits of data in ***************
mov cx, 16 ;16 bits to read
mov cx, 16 ;16 bits to read
sis900_read_eeprom_Send2:
mov eax, SIS900_EECS
out dx, eax
call SIS900_Eeprom_Delay_1
or eax, SIS900_EECLK
or eax, SIS900_EECLK
out dx, eax
call SIS900_Eeprom_Delay_1
in eax, dx
in eax, dx
shl ebx, 1
and eax, SIS900_EEDO
jz SIS900_Read_Eeprom_0
or ebx, 1
jz SIS900_Read_Eeprom_0
or ebx, 1
SIS900_Read_Eeprom_0:
dec cx
jnz sis900_read_eeprom_Send2
dec cx
jnz sis900_read_eeprom_Send2
;************** Terminate the EEPROM access. **************
xor eax, eax
out dx, eax
xor eax, eax
out dx, eax
call SIS900_Eeprom_Delay_1
mov eax, SIS900_EECLK
out dx, eax
mov eax, ebx
and eax, 0x0000ffff ;return only 16 bits
pop ebp
pop ebx
pop ecx
pop edx
pop esi
mov eax, SIS900_EECLK
out dx, eax
mov eax, ebx
and eax, 0x0000ffff ;return only 16 bits
pop ebp
pop ebx
pop ecx
pop edx
pop esi
ret
;***************************************************************************
; Function
1157,7 → 1157,7
mov ebx, [esi]
mov edx, [ebx+device.io_addr]
add edx, SIS900_isr
in eax, dx ; note that this clears all interrupts
in eax, dx ; note that this clears all interrupts
test al, SIS900_RxOK
jnz .got_it
loop .nextdevice
1165,9 → 1165,9
ret
.got_it:
;**************Get Status **************
movzx eax, [ebx+device.cur_rx] ;find current discriptor
imul eax, 12 ;
mov ecx, [ebx+device.rxd+eax+4] ; get receive status
movzx eax, [ebx+device.cur_rx] ;find current discriptor
imul eax, 12 ;
mov ecx, [ebx+device.rxd+eax+4] ; get receive status
;**************Check Status **************
;Check RX_Status to see if packet is waiting
test ecx, 0x80000000
1175,74 → 1175,74
ret
;**********There is a packet waiting check it for errors**************
SIS900_poll_IS_packet:
test ecx, 0x67C0000 ;see if there are any errors
test ecx, 0x67C0000 ;see if there are any errors
jnz SIS900_Poll_Error_Status
;**************Check size of packet*************
and ecx, SIS900_DSIZE ;get packet size minus CRC
cmp ecx, SIS900_CRC_SIZE
and ecx, SIS900_DSIZE ;get packet size minus CRC
cmp ecx, SIS900_CRC_SIZE
;make sure packet contains data
jle SIS900_Poll_Error_Size
jle SIS900_Poll_Error_Size
;*******Copy Good Packet to receive buffer******
sub ecx, SIS900_CRC_SIZE ;dont want crc
sub ecx, SIS900_CRC_SIZE ;dont want crc
; update statistics
inc dword [ebx+device.packets_rx]
add dword [ebx+device.bytes_rx], ecx
adc dword [ebx+device.bytes_rx+4], 0
inc dword [ebx+device.packets_rx]
add dword [ebx+device.bytes_rx], ecx
adc dword [ebx+device.bytes_rx+4], 0
push ecx
stdcall KernelAlloc, ecx
pop ecx
pop ecx
test eax, eax
jz int_handler.nothing
jz int_handler.nothing
push ebx
push .return ; return address for EthReceiver
;**********Continue copying packet****************
push ecx eax ; save buffer pointer and size for EthReceiver
mov edi, eax
mov edi, eax
movzx esi, byte [ebx+device.cur_rx]
imul esi, RX_BUFF_SZ
lea esi, [esi+ebx+0x1000+NUM_TX_DESC*TX_BUFF_SZ]
lea esi, [esi+ebx+0x1000+NUM_TX_DESC*TX_BUFF_SZ]
; first copy dword-wise, divide size by 4
shr ecx, 2
rep movsd ; copy the dwords
mov ecx, [esp+4]
and ecx, 3 ;
rep movsb
shr ecx, 2
rep movsd ; copy the dwords
mov ecx, [esp+4]
and ecx, 3 ;
rep movsb
;********Debug, tell user we have a good packet*************
if defined SIS900_DEBUG
mov esi, SIS900_Debug_Pull_Packet_good
mov esi, SIS900_Debug_Pull_Packet_good
call sys_msg_board_str
end if
jmp EthReceiver
jmp EthReceiver
.return:
pop ebx
jmp SIS900_Poll_Cnt
pop ebx
jmp SIS900_Poll_Cnt
;*************Error occured let user know through debug window***********
SIS900_Poll_Error_Status:
if defined SIS900_DEBUG
mov esi, SIS900_Debug_Pull_Bad_Packet_Status
call sys_msg_board_str
mov esi, SIS900_Debug_Pull_Bad_Packet_Status
call sys_msg_board_str
end if
jmp SIS900_Poll_Cnt
jmp SIS900_Poll_Cnt
SIS900_Poll_Error_Size:
if defined SIS900_DEBUG
mov esi, SIS900_Debug_Pull_Bad_Packet_Size
call sys_msg_board_str
mov esi, SIS900_Debug_Pull_Bad_Packet_Size
call sys_msg_board_str
end if
;*************Increment to next available descriptor**************
SIS900_Poll_Cnt:
;Reset status, allow ethernet card access to descriptor
movzx eax, [ebx+device.cur_rx]
lea eax, [eax*3]
mov ecx, RX_BUFF_SZ
mov [ebx+device.rxd+eax*4+4], ecx ;
inc [ebx+device.cur_rx] ;get next descriptor
and [ebx+device.cur_rx],NUM_RX_DESC-1 ;only 4 descriptors 0-3
lea eax, [eax*3]
mov ecx, RX_BUFF_SZ
mov [ebx+device.rxd+eax*4+4], ecx ;
inc [ebx+device.cur_rx] ;get next descriptor
and [ebx+device.cur_rx],NUM_RX_DESC-1 ;only 4 descriptors 0-3
;******Enable Receiver************
mov edx, [ebx+device.io_addr]
add edx, SIS900_cr ; Command Register offset
in eax, dx ; Get current Command Register
or eax, SIS900_RxENA ;Enable Receive
out dx, eax
mov edx, [ebx+device.io_addr]
add edx, SIS900_cr ; Command Register offset
in eax, dx ; Get current Command Register
or eax, SIS900_RxENA ;Enable Receive
out dx, eax
ret
;***************************************************************************
; Function
1249,8 → 1249,8
; transmit
; Description
; Transmits a packet of data via the ethernet card
; buffer pointer in [esp]
; size of buffer in [esp+4]
; buffer pointer in [esp+4]
; size of buffer in [esp+8]
; pointer to device structure in ebx
;
; only one transmit descriptor is used
1263,39 → 1263,39
str1 db 'Transmitting packet:',13,10,0
str2 db ' ',0
transmit:
cmp dword [esp+4], MAX_ETH_FRAME_SIZE
jg transmit_finish
cmp dword [esp+4], 60
jl transmit_finish
cmp dword [esp+8], MAX_ETH_FRAME_SIZE
jg transmit_finish
cmp dword [esp+8], 60
jl transmit_finish
push ebp
mov ebp, [ebx+device.io_addr] ; Base Address
mov ebp, [ebx+device.io_addr] ; Base Address
;******** Stop the transmitter ********
lea edx,[ebp+SIS900_cr] ; Command Register offset
in eax, dx ; Get current Command Register
or eax, SIS900_TxDIS ; Disable Transmitter
out dx, eax
lea edx,[ebp+SIS900_cr] ; Command Register offset
in eax, dx ; Get current Command Register
or eax, SIS900_TxDIS ; Disable Transmitter
out dx, eax
;*******load Transmit Descriptor Register *******
lea edx,[ebp+SIS900_txdp]
mov eax, ebx
lea edx,[ebp+SIS900_txdp]
mov eax, ebx
call GetPgAddr
add eax, device.txd
out dx, eax
add eax, device.txd
out dx, eax
;******* copy packet to descriptor*******
mov esi, [esp+4]
lea edi, [ebx+0x1000]
mov ecx, [esp+8]
mov edx, ecx
shr ecx, 2
and edx, 3
rep movsd
mov ecx, edx
rep movsb
mov esi, [esp+8]
lea edi, [ebx+0x1000]
mov ecx, [esp+12]
mov edx, ecx
shr ecx, 2
and edx, 3
rep movsd
mov ecx, edx
rep movsb
;**************set length tag**************
mov ecx, [esp+8] ;restore packet size
and ecx, SIS900_DSIZE ;
inc [ebx+device.packets_tx]
add dword [ebx+device.bytes_tx], ecx
adc dword [ebx+device.bytes_tx+4], 0
mov ecx, [esp+12] ;restore packet size
and ecx, SIS900_DSIZE ;
inc [ebx+device.packets_tx]
add dword [ebx+device.bytes_tx], ecx
adc dword [ebx+device.bytes_tx+4], 0
;**************pad to minimum packet size **************not needed
;cmp ecx, SIS900_ETH_ZLEN
;jge SIS900_transmit_Size_Ok
1306,33 → 1306,31
;rep movsb
;pop ecx
SIS900_transmit_Size_Ok:
or ecx, 0x80000000 ;card owns descriptor
mov [ebx+device.txd+4], ecx
or ecx, 0x80000000 ;card owns descriptor
mov [ebx+device.txd+4], ecx
if defined SIS900_DEBUG
mov esi, SIS900_Debug_Transmit_Packet
mov esi, SIS900_Debug_Transmit_Packet
call sys_msg_board_str
end if
;***************restart the transmitter ********
lea edx,[ebp+SIS900_cr]
in eax, dx ; Get current Command Register
or eax, SIS900_TxENA ; Enable Transmitter
out dx, eax
lea edx,[ebp+SIS900_cr]
in eax, dx ; Get current Command Register
or eax, SIS900_TxENA ; Enable Transmitter
out dx, eax
;****make sure packet transmitted successfully****
; mov esi,10
; call delay_ms
mov eax, [ebx+device.txd+4]
and eax, 0x6200000
jz SIS900_transmit_OK
mov eax, [ebx+device.txd+4]
and eax, 0x6200000
jz SIS900_transmit_OK
;**************Tell user there was an error through debug window
if defined SIS900_DEBUG
mov esi, SIS900_Debug_Transmit_Packet_Err
mov esi, SIS900_Debug_Transmit_Packet_Err
call sys_msg_board_str
end if
SIS900_transmit_OK:
pop ebp
pop ebp
transmit_finish:
call KernelFree
add esp, 4
ret
 
;***************************************************************************
1352,7 → 1350,7
if defined SIS900_DEBUG
 
SIS900_Char_String db '0','1','2','3','4','5','6','7','8','9'
db 'A','B','C','D','E','F'
db 'A','B','C','D','E','F'
Mac_str_build: times 20 db 0
Create_Mac_String:
pusha
1374,12 → 1372,12
mov [Mac_str_build+2+ecx*3], bl
inc ecx
jmp Create_Mac_String_loop
Create_Mac_String_done: ;Insert CR and Zero Terminate
Create_Mac_String_done: ;Insert CR and Zero Terminate
mov [Mac_str_build+2+ecx*3],byte 13
mov [Mac_str_build+3+ecx*3],byte 10
mov [Mac_str_build+4+ecx*3],byte 0
mov esi, Mac_str_build
call sys_msg_board_str ;Print String to message board
call sys_msg_board_str ;Print String to message board
popa
ret
end if
1391,13 → 1389,13
;*******Get current setting************************
stdcall PciRead16, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x04
;******see if its already set as bus master********
mov cx, ax
and cx,5
cmp cx,5
je SIS900_adjust_pci_device_Latency
mov cx, ax
and cx,5
cmp cx,5
je SIS900_adjust_pci_device_Latency
;******Make card a bus master*******
mov cx, ax ;value to write
or cx,5
mov cx, ax ;value to write
or cx,5
stdcall PciWrite16, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x04, ecx
;******Check latency setting***********
SIS900_adjust_pci_device_Latency:
1404,8 → 1402,8
;*******Get current latency setting************************
stdcall PciRead8, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x0D
;******see if its aat least 64 clocks********
cmp al,64
jge SIS900_adjust_pci_device_Done
cmp al,64
jge SIS900_adjust_pci_device_Done
;******Set latency to 32 clocks*******
stdcall PciWrite8, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x0D, 64
;******Check latency setting***********
1436,5 → 1434,5
 
section '.data' data readable writable align 16 ; place all uninitialized data place here
 
DEV_LIST rd MAX_DEVICES ; This list contains all pointers to device structures the driver is handling
DEV_LIST rd MAX_DEVICES ; This list contains all pointers to device structures the driver is handling
 
/kernel/branches/net/network/IPv4.inc
123,7 → 123,6
 
; save checksum, and clear it in original packet
mov di , [edx + IPv4_Packet.HeaderChecksum]
DEBUGF 1,"checksum: %x\n",di
mov word [edx + IPv4_Packet.HeaderChecksum], 0
 
; Re-calculate checksum
140,6 → 139,8
pop ebx edx
jne .dump ; if checksum isn't valid then dump packet
 
DEBUGF 1,"IPv4 Checksum is correct\n",di
 
mov eax, [edx + IPv4_Packet.DestinationAddress]
mov edi, BROADCAST
mov ecx, MAX_IP+1
157,7 → 158,7
.ip_ok:
call ETH_struc2dev ; TODO: make this work on other protocols too!
inc [IP_PACKETS_RX+4*edi]
DEBUGF 1,"IP_Handler - packet from %u.%u.%u.%u\n",\
DEBUGF 1,"packet comes from %u.%u.%u.%u\n",\
[edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1
 
mov al , [edx + IPv4_Packet.VersionAndIHL]
189,10 → 190,8
add eax, edx
push eax
mov al , [edx + IPv4_Packet.Protocol]
;----------------------- experimental
mov esi, [edx + IPv4_Packet.SourceAddress]
mov edi, [edx + IPv4_Packet.DestinationAddress]
;-----------------------
pop edx ; Offset to data (tcp/udp/icmp/.. Packet)
 
cmp al , IP_PROTO_TCP
204,7 → 203,7
cmp al , IP_PROTO_ICMP
je ICMP_handler
 
DEBUGF 1,"IP_Handler - unknown protocol:%u\n",al
DEBUGF 1,"unknown protocol: %u\n",al
 
.dump:
DEBUGF 1,"IP_Handler - done\n"
402,10 → 401,8
add eax, edx
push eax
mov al , [edx + IPv4_Packet.Protocol]
;----------------------- experimental
mov esi, [edx + IPv4_Packet.SourceAddress]
mov edi, [edx + IPv4_Packet.DestinationAddress]
;-----------------------
pop edx ; Offset to data (tcp/udp/icmp/.. Packet)
 
cmp al , IP_PROTO_TCP
/kernel/branches/net/network/ethernet.inc
327,28 → 327,18
 
get_from_queue ETH_OUT_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .gohome
 
push ETH_send_queued
push ETH_send_queued ; this will cause the procedure to check for more packets
; when a single packet is handled
 
lodsd
mov ebx, eax
mov ebx, [esi]
pushd [esi + 8]
pushd [esi + 4]
 
sub esp, 8
mov edi, esp
movsd
movsd
 
DEBUGF 1,"dequeued packet for device %x\n", ebx
 
call ETH_struc2dev ; convert struct ptr to device num (this way we know if driver is still mounted)
cmp edi, -1
je .fail
 
jmp [ebx+ETH_DEVICE.transmit] ; we will return to get_from_queue macro after transmitting packet
 
.fail:
call [ebx+ETH_DEVICE.transmit] ; we will return to get_from_queue macro after transmitting packet
call kernel_free
add esp, 4 ; pop (balance stack)
DEBUGF 1,"ETH_Sender - fail\n"
 
.gohome:
ret
/kernel/branches/net/network/queue.inc
42,7 → 42,7
.retries dd ?
.owner dd ?
.sendproc dd ?
.ack_num dd ?
.seq_num dd ?
.size:
ends
 
/kernel/branches/net/network/socket.inc
43,12 → 43,15
.RemotePort dw ? ; In INET byte order
 
.backlog dw ? ; Backlog
.OrigRemoteIP dd ? ; original remote IP address (used to reset to LISTEN state)
.OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state)
.TCBState dd ? ; TCB state
.TCBTimer dd ? ; TCB timer (seconds)
.ISS dd ? ; initial send sequence
.IRS dd ? ; initial receive sequence
; .OrigRemoteIP dd ? ; original remote IP address (used to reset to LISTEN state)
; .OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state)
.wndsizeTimer dd ? ; window size timer
 
; Transmission control block
.state dd ? ; TCB state
.timer dd ? ; TCB timer (seconds)
.ISS dd ? ; initial send sequence number
.IRS dd ? ; initial receive sequence number
.SND_UNA dd ? ; sequence number of unack'ed sent Packets
.SND_NXT dd ? ; next send sequence number to use
.SND_WND dd ? ; send window
56,7 → 59,6
.RCV_WND dd ? ; receive window
.SEG_LEN dd ? ; segment length
.SEG_WND dd ? ; segment window
.wndsizeTimer dd ? ; window size timer
 
.flags db ? ; packet flags
 
121,36 → 123,33
ret
 
 
;-----------------------------------------------------------------------------
;-----------------------------------------------
;
; Socket API (function 74)
;
;-----------------------------------------------------------------------------
;-----------------------------------------------
 
align 4
sys_socket:
and ebx, 0x000000FF ; should i remove this line ?
cmp bl , 7 ; highest possible number
jg s_error
lea ebx, [.table + 4*ebx]
jmp dword [ebx]
 
test bl, bl
jz socket_open ; 0
dec bl
jz socket_close ; 1
dec bl
jz socket_bind ; 2
dec bl
jz socket_listen ; 3
dec bl
jz socket_connect ; 4
dec bl
jz socket_accept ; 5
dec bl
jz socket_send ; 6
dec bl
jz socket_recv ; 7
dec bl
; jz socket_get_opt ; 8
dec bl
; jz socket_set_opt ; 9
.table:
dd socket_open ; 0
dd socket_close ; 1
dd socket_bind ; 2
dd socket_listen ; 3
dd socket_connect ; 4
dd socket_accept ; 5
dd socket_send ; 6
dd socket_recv ; 7
; dd socket_get_opt ; 8
; dd socket_set_opt ; 9
 
 
s_error:
mov dword [esp+32],-1
 
157,8 → 156,6
ret
 
 
 
 
;-----------------------------------------------
;
; SOCKET_open
186,6 → 183,8
stdcall net_socket_addr_to_num, eax
DEBUGF 1,", socketnumber: %u\n", eax
 
; TODO: if it is txcp socket, set state to TCB_CLOSED
 
mov [esp+32], eax
 
ret
231,7 → 230,6
 
; TODO: write code here
 
 
mov dword [esp+32],0
ret
 
295,7 → 293,7
cmp eax, -1
jz s_error
 
cmp esi, 2
cmp esi, 8
jl s_error
 
cmp word [edx], AF_INET4
305,21 → 303,15
 
.af_inet4:
 
cmp esi, 8
jl s_error
 
cmp [eax + SOCKET_head.Type], IP_PROTO_UDP
je .udp
 
cmp [eax + SOCKET_head.Type], IP_PROTO_ICMP
je .icmp
 
cmp [eax + SOCKET_head.Type], IP_PROTO_TCP
je .tcp
 
jmp s_error
 
.udp:
.udp:
 
mov bx , word [edx + 2]
mov word [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], bx
332,92 → 324,49
mov dword [esp+32],0
ret
 
.icmp:
 
; TODO: write code here
.tcp:
; TODO: set sequence number to random value
 
ret
 
; fill in remote port and IP
 
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 0 ; Reset the window timer.
; TODO: figure out WTF this is
mov bx , word [edx + 2]
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort], bx
DEBUGF 1,"remote port: %x ",bx
 
.tcp:
mov ebx, dword [edx + 4]
mov [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], ebx
 
;local sockAddr dd ?
; check if local port and IP is ok
 
; cmp esi, SOCKET_PASSIVE
; jne .skip_port_check
;
; push ebx
; mov eax, ebx
; xchg al, ah
; mov ebx, net_sockets
;
; .next_socket:
; mov ebx, [ebx + SOCKET.NextPtr]
; or ebx, ebx
; jz .last_socket
; cmp [ebx + SOCKET.TCBState], TCB_LISTEN
; jne .next_socket
; cmp [ebx + SOCKET.LocalPort], ax
; jne .next_socket
;
; xchg al, ah
; DEBUGF 1, "K : error: port %u is listened by 0x%x\n", ax, ebx
; pop ebx
; jmp .error
;
; .last_socket:
; pop ebx
;
; .skip_port_check:
cmp [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP], 0
jne @f
push [IP_LIST] ; device zero = default
pop [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP]
@@:
 
; mov [eax + SOCKET.wndsizeTimer], 0 ; Reset the window timer.
;
; xchg bh, bl
; mov [eax + SOCKET.LocalPort], bx
; xchg ch, cl
; mov [eax + SOCKET.RemotePort], cx
; mov [eax + SOCKET.OrigRemotePort], cx
; mov ebx, [IP_LIST]
; mov [eax + SOCKET.LocalIP], ebx
; mov [eax + SOCKET.RemoteIP], edx
; mov [eax + SOCKET.OrigRemoteIP], edx
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], 0
jne @f
 
; mov ebx, TCB_LISTEN
; cmp esi, SOCKET_PASSIVE
; je @f
; mov ebx, TCB_SYN_SENT
; @@: mov [eax + SOCKET.TCBState], ebx ; Indicate the state of the TCB
mov ecx, [eax + SOCKET_head.Type]
call socket_find_port
test bx, bx
jz s_error
 
; cmp ebx, TCB_LISTEN
; je .exit
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], bx
@@:
 
; Now, if we are in active mode, then we have to send a SYN to the specified remote port
; mov eax, EMPTY_QUEUE
; call dequeue
; cmp ax, NO_BUFFER
; je .exit
 
; push eax
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_SENT
; now say hello to the remote tcp socket
 
; mov bl, TH_SYN
; xor ecx, ecx
; stdcall build_tcp_Packet, [sockAddr]
mov bl, TH_SYN
call TCP_send_ack
 
; mov eax, NET1OUT_QUEUE
; mov edx, [IP_LIST]
; mov ecx, [sockAddr]
; cmp edx, [ecx + SOCKET.RemoteIP]
; jne .not_local
; mov eax, IPIN_QUEUE
 
; .not_local:
; Send it.
; pop ebx
; call queue
 
.exit:
xor eax, eax
mov dword [esp+32],0
ret
 
 
442,6 → 391,12
cmp eax, -1
jz s_error
 
cmp word [eax + SOCKET_head.Domain], AF_INET4
jne s_error
 
cmp [eax + SOCKET_head.Type], IP_PROTO_TCP
jne s_error
 
cmp edx, MAX_backlog
jl .ok
mov dx , 20
448,9 → 403,8
.ok:
 
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog], dx
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LISTEN
 
; TODO: insert code for active connections like TCP
 
mov dword [esp+32], 0
ret
 
569,98 → 523,44
ret
 
.tcp:
; first, remove all resend entries for this socket
 
if 1 = 0
;local sockAddr dd ?
 
; DEBUGF 1, "K : socket_close_tcp (0x%x)\n", ebx
; first, remove any resend entries
pusha
 
mov esi, resendQ
mov ecx, 0
 
.next_resendq:
cmp ecx, NUMRESENDENTRIES
je .last_resendq ; None left
cmp [esi + 4], ebx
je @f ; found one
inc ecx
add esi, 8
jmp .next_resendq
 
@@: mov dword[esi + 4], 0
inc ecx
add esi, 8
jmp .next_resendq
 
.last_resendq:
popa
 
mov ebx, eax
; mov [sockAddr], eax
 
cmp [eax + SOCKET.TCBState], TCB_LISTEN
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LISTEN
je .destroy_tcb
cmp [eax + SOCKET.TCBState], TCB_SYN_SENT
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_SENT
je .destroy_tcb
 
; Now construct the response, and queue for sending by IP
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .error
; Now construct the response, and queue for sending by IP
 
push eax
 
mov bl, TH_FIN
xor ecx, ecx
xor esi, esi
stdcall build_tcp_Packet, [sockAddr]
call TCP_send_ack
 
mov ebx, [sockAddr]
; increament SND.NXT in socket
lea esi, [ebx + SOCKET.SND_NXT]
call inc_inet_esi
lea esi, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]
inc_INET esi
 
; Get the socket state
mov eax, [ebx + SOCKET.TCBState]
cmp eax, TCB_SYN_RECEIVED
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED
je .fin_wait_1
cmp eax, TCB_ESTABLISHED
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_ESTABLISHED
je .fin_wait_1
 
; assume CLOSE WAIT
; Send a fin, then enter last-ack state
mov [ebx + SOCKET.TCBState], TCB_LAST_ACK
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LAST_ACK
jmp .send
 
.fin_wait_1:
; Send a fin, then enter finwait2 state
mov [ebx + SOCKET.TCBState], TCB_FIN_WAIT_1
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_FIN_WAIT_1
 
.send:
mov eax, NET1OUT_QUEUE
mov edx, [IP_LIST]
; mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
 
.not_local:
; Send it.
pop ebx
call queue
jmp .exit
;;;;;
 
 
.destroy_tcb:
 
stdcall net_socket_free, eax
 
end if
 
.exit:
mov dword [esp+32],0
ret
 
735,6 → 635,7
; OUT: -1 on error
;
;-----------------------------------------------
 
align 4
socket_send:
 
749,7 → 650,6
 
jmp s_error
 
;---------
.af_inet4:
DEBUGF 1,"Socket type:%u\n", [eax + SOCKET_head.Type]:4
 
763,7 → 663,6
je .raw
 
jmp s_error
;--------
 
.udp:
 
792,10 → 691,27
 
.tcp:
 
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort],0
jne @f
 
push esi
mov ecx, [eax + SOCKET_head.Type]
call socket_find_port
test bx, bx
pop esi
je s_error
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], bx
 
@@:
 
mov ecx, esi
mov esi, edx
 
call TCP_socket_send
 
mov [esp+32], eax
ret
 
;--------
.raw:
cmp [eax + SOCKET_head.Protocol], IP_PROTO_IP
je .raw_ip
804,11 → 720,12
je .raw_icmp
 
jmp s_error
;--------
 
 
.raw_ip:
 
;;;;;;
 
mov [esp+32], eax
ret
 
/kernel/branches/net/network/stack.inc
32,7 → 32,7
ETHER equ 1337
ETHER_ARP equ 0x0608
 
;AF_UNSPEC equ 0
AF_UNSPEC equ 0
AF_UNIX equ 1
AF_INET4 equ 2
;AF_AX25 equ 3
55,10 → 55,47
SOCK_DGRAM = 2
SOCK_RAW = 3
 
; TCP opening modes
SOCKET_PASSIVE equ 0
SOCKET_ACTIVE equ 1
TCB_LISTEN equ 1
TCB_SYN_SENT equ 2
TCB_SYN_RECEIVED equ 3
TCB_ESTABLISHED equ 4
TCB_FIN_WAIT_1 equ 5
TCB_FIN_WAIT_2 equ 6
TCB_CLOSE_WAIT equ 7
TCB_CLOSING equ 8
TCB_LAST_ACK equ 9
TCB_TIMED_WAIT equ 10
TCB_CLOSED equ 11
 
TH_FIN equ 1 shl 0
TH_SYN equ 1 shl 1
TH_RST equ 1 shl 2
TH_PUSH equ 1 shl 3
TH_ACK equ 1 shl 4
TH_URG equ 1 shl 5
 
 
macro inc_INET reg {
 
inc byte [reg + 3]
adc byte [reg + 2], 0
adc byte [reg + 1], 0
adc byte [reg + 0], 0
 
}
 
 
macro add_INET reg {
 
rol ecx, 16
adc byte [reg + 3], ch
adc byte [reg + 2], cl
rol ecx, 16
adc byte [reg + 1], ch
adc byte [reg + 0], cl
 
}
 
include "queue.inc"
include "ARP.inc"
include "IPv4.inc"
90,7 → 127,7
call ICMP_init
call socket_init
 
mov al, 0x0 ; set up 1s timer
mov al, 0 ; set up 1s timer
out 0x70, al
in al, 0x71
mov [last_1sTick], al
116,7 → 153,7
cmp [ETH_RUNNING], 0
je .exit
 
; Test for 10ms tick
; Test for 1/100 s (10ms) tick
mov eax, [timer_ticks]
cmp eax, [last_1hsTick]
je .exit
129,8 → 166,8
 
.sec_tick:
 
; Test for 1 second event
mov al, 0x0 ;second
; Test for 1 second tick
mov al, 0
out 0x70, al
in al, 0x71
cmp al, [last_1sTick]
336,7 → 373,7
je UDP_API
 
cmp ax , IP_PROTO_TCP
; je TCP_API
je TCP_API
 
cmp ax , ETHER_ARP
je ARP_API
/kernel/branches/net/network/tcp.inc
17,30 → 17,9
 
$Revision$
 
 
TCB_LISTEN equ 1
TCB_SYN_SENT equ 2
TCB_SYN_RECEIVED equ 3
TCB_ESTABLISHED equ 4
TCB_FIN_WAIT_1 equ 5
TCB_FIN_WAIT_2 equ 6
TCB_CLOSE_WAIT equ 7
TCB_CLOSING equ 8
TCB_LAST_ACK equ 9
TCB_TIMED_WAIT equ 10
TCB_CLOSED equ 11
 
TH_FIN equ 1 shl 0
TH_SYN equ 1 shl 1
TH_RST equ 1 shl 2
TH_PUSH equ 1 shl 3
TH_ACK equ 1 shl 4
TH_URG equ 1 shl 5
 
TWOMSL equ 10 ; # of secs to wait before closing socket
 
TCP_RETRIES equ 5 ; Number of times to resend a Packet
TCP_TIMEOUT equ 10 ; resend if not replied to in 1/100 s
TCP_PACKET_TTL equ 50 ; resend if not replied to in 1/100 s
TCP_SOCKET_TTL equ 10 ; # of secs to wait before closing socket
 
TCP_QUEUE_SIZE equ 16
 
66,7 → 45,7
TCP_PACKETS_RX rd MAX_IP
 
TCP_IN_QUEUE rd (tcp_in_queue_entry.size*TCP_QUEUE_SIZE+queue.data)/4
TCP_OUT_QUEUE dd ?
TCP_OUT_QUEUE dd ?
rd (tcp_out_queue_entry.size*TCP_QUEUE_SIZE)/4
endg
 
73,7 → 52,7
align 4
iglobal
 
TCBStateHandler:
stateHandler:
 
dd stateTCB_LISTEN
dd stateTCB_SYN_SENT
90,30 → 69,6
endg
 
 
macro inc_INET reg {
 
inc byte [reg + 0]
adc byte [reg + 1], 0
adc byte [reg + 2], 0
adc byte [reg + 3], 0
 
}
 
 
macro add_INET reg {
 
rol ecx, 16
adc byte [reg + 0], ch
adc byte [reg + 1], cl
rol ecx, 16
adc byte [reg + 2], ch
adc byte [reg + 3], cl
 
}
 
 
 
 
;-----------------------------------------------------------------
;
; TCP_init
134,8 → 89,13
rep stosd
 
init_queue TCP_IN_QUEUE
init_queue TCP_OUT_QUEUE
 
; tcp_out_queue is a special type of queue
xor eax, eax
mov esi, TCP_OUT_QUEUE
mov ecx, TCP_QUEUE_SIZE*tcp_out_queue_entry/4+1
rep stosd
 
ret
 
 
165,9 → 125,9
cmp [ebx + SOCKET_head.Type], IP_PROTO_TCP
jne .next_socket
 
; DEBUGF 1, "K : %x-%x: %x-%x-%x-%u\n", [ebx + SOCKET.PID]:2, [ebx + SOCKET.Number]:2, [ebx + SOCKET.LocalPort]:4, [ebx + SOCKET.RemoteIP], [ebx + SOCKET.RemotePort]:4, [ebx + SOCKET.TCBState]
; DEBUGF 1, "K : %x-%x: %x-%x-%x-%u\n", [ebx + SOCKET.PID]:2, [ebx + SOCKET.Number]:2, [ebx + SOCKET.LocalPort]:4, [ebx + SOCKET.RemoteIP], [ebx + SOCKET.RemotePort]:4, [ebx + SOCKET.state]
 
cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBTimer], 0
cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.timer], 0
jne .decrement_tcb
cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 0
jne .decrement_wnd
175,10 → 135,10
 
.decrement_tcb:
; decrement it, delete socket if TCB timer = 0 & socket in timewait state
dec [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBTimer]
dec [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.timer]
jnz .next_socket
 
cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBState], TCB_TIMED_WAIT
cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT
jne .next_socket
 
push [ebx + SOCKET_head.PrevPtr]
231,30 → 191,33
dec [esi + tcp_out_queue_entry.ttl]
jz .send_it
.find_next:
add esi, tcp_out_queue_entry.size
dec eax
jz .exit
jmp .loop
test ecx, ecx
jnz .loop
ret
 
.send_it:
push eax ecx esi
 
mov ebx, [esi + tcp_out_queue_entry.owner]
push [esi + tcp_out_queue_entry.data_size]
push [esi + tcp_out_queue_entry.data_ptr]
mov ebx, [esi + tcp_out_queue_entry.owner]
 
DEBUGF 1,"Now sending TCP packet %x, size: %u, owner: %x, sendproc %x\n", [esp], [esp+4], ebx, [esi + tcp_out_queue_entry.sendproc]
call [esi + tcp_out_queue_entry.sendproc]
 
add esp, 8
pop esi ecx eax
 
dec [esi + tcp_out_queue_entry.retries]
jz .remove_it
mov [esi + tcp_out_queue_entry.ttl], TCP_TIMEOUT
 
mov [esi + tcp_out_queue_entry.ttl], TCP_PACKET_TTL
jmp .find_next
 
.remove_it:
push [esi + tcp_out_queue_entry.data_ptr]
mov [esi + tcp_out_queue_entry.data_ptr], 0
dec [TCP_OUT_QUEUE]
call kernel_free
jmp .find_next
 
278,6 → 241,8
align 4
TCP_add_to_queue:
 
DEBUGF 1,"Adding packet to TCP queue, buffer: %x, size: %u, driver: %x, acknum: %x\n", [esp], [esp+4], ebx, edx
 
cmp [TCP_OUT_QUEUE], TCP_QUEUE_SIZE
jge .full
 
291,6 → 256,9
loop .loop
 
.full: ; silently discard the packet
 
DEBUGF 1,"TCP queue is full!\n"
 
call kernel_free
add esp, 4
 
304,9 → 272,13
mov [eax + tcp_out_queue_entry.retries], TCP_RETRIES
mov [eax + tcp_out_queue_entry.owner], ebx
mov [eax + tcp_out_queue_entry.sendproc], esi
mov [eax + tcp_out_queue_entry.ack_num], edx
mov [eax + tcp_out_queue_entry.seq_num], edx
 
inc [TCP_OUT_QUEUE]
 
sub eax, TCP_OUT_QUEUE+4
DEBUGF 1,"Added to queue in pos %u\n", eax
 
ret
 
 
332,6 → 304,8
 
DEBUGF 1,"TCP_Handler\n"
 
; TODO: validate checksum
 
; IP Packet TCP Destination Port = local Port
; IP Packet SA = Remote IP OR = 0
; IP Packet TCP Source Port = remote Port OR = 0
358,10 → 332,12
cmp [edx + TCP_Packet.SourcePort] , ax
je .change_state
test ax, ax
jne .socket_loop
jnz .socket_loop
 
.change_state:
 
DEBUGF 1,"Found valid socket for packet\n"
 
push ebx
lea ebx, [ebx + SOCKET_head.lock]
call wait_mutex
373,29 → 349,37
; edx is pointer to tcp packet
 
; as a Packet has been received, update the TCB timer
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBTimer], TWOMSL
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.timer], TCP_SOCKET_TTL
 
; If the received Packet has an ACK bit set, remove any Packets in the resend queue that this received Packet acknowledges
test [edx + TCP_Packet.Flags], TH_ACK
jz .call_handler ; No ACK, so no data yet
 
mov eax, [edx + TCP_Packet.SequenceNumber] ; Calculate sequencenumber in eax
bswap eax ;
add eax, ecx ;
; mov eax, [edx + TCP_Packet.SequenceNumber] ; Calculate sequencenumber in eax
; bswap eax ;
; add eax, ecx ;
 
mov eax, [edx + TCP_Packet.AckNumber]
;---------
 
cmp [TCP_OUT_QUEUE], 0
je .call_handler
push ecx
 
push ecx
DEBUGF 1,"Removing all queued packets with smaller ACK\n"
 
mov ecx, TCP_QUEUE_SIZE
mov esi, TCP_OUT_QUEUE+4
 
.loop:
cmp [esi + tcp_out_queue_entry.data_ptr], 0
jne .maybe_next
cmp [esi + tcp_out_queue_entry.ack_num], eax
je .maybe_next
cmp [esi + tcp_out_queue_entry.seq_num], eax
jg .maybe_next
; TODO: check if the packets belong to the same tcp connection !
 
DEBUGF 1,"Removing a queued packet\n"
 
push [esi + tcp_out_queue_entry.data_ptr]
mov [esi + tcp_out_queue_entry.data_ptr], 0
dec [TCP_OUT_QUEUE]
404,25 → 388,24
.maybe_next:
add esi, tcp_out_queue_entry.size
loop .loop
 
pop ecx
 
.call_handler:
; Call handler for given TCB state
mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBState]
mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state]
DEBUGF 1,"Socket state: %u\n", eax
 
cmp eax, TCB_LISTEN
jb .exit
jb .dump
cmp eax, TCB_CLOSED
ja .exit
ja .dump
 
dec eax
shl eax, 2
add eax, TCBStateHandler - 4
add eax, stateHandler
 
push .exit
jmp eax
call dword[eax]
 
.exit:
mov [ebx + SOCKET_head.lock], 0
 
.dump:
DEBUGF 1,"Dumping TCP packet\n"
call kernel_free
463,7 → 446,7
 
 
push ecx esi eax ; save some variables for later
add ecx, TCP_Packet.Data
add ecx, TCP_Packet.Options
call IPv4_create_packet
cmp edi, -1
je .fail
485,7 → 468,7
mov al, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.flags]
mov [edi + TCP_Packet.Flags], al
 
mov [edi + TCP_Packet.Window], 0x0005 ; 1280 bytes ;;; TODO: read RFC !
mov [edi + TCP_Packet.Window], 0x0005 ; 1280 bytes
mov [edi + TCP_Packet.UrgentPointer], 0
mov [edi + TCP_Packet.DataOffset], 0x50
mov [edi + TCP_Packet.Checksum], 0
493,7 → 476,7
; Copy the data
mov esi, [esp]
mov ecx, [esp+4]
add edi, TCP_Packet.Data
add edi, TCP_Packet.Options
 
shr ecx, 1
jnc .nb
519,12 → 502,12
 
; And now, send it!
DEBUGF 1,"Sending TCP Packet to device %x\n", ebx
mov esi, ETH_sender
lea esi, [ebx+ETH_DEVICE.transmit]
mov edx, [edi + TCP_Packet.AckNumber]
jmp TCP_add_to_queue
 
.fail:
add esp, 12+4
add esp, 12+12+4
ret
 
 
543,14 → 526,15
align 4
TCP_send_ack:
 
DEBUGF 1,"Creating TCP ACK\n"
DEBUGF 1,"Creating TCP ACK, socket: %x, flags: %x\n",eax, bl
 
mov di , IP_PROTO_TCP
mov cx , TCP_Packet.Data
mov ecx, TCP_Packet.Options
 
push bx eax
 
; Create an IPv4 Packet of the correct size
 
mov ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP]
mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP]
 
564,10 → 548,10
push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]
pop [edi + TCP_Packet.SequenceNumber]
 
push dword [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort]
push dword [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort] ; both ports at once
pop dword [edi + TCP_Packet.SourcePort]
 
push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]
push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
pop [edi + TCP_Packet.AckNumber]
 
pop cx
575,32 → 559,39
mov [edi + TCP_Packet.Window], 0x0005 ; 1280 bytes
mov [edi + TCP_Packet.UrgentPointer], 0
mov [edi + TCP_Packet.DataOffset], 0x50
mov [edi + TCP_Packet.Checksum], 0
 
push eax edx
push edx eax
 
push word TCP_Packet.Data shl 8
push IP_PROTO_TCP
push [esi + SOCKET_head.end + SOCKET_head.end + IPv4_SOCKET.RemoteIP]
push [esi + SOCKET_head.end + SOCKET_head.end + IPv4_SOCKET.LocalIP]
lea esi, [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]
inc_INET esi
 
; Now, calculate the checksum for pseudoheader
; Now, calculate the checksum
pushw TCP_Packet.Options shl 8
pushw IP_PROTO_TCP shl 8
pushd [edi-4] ; destination address
pushd [edi-8] ; source address
 
xor edx, edx
mov ecx, TCP_Packet.Options
mov esi, edi
call checksum_1
mov ecx, 12
mov esi, esp
call checksum_1
add esp, 12 ; remove the pseudoheader from stack
; Now create the final checksum and store it in TCP header
; and store it in TCP header
call checksum_2
mov [edi + TCP_Packet.Checksum], dx
 
; And now, send it!
; And now, send the packet!
DEBUGF 1,"Sending TCP Packet to device %x\n", ebx
mov esi, ETH_sender
mov edx, [edi + TCP_Packet.AckNumber]
mov esi, [ebx + ETH_DEVICE.transmit]
mov edx, [edi + TCP_Packet.SequenceNumber]
jmp TCP_add_to_queue
 
.fail:
add esp, 12+4
add esp, 2+4
ret
 
 
609,6 → 600,9
 
align 4
stateTCB_LISTEN:
 
DEBUGF 1,"TCBStateHandler: Listen\n"
 
; In this case, we are expecting a SYN Packet
; For now, if the Packet is a SYN, process it, and send a response
; If not, ignore it
631,11 → 625,13
mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.ISS]
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT], eax
 
mov [ebx + SOCKET_head.lock], 0
 
; Now construct the response
mov bl, TH_SYN + TH_ACK
call TCP_send_ack
 
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBState], TCB_SYN_RECEIVED
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED
 
; increment SND.NXT in socket
lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]
642,11 → 638,15
inc_INET esi
 
.exit:
mov [ebx + SOCKET_head.lock], 0
ret
 
 
align 4
stateTCB_SYN_SENT:
 
DEBUGF 1,"TCBStateHandler: Syn_Sent\n"
 
; We are awaiting an ACK to our SYN, with a SYM
; Look at control flags - expecting an ACK
 
658,28 → 658,31
test al, TH_SYN
jz .exit
 
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBState], TCB_SYN_RECEIVED
push TH_SYN + TH_ACK
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED
pushd TH_SYN + TH_ACK
jmp .send
 
.syn_ack:
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBState], TCB_ESTABLISHED
push TH_ACK
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_ESTABLISHED
pushd TH_ACK
 
.send:
; Store the recv.nxt field
mov eax, [edx + TCP_Packet.SequenceNumber]
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.IRS], eax
bswap eax
inc eax
bswap eax
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT], eax ; Update our recv.nxt field
mov [ebx + SOCKET_head.lock], 0
 
; Update our recv.nxt field
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT], eax
lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
inc_INET esi
 
; Send an ACK
mov eax, ebx
pop ebx
call TCP_send_ack
 
.exit:
mov [ebx + SOCKET_head.lock], 0
ret
 
 
686,6 → 689,9
 
align 4
stateTCB_SYN_RECEIVED:
 
DEBUGF 1,"TCBStateHandler: Syn_received\n"
 
; In this case, we are expecting an ACK Packet
; For now, if the Packet is an ACK, process it,
; If not, ignore it
693,12 → 699,12
test [edx + TCP_Packet.Flags], TH_RST
jz .check_ack
 
push [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.OrigRemotePort]
pop [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort]
push [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.OrigRemoteIP]
pop [ebx + SOCKET_head.end + IPv4_SOCKET.RemoteIP]
; push [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.OrigRemotePort]
; pop [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort]
; push [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.OrigRemoteIP]
; pop [ebx + SOCKET_head.end + IPv4_SOCKET.RemoteIP]
 
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBState], TCB_LISTEN
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LISTEN
jmp .exit
 
.check_ack:
706,9 → 712,10
test [edx + TCP_Packet.Flags], TH_ACK
jz .exit
 
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBState], TCB_ESTABLISHED
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_ESTABLISHED
 
.exit:
mov [ebx + SOCKET_head.lock], 0
ret
 
 
715,6 → 722,10
 
align 4
stateTCB_ESTABLISHED:
 
 
DEBUGF 1,"TCBStateHandler: Established\n"
 
; Here we are expecting data, or a request to close
; OR both...
 
724,6 → 735,7
 
; It was a fin or reset.
 
;;; TODO: write following code:
; Remove resend entries from the queue - I dont want to send any more data
; Send an ACK to that fin, and enter closewait state
 
732,6 → 744,8
test [edx + TCP_Packet.Flags], TH_ACK
jz .exit
 
DEBUGF 1,"Received ACK\n"
 
; First, look at the incoming window. If this is less than or equal to 1024,
; Set the socket window timer to 1. This will stop an additional Packets being queued.
; ** I may need to tweak this value, since I do not know how many Packets are already queued
752,7 → 766,7
; recv seq is in [sktAddr]+56, in inet format
; just do a comparision
mov ecx, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBState], TCB_CLOSE_WAIT
cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSE_WAIT
jne @f
mov ecx, eax
 
763,11 → 777,12
jnz .data
 
; If we had received a fin, we need to ACK it.
cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBState], TCB_CLOSE_WAIT
cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSE_WAIT
je .ack
jmp .exit
 
.data:
DEBUGF 1,"Got data!\n"
mov esi, [esp + 4]
sub edx, esi
mov edi, edx
774,10 → 789,14
call socket_internal_receiver
 
.ack:
mov [ebx + SOCKET_head.lock], 0
; Send an ACK
mov eax, ebx
mov bl, TH_ACK
call TCP_send_ack
.exit:
 
mov [ebx + SOCKET_head.lock], 0
ret
 
 
784,6 → 803,9
 
align 4
stateTCB_FIN_WAIT_1:
 
DEBUGF 1,"TCBStateHandler: Fin_wait_1\n"
 
; We can either receive an ACK of a fin, or a fin
mov al, [edx + TCP_Packet.Flags]
and al, TH_FIN + TH_ACK
792,21 → 814,25
jne @f
 
; It was an ACK
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBState], TCB_FIN_WAIT_2
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_FIN_WAIT_2
jmp .exit
 
@@: mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBState], TCB_CLOSING
@@: mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSING
cmp al, TH_FIN
je @f
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBState], TCB_TIMED_WAIT
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT
 
@@: lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
inc_INET esi
 
mov [ebx + SOCKET_head.lock], 0
; Send an ACK
mov eax, ebx
mov bl, TH_ACK
call TCP_send_ack
 
.exit:
mov [ebx + SOCKET_head.lock], 0
ret
 
 
813,20 → 839,27
 
align 4
stateTCB_FIN_WAIT_2:
 
DEBUGF 1,"TCBStateHandler: Fin_wait_2\n"
 
test [edx + TCP_Packet.Flags], TH_FIN
jz .exit
 
; Change state, as we have a fin
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBState], TCB_TIMED_WAIT
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT
 
lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
inc_INET esi
 
mov [ebx + SOCKET_head.lock], 0
 
; Send an ACK
mov eax, ebx
mov bl, TH_ACK
call TCP_send_ack
 
.exit:
mov [ebx + SOCKET_head.lock], 0
ret
 
 
833,8 → 866,12
 
align 4
stateTCB_CLOSE_WAIT:
 
DEBUGF 1,"TCBStateHandler: close_wait\n"
; Intentionally left empty
; socket_close_tcp handles this
 
mov [ebx + SOCKET_head.lock], 0
ret
 
 
841,22 → 878,32
 
align 4
stateTCB_CLOSING:
 
DEBUGF 1,"TCBStateHandler: closingn\n"
 
; We can either receive an ACK of a fin, or a fin
test [edx + TCP_Packet.Flags], TH_ACK
jz .exit
 
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBState], TCB_TIMED_WAIT
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT
 
.exit:
 
mov [ebx + SOCKET_head.lock], 0
ret
 
 
align 4
stateTCB_LAST_ACK:
 
DEBUGF 1,"TCBStateHandler: last_ackn\n"
 
; Look at control flags - expecting an ACK
test [edx + TCP_Packet.Flags], TH_ACK
jz .exit
 
mov [ebx + SOCKET_head.lock], 0
 
; delete the socket
stdcall net_socket_free, ebx
 
866,13 → 913,60
 
align 4
stateTCB_TIME_WAIT:
 
DEBUGF 1,"TCBStateHandler: time_wait\n"
 
mov [ebx + SOCKET_head.lock], 0
 
ret
 
 
align 4
stateTCB_CLOSED:
 
DEBUGF 1,"TCBStateHandler: closed\n"
 
mov [ebx + SOCKET_head.lock], 0
 
ret
 
 
 
;---------------------------------------------------------------------------
;
; TCP_API
;
; This function is called by system function 75
;
; IN: subfunction number in bl
; device number in bh
; ecx, edx, .. depends on subfunction
;
; OUT:
;
;---------------------------------------------------------------------------
 
align 4
TCP_API:
 
movzx eax, bh
shl eax, 2
 
test bl, bl
jz .packets_tx ; 0
dec bl
jz .packets_rx ; 1
 
.error:
mov eax, -1
ret
 
.packets_tx:
add eax, TCP_PACKETS_TX
mov eax, [eax]
ret
 
.packets_rx:
add eax, TCP_PACKETS_RX
mov eax, [eax]
ret
/kernel/branches/net/network/udp.inc
77,9 → 77,6
DEBUGF 1,"UDP_Handler\n"
; First validate, checksum:
 
DEBUGF 1,"Real UDP checksum: %x\n", [edx + UDP_Packet.Checksum]:4
mov [edx + UDP_Packet.Checksum], 0
 
pusha
 
rol cx, 8
89,10 → 86,12
push edi
push esi
 
mov di, [edx + UDP_Packet.Checksum]
mov [edx + UDP_Packet.Checksum], 0
 
mov esi, edx
xor edx, edx
call checksum_1
; Checksum for pseudoheader
mov ecx, 12
mov esi, esp
call checksum_1
99,10 → 98,12
add esp, 12
call checksum_2
 
cmp di, dx
popa
jne .dump
 
DEBUGF 1,"UDP Checksum is correct\n"
 
 
; Look for a socket where
; IP Packet UDP Destination Port = local Port
; IP Packet SA = Remote IP
207,8 → 208,7
 
sub esp, 8 ; reserve some place in stack for later
 
; Create the pseudoheader in stack,
; (now that we still have all the variables that are needed.)
; Create a part pseudoheader in stack,
push dword IP_PROTO_UDP shl 8
 
add ecx, UDP_Packet.Data
221,7 → 221,7
je .fail
 
mov [esp + 8 + 4], eax ; pointer to buffer start
mov [esp + 8 + 4 + 4], edx ; buffer size
mov [esp + 8 + 4 + 4], edx ; buffer size
 
rol cx, 8
mov [edi + UDP_Packet.Length], cx
239,7 → 239,7
rep movsb
pop ecx edi
 
pop dword [edi + UDP_Packet.SourcePort] ; fill in both portnumbers
pop dword [edi + UDP_Packet.SourcePort] ; fill in both portnumbers
mov [edi + UDP_Packet.Checksum], 0 ; set it to zero, to calculate checksum
 
; Checksum for UDP header + data
247,8 → 247,8
mov esi, edi
call checksum_1
; Checksum for pseudoheader
pushd [edi-4] ; destination address
pushd [edi-8] ; source address
pushd [edi-4] ; destination address
pushd [edi-8] ; source address
mov ecx, 12
mov esi, esp
call checksum_1