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 ;;
|
;; 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 ;;
|
;; 3C59X.INC ;;
|
||||||
@ -84,13 +80,14 @@
|
|||||||
;;
|
;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
|
||||||
PROMISCIOUS equ 1
|
|
||||||
|
|
||||||
|
|
||||||
format MS COFF
|
format MS COFF
|
||||||
|
|
||||||
API_VERSION equ 0x01000100
|
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
|
||||||
__DEBUG__ equ 1
|
__DEBUG__ equ 1
|
||||||
@ -101,55 +98,18 @@ include 'imports.inc'
|
|||||||
include 'fdo.inc'
|
include 'fdo.inc'
|
||||||
include 'netdrv.inc'
|
include 'netdrv.inc'
|
||||||
|
|
||||||
|
|
||||||
OS_BASE equ 0
|
|
||||||
new_app_base equ 0x60400000
|
|
||||||
PROC_BASE equ OS_BASE+0x0080000
|
|
||||||
|
|
||||||
public START
|
public START
|
||||||
public service_proc
|
public service_proc
|
||||||
public version
|
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
|
struc DPD { ; Download Packet Descriptor
|
||||||
|
|
||||||
.next_ptr dd ?
|
.next_ptr dd ?
|
||||||
.frame_start_hdr dd ?
|
.frame_start_hdr dd ?
|
||||||
.frag_addr dd ? ; for packet data
|
.frag_addr dd ? ; for packet data
|
||||||
.frag_len dd ? ; for packet data
|
.frag_len dd ? ; for packet data
|
||||||
.realaddr dd ?
|
.realaddr dd ?
|
||||||
.size = 32
|
.size = 32
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual at 0
|
virtual at 0
|
||||||
@ -159,12 +119,12 @@ end virtual
|
|||||||
|
|
||||||
struc UPD { ; Upload Packet Descriptor
|
struc UPD { ; Upload Packet Descriptor
|
||||||
|
|
||||||
.next_ptr dd ?
|
.next_ptr dd ?
|
||||||
.pkt_status dd ?
|
.pkt_status dd ?
|
||||||
.frag_addr dd ?
|
.frag_addr dd ?
|
||||||
.frag_len dd ? ; for packet data
|
.frag_len dd ? ; for packet data
|
||||||
.realaddr dd ?
|
.realaddr dd ?
|
||||||
.size = 32
|
.size = 32
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,17 +132,11 @@ virtual at 0
|
|||||||
upd UPD
|
upd UPD
|
||||||
end virtual
|
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
|
; Ethernet frame symbols
|
||||||
ETH_ALEN equ 6
|
ETH_ALEN equ 6
|
||||||
ETH_HLEN equ (2*ETH_ALEN+2)
|
ETH_HLEN equ (2*ETH_ALEN+2)
|
||||||
ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for
|
ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for
|
||||||
; mininmum 64bytes frame length
|
; mininmum 64bytes frame length
|
||||||
|
|
||||||
; Registers
|
; Registers
|
||||||
REG_POWER_MGMT_CTRL equ 0x7c
|
REG_POWER_MGMT_CTRL equ 0x7c
|
||||||
REG_UP_LIST_PTR equ 0x38
|
REG_UP_LIST_PTR equ 0x38
|
||||||
@ -193,9 +147,11 @@ end virtual
|
|||||||
REG_TX_STATUS equ 0x1b
|
REG_TX_STATUS equ 0x1b
|
||||||
REG_RX_STATUS equ 0x18
|
REG_RX_STATUS equ 0x18
|
||||||
REG_TX_DATA equ 0x10
|
REG_TX_DATA equ 0x10
|
||||||
|
|
||||||
; Common window registers
|
; Common window registers
|
||||||
REG_INT_STATUS equ 0xe
|
REG_INT_STATUS equ 0xe
|
||||||
REG_COMMAND equ 0xe
|
REG_COMMAND equ 0xe
|
||||||
|
|
||||||
; Register window 7
|
; Register window 7
|
||||||
REG_MASTER_STATUS equ 0xc
|
REG_MASTER_STATUS equ 0xc
|
||||||
REG_POWER_MGMT_EVENT equ 0xc
|
REG_POWER_MGMT_EVENT equ 0xc
|
||||||
@ -203,6 +159,7 @@ end virtual
|
|||||||
REG_VLAN_ETHER_TYPE equ 0x4
|
REG_VLAN_ETHER_TYPE equ 0x4
|
||||||
REG_VLAN_MASK equ 0x0
|
REG_VLAN_MASK equ 0x0
|
||||||
REG_MASTER_ADDRESS equ 0x0
|
REG_MASTER_ADDRESS equ 0x0
|
||||||
|
|
||||||
; Register window 6
|
; Register window 6
|
||||||
REG_BYTES_XMITTED_OK equ 0xc
|
REG_BYTES_XMITTED_OK equ 0xc
|
||||||
REG_BYTES_RCVD_OK equ 0xa
|
REG_BYTES_RCVD_OK equ 0xa
|
||||||
@ -216,6 +173,7 @@ end virtual
|
|||||||
REG_MULTIPLE_COLLISIONS equ 0x2
|
REG_MULTIPLE_COLLISIONS equ 0x2
|
||||||
REG_SQE_ERRORS equ 0x1
|
REG_SQE_ERRORS equ 0x1
|
||||||
REG_CARRIER_LOST equ 0x0
|
REG_CARRIER_LOST equ 0x0
|
||||||
|
|
||||||
; Register window 5
|
; Register window 5
|
||||||
REG_INDICATION_ENABLE equ 0xc
|
REG_INDICATION_ENABLE equ 0xc
|
||||||
REG_INTERRUPT_ENABLE equ 0xa
|
REG_INTERRUPT_ENABLE equ 0xa
|
||||||
@ -223,6 +181,7 @@ end virtual
|
|||||||
REG_RX_FILTER equ 0x8
|
REG_RX_FILTER equ 0x8
|
||||||
REG_RX_EARLY_THRESH equ 0x6
|
REG_RX_EARLY_THRESH equ 0x6
|
||||||
REG_TX_START_THRESH equ 0x0
|
REG_TX_START_THRESH equ 0x0
|
||||||
|
|
||||||
; Register window 4
|
; Register window 4
|
||||||
REG_UPPER_BYTES_OK equ 0xe
|
REG_UPPER_BYTES_OK equ 0xe
|
||||||
REG_BAD_SSD equ 0xc
|
REG_BAD_SSD equ 0xc
|
||||||
@ -231,8 +190,10 @@ end virtual
|
|||||||
REG_NETWORK_DIAGNOSTIC equ 0x6
|
REG_NETWORK_DIAGNOSTIC equ 0x6
|
||||||
REG_FIFO_DIAGNOSTIC equ 0x4
|
REG_FIFO_DIAGNOSTIC equ 0x4
|
||||||
REG_VCO_DIAGNOSTIC equ 0x2 ; may not supported
|
REG_VCO_DIAGNOSTIC equ 0x2 ; may not supported
|
||||||
|
|
||||||
; Bits in register window 4
|
; Bits in register window 4
|
||||||
BIT_AUTOSELECT equ 24
|
BIT_AUTOSELECT equ 24
|
||||||
|
|
||||||
; Register window 3
|
; Register window 3
|
||||||
REG_TX_FREE equ 0xc
|
REG_TX_FREE equ 0xc
|
||||||
REG_RX_FREE equ 0xa
|
REG_RX_FREE equ 0xa
|
||||||
@ -240,6 +201,7 @@ end virtual
|
|||||||
REG_MAC_CONTROL equ 0x6
|
REG_MAC_CONTROL equ 0x6
|
||||||
REG_MAX_PKT_SIZE equ 0x4
|
REG_MAX_PKT_SIZE equ 0x4
|
||||||
REG_INTERNAL_CONFIG equ 0x0
|
REG_INTERNAL_CONFIG equ 0x0
|
||||||
|
|
||||||
; Register window 2
|
; Register window 2
|
||||||
REG_RESET_OPTIONS equ 0xc
|
REG_RESET_OPTIONS equ 0xc
|
||||||
REG_STATION_MASK_HI equ 0xa
|
REG_STATION_MASK_HI equ 0xa
|
||||||
@ -248,6 +210,7 @@ end virtual
|
|||||||
REG_STATION_ADDRESS_HI equ 0x4
|
REG_STATION_ADDRESS_HI equ 0x4
|
||||||
REG_STATION_ADDRESS_MID equ 0x2
|
REG_STATION_ADDRESS_MID equ 0x2
|
||||||
REG_STATION_ADDRESS_LO equ 0x0
|
REG_STATION_ADDRESS_LO equ 0x0
|
||||||
|
|
||||||
; Register window 1
|
; Register window 1
|
||||||
REG_TRIGGER_BITS equ 0xc
|
REG_TRIGGER_BITS equ 0xc
|
||||||
REG_SOS_BITS equ 0xa
|
REG_SOS_BITS equ 0xa
|
||||||
@ -258,34 +221,42 @@ end virtual
|
|||||||
REG_SMB_STATUS equ 0x2
|
REG_SMB_STATUS equ 0x2
|
||||||
REG_SMB_ADDRESS equ 0x1
|
REG_SMB_ADDRESS equ 0x1
|
||||||
REG_SMB_FIFO_DATA equ 0x0
|
REG_SMB_FIFO_DATA equ 0x0
|
||||||
|
|
||||||
; Register window 0
|
; Register window 0
|
||||||
REG_EEPROM_DATA equ 0xc
|
REG_EEPROM_DATA equ 0xc
|
||||||
REG_EEPROM_COMMAND equ 0xa
|
REG_EEPROM_COMMAND equ 0xa
|
||||||
REG_BIOS_ROM_DATA equ 0x8
|
REG_BIOS_ROM_DATA equ 0x8
|
||||||
REG_BIOS_ROM_ADDR equ 0x4
|
REG_BIOS_ROM_ADDR equ 0x4
|
||||||
|
|
||||||
; Physical management bits
|
; Physical management bits
|
||||||
BIT_MGMT_DIR equ 2 ; drive with the data written in mgmtData
|
BIT_MGMT_DIR equ 2 ; drive with the data written in mgmtData
|
||||||
BIT_MGMT_DATA equ 1 ; MII management data bit
|
BIT_MGMT_DATA equ 1 ; MII management data bit
|
||||||
BIT_MGMT_CLK equ 0 ; MII management clock
|
BIT_MGMT_CLK equ 0 ; MII management clock
|
||||||
|
|
||||||
; MII commands
|
; MII commands
|
||||||
MII_CMD_MASK equ (1111b shl 10)
|
MII_CMD_MASK equ (1111b shl 10)
|
||||||
MII_CMD_READ equ (0110b shl 10)
|
MII_CMD_READ equ (0110b shl 10)
|
||||||
MII_CMD_WRITE equ (0101b shl 10)
|
MII_CMD_WRITE equ (0101b shl 10)
|
||||||
|
|
||||||
; MII registers
|
; MII registers
|
||||||
REG_MII_BMCR equ 0 ; basic mode control register
|
REG_MII_BMCR equ 0 ; basic mode control register
|
||||||
REG_MII_BMSR equ 1 ; basic mode status register
|
REG_MII_BMSR equ 1 ; basic mode status register
|
||||||
REG_MII_ANAR equ 4 ; auto negotiation advertisement register
|
REG_MII_ANAR equ 4 ; auto negotiation advertisement register
|
||||||
REG_MII_ANLPAR equ 5 ; auto negotiation link partner ability register
|
REG_MII_ANLPAR equ 5 ; auto negotiation link partner ability register
|
||||||
REG_MII_ANER equ 6 ; auto negotiation expansion register
|
REG_MII_ANER equ 6 ; auto negotiation expansion register
|
||||||
|
|
||||||
; MII bits
|
; MII bits
|
||||||
BIT_MII_AUTONEG_COMPLETE equ 5 ; auto-negotiation complete
|
BIT_MII_AUTONEG_COMPLETE equ 5 ; auto-negotiation complete
|
||||||
BIT_MII_PREAMBLE_SUPPRESSION equ 6
|
BIT_MII_PREAMBLE_SUPPRESSION equ 6
|
||||||
|
|
||||||
; eeprom bits and commands
|
; eeprom bits and commands
|
||||||
EEPROM_CMD_READ equ 0x80
|
EEPROM_CMD_READ equ 0x80
|
||||||
EEPROM_BIT_BUSY equ 15
|
EEPROM_BIT_BUSY equ 15
|
||||||
|
|
||||||
; eeprom registers
|
; eeprom registers
|
||||||
EEPROM_REG_OEM_NODE_ADDR equ 0xa
|
EEPROM_REG_OEM_NODE_ADDR equ 0xa
|
||||||
EEPROM_REG_CAPABILITIES equ 0x10
|
EEPROM_REG_CAPABILITIES equ 0x10
|
||||||
|
|
||||||
; Commands for command register
|
; Commands for command register
|
||||||
SELECT_REGISTER_WINDOW equ (1 shl 11)
|
SELECT_REGISTER_WINDOW equ (1 shl 11)
|
||||||
|
|
||||||
@ -306,7 +277,6 @@ end virtual
|
|||||||
EXTRA_PREAMBLE equ 0x4000
|
EXTRA_PREAMBLE equ 0x4000
|
||||||
|
|
||||||
; Status
|
; Status
|
||||||
|
|
||||||
IntLatch equ 0x0001
|
IntLatch equ 0x0001
|
||||||
HostError equ 0x0002
|
HostError equ 0x0002
|
||||||
TxComplete equ 0x0004
|
TxComplete equ 0x0004
|
||||||
@ -315,18 +285,15 @@ end virtual
|
|||||||
RxEarly equ 0x0020
|
RxEarly equ 0x0020
|
||||||
IntReq equ 0x0040
|
IntReq equ 0x0040
|
||||||
StatsFull equ 0x0080
|
StatsFull equ 0x0080
|
||||||
DMADone equ 0x0100 ; 1 shl 8
|
DMADone equ 0x0100
|
||||||
DownComplete equ 0x0200 ; 1 shl 9
|
DownComplete equ 0x0200
|
||||||
UpComplete equ 0x0400 ; 1 shl 10
|
UpComplete equ 0x0400
|
||||||
DMAInProgress equ 0x0800 ; 1 shl 11 (DMA controller is still busy)
|
DMAInProgress equ 0x0800 ; 1 shl 11 (DMA controller is still busy)
|
||||||
CmdInProgress equ 0x1000 ; 1 shl 12 (EL3_CMD 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
|
; Commands
|
||||||
|
|
||||||
TotalReset equ 0 shl 11
|
TotalReset equ 0 shl 11
|
||||||
SelectWindow equ 1 shl 11
|
SelectWindow equ 1 shl 11
|
||||||
StartCoax equ 2 shl 11
|
StartCoax equ 2 shl 11
|
||||||
@ -354,29 +321,47 @@ end virtual
|
|||||||
StatsEnable equ 21 shl 11
|
StatsEnable equ 21 shl 11
|
||||||
StatsDisable equ 22 shl 11
|
StatsDisable equ 22 shl 11
|
||||||
StopCoax equ 23 shl 11
|
StopCoax equ 23 shl 11
|
||||||
SetFilterBit equ 25 shl 11}
|
SetFilterBit equ 25 shl 11
|
||||||
|
|
||||||
|
|
||||||
; Rx mode bits
|
; Rx mode bits
|
||||||
|
|
||||||
RxStation equ 1
|
RxStation equ 1
|
||||||
RxMulticast equ 2
|
RxMulticast equ 2
|
||||||
RxBroadcast equ 4
|
RxBroadcast equ 4
|
||||||
RxProm equ 8
|
RxProm equ 8
|
||||||
|
|
||||||
|
|
||||||
; RX/TX buffers sizes
|
; RX/TX buffers sizes
|
||||||
|
|
||||||
MAX_ETH_PKT_SIZE equ 1536 ; max packet size
|
MAX_ETH_PKT_SIZE equ 1536 ; max packet size
|
||||||
NUM_RX_DESC equ 4 ; a power of 2 number
|
NUM_RX_DESC equ 4 ; a power of 2 number
|
||||||
NUM_TX_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
|
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
|
section '.flat' code readable align 16
|
||||||
|
|
||||||
@ -513,21 +498,14 @@ proc service_proc stdcall, ioctl:dword
|
|||||||
mov [device.pci_dev], cl
|
mov [device.pci_dev], cl
|
||||||
|
|
||||||
; Now, it's time to find the base io addres of the PCI device
|
; 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]
|
find_io [device.pci_bus], [device.pci_dev], [device.io_addr]
|
||||||
|
|
||||||
; We've found the io address, find IRQ now
|
; We've found the io address, find IRQ now
|
||||||
|
|
||||||
find_irq [device.pci_bus], [device.pci_dev], [device.irq_line]
|
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",\
|
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
|
[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
|
; Ok, the eth_device structure is ready, let's probe the device
|
||||||
call probe ; this function will output in eax
|
call probe ; this function will output in eax
|
||||||
test eax, eax
|
test eax, eax
|
||||||
@ -579,8 +557,6 @@ proc service_proc stdcall, ioctl:dword
|
|||||||
; todo: reset device into virgin state
|
; todo: reset device into virgin state
|
||||||
|
|
||||||
.err:
|
.err:
|
||||||
stdcall KernelFree, [device.rx_buffer]
|
|
||||||
stdcall KernelFree, [device.tx_buffer]
|
|
||||||
stdcall KernelFree, ebx
|
stdcall KernelFree, ebx
|
||||||
|
|
||||||
|
|
||||||
@ -613,7 +589,7 @@ endp
|
|||||||
;***************************************************************************
|
;***************************************************************************
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
probe: ; Tested - ok
|
probe:
|
||||||
|
|
||||||
DEBUGF 1,"Probing 3com card\n"
|
DEBUGF 1,"Probing 3com card\n"
|
||||||
|
|
||||||
@ -671,6 +647,11 @@ probe: ; Tested - ok
|
|||||||
jnz .boomerang_func
|
jnz .boomerang_func
|
||||||
mov [device.transmit], vortex_transmit
|
mov [device.transmit], vortex_transmit
|
||||||
DEBUGF 1,"Device is a vortex type\n"
|
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
|
jmp @f
|
||||||
.boomerang_func: ; full bus master, so use boomerang functions
|
.boomerang_func: ; full bus master, so use boomerang functions
|
||||||
mov [device.transmit], boomerang_transmit
|
mov [device.transmit], boomerang_transmit
|
||||||
@ -812,6 +793,9 @@ reset:
|
|||||||
mov ecx, 6
|
mov ecx, 6
|
||||||
rep stosd
|
rep stosd
|
||||||
|
|
||||||
|
; Set the mtu, kernel will be able to send now
|
||||||
|
mov [device.mtu], 1514
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
@ -975,13 +959,9 @@ tx_reset:
|
|||||||
jnz .tx_reset_loop
|
jnz .tx_reset_loop
|
||||||
.tx_set_prev:
|
.tx_set_prev:
|
||||||
; init last_dpd
|
; init last_dpd
|
||||||
mov eax, [device.dpd_buffer]
|
lea eax, [device.dpd_buffer + (NUM_TX_DESC-1)*dpd.size]
|
||||||
add eax, (NUM_TX_DESC-1)*dpd.size
|
|
||||||
mov [device.prev_dpd], eax
|
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:
|
.tx_enable:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -1004,59 +984,54 @@ rx_reset:
|
|||||||
set_io REG_COMMAND
|
set_io REG_COMMAND
|
||||||
mov ax, RxReset or 0x4
|
mov ax, RxReset or 0x4
|
||||||
out dx, ax
|
out dx, ax
|
||||||
|
|
||||||
; wait for RxReset to complete
|
; wait for RxReset to complete
|
||||||
mov ecx, 200000
|
mov ecx, 200000
|
||||||
.rx_reset_loop:
|
.loop:
|
||||||
in ax, dx
|
in ax, dx
|
||||||
test ah, 10000b ; check CmdInProgress
|
test ah, 10000b ; check CmdInProgress
|
||||||
dec ecx
|
dec ecx
|
||||||
jnz .rx_reset_loop
|
jnz .loop
|
||||||
|
|
||||||
; create upd ring
|
; create upd ring
|
||||||
|
lea eax, [device.upd_buffer]
|
||||||
|
GetRealAddr
|
||||||
|
mov edi, eax ; real addr of first descr
|
||||||
|
|
||||||
mov eax, [device.upd_buffer]
|
lea esi, [device.upd_buffer] ; ptr to first descr
|
||||||
mov [device.curr_upd], eax
|
lea edx, [device.upd_buffer + (NUM_RX_DESC-1)*upd.size] ; ptr to last descr
|
||||||
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]
|
|
||||||
|
|
||||||
mov ecx, NUM_RX_DESC
|
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
|
.upd_loop:
|
||||||
mov [eax + upd.frag_addr], edi
|
mov [edx + upd.next_ptr], edi
|
||||||
mov [eax + upd.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31)
|
|
||||||
mov [eax + upd.realaddr], ebx
|
|
||||||
|
|
||||||
add edi, MAX_ETH_FRAME_SIZE
|
push ecx edx
|
||||||
add ebx, MAX_ETH_FRAME_SIZE
|
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
|
add esi, upd.size
|
||||||
mov edx, eax
|
add edi, upd.size
|
||||||
add eax, upd.size
|
|
||||||
|
|
||||||
dec ecx
|
dec ecx
|
||||||
jnz .upd_loop
|
jnz .upd_loop
|
||||||
|
|
||||||
pop ebx
|
lea eax, [device.upd_buffer]
|
||||||
|
mov [device.curr_upd], eax
|
||||||
mov eax, [device.upd_buffer]
|
GetRealAddr
|
||||||
call GetPgAddr
|
|
||||||
set_io 0
|
set_io 0
|
||||||
set_io REG_UP_LIST_PTR
|
set_io REG_UP_LIST_PTR
|
||||||
out dx, eax
|
out dx, eax
|
||||||
|
|
||||||
.rx_enable:
|
.rx_enable:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
@ -2228,6 +2203,8 @@ vortex_transmit:
|
|||||||
mov ax, (10100b shl 11) + 1 ; StartDMADown
|
mov ax, (10100b shl 11) + 1 ; StartDMADown
|
||||||
out dx, ax
|
out dx, ax
|
||||||
.finish:
|
.finish:
|
||||||
|
call KernelFree
|
||||||
|
add esp, 4
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
@ -2245,26 +2222,32 @@ vortex_transmit:
|
|||||||
align 4
|
align 4
|
||||||
boomerang_transmit:
|
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
|
cmp dword [esp+8], MAX_ETH_FRAME_SIZE
|
||||||
ja .finish ; packet is too long
|
jg .fail
|
||||||
|
|
||||||
call check_tx_status
|
call check_tx_status
|
||||||
|
|
||||||
test al, al
|
test al, al
|
||||||
jnz tx_reset
|
jnz tx_reset
|
||||||
|
|
||||||
; calculate descriptor address
|
; calculate descriptor address
|
||||||
mov eax, [device.prev_dpd]
|
mov esi, [device.prev_dpd]
|
||||||
DEBUGF 1,"Previous DPD: %x\n", eax
|
DEBUGF 1,"Previous DPD: %x\n", esi
|
||||||
add eax, dpd.size
|
add esi, dpd.size
|
||||||
mov ecx, [device.dpd_buffer]
|
lea ecx, [device.dpd_buffer + (NUM_TX_DESC)*dpd.size]
|
||||||
add ecx, NUM_TX_DESC*dpd.size
|
cmp esi, ecx
|
||||||
cmp eax, ecx
|
jl @f
|
||||||
cmovae eax, [device.dpd_buffer] ; Wrap if needed
|
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
|
; check DnListPtr
|
||||||
set_io 0
|
set_io 0
|
||||||
set_io REG_DN_LIST_PTR
|
set_io REG_DN_LIST_PTR
|
||||||
@ -2272,91 +2255,56 @@ boomerang_transmit:
|
|||||||
; mark if Dn_List_Ptr is cleared
|
; mark if Dn_List_Ptr is cleared
|
||||||
test eax, eax
|
test eax, eax
|
||||||
setz [device.dn_list_ptr_cleared]
|
setz [device.dn_list_ptr_cleared]
|
||||||
|
|
||||||
; finish if no more free descriptor is available - FIXME!
|
; finish if no more free descriptor is available - FIXME!
|
||||||
cmp eax, [esp]
|
; cmp eax, esi
|
||||||
pop eax
|
; jz .finish
|
||||||
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 ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
|
|
||||||
; update statistics
|
; update statistics
|
||||||
inc [device.packets_tx]
|
inc [device.packets_tx]
|
||||||
|
mov ecx, [esp+8] ; buffer size
|
||||||
mov ecx, [esp+8+8]
|
|
||||||
add dword [device.bytes_tx], ecx
|
add dword [device.bytes_tx], ecx
|
||||||
adc dword [device.bytes_tx + 4], 0
|
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
|
; 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
|
call GetPgAddr
|
||||||
mov edi, [esp]
|
mov [esi+dpd.frag_addr], eax
|
||||||
and edi, 4096 - 1
|
mov ecx, [esp+8] ; packet size
|
||||||
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
|
|
||||||
or ecx, 0x80000000 ; last fragment
|
or ecx, 0x80000000 ; last fragment
|
||||||
DEBUGF 1,"Frag size + flag is: %x\n", ecx
|
mov [esi+dpd.frag_len], ecx
|
||||||
mov [eax+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
|
; test byte [device.has_hwcksm], 0xff
|
||||||
; jz @f
|
; jz @f
|
||||||
; or ecx, (1 shl 26) ; set AddTcpChecksum
|
; or ecx, (1 shl 26) ; set AddTcpChecksum
|
||||||
;@@:
|
;@@:
|
||||||
DEBUGF 1,"Frag start_hdr + flag is: %x\n", ecx
|
mov [esi+dpd.frame_start_hdr], ecx
|
||||||
mov [eax+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
|
; calculate physical address of dpd
|
||||||
mov edi, eax
|
mov eax, esi
|
||||||
call GetPgAddr
|
GetRealAddr
|
||||||
and edi, 4096 - 1
|
|
||||||
or eax, edi
|
|
||||||
cmp [device.dn_list_ptr_cleared], 0
|
cmp [device.dn_list_ptr_cleared], 0
|
||||||
jz .add_to_list
|
jz .add_to_list
|
||||||
|
|
||||||
DEBUGF 1,"DN list ptr: %x\n", eax
|
|
||||||
; write Dn_List_Ptr
|
; write Dn_List_Ptr
|
||||||
|
DEBUGF 1,"DPD phys addr=%x\n", eax
|
||||||
set_io 0
|
set_io 0
|
||||||
set_io REG_DN_LIST_PTR
|
set_io REG_DN_LIST_PTR
|
||||||
out dx, eax
|
out dx, eax
|
||||||
jmp .finish_pop
|
jmp .finish
|
||||||
.add_to_list:
|
|
||||||
|
|
||||||
|
.add_to_list:
|
||||||
DEBUGF 1,"Adding To list\n"
|
DEBUGF 1,"Adding To list\n"
|
||||||
|
push eax
|
||||||
; DnStall
|
; DnStall
|
||||||
set_io 0
|
set_io 0
|
||||||
set_io REG_COMMAND
|
set_io REG_COMMAND
|
||||||
@ -2364,47 +2312,46 @@ boomerang_transmit:
|
|||||||
out dx, ax
|
out dx, ax
|
||||||
|
|
||||||
; wait for DnStall to complete
|
; wait for DnStall to complete
|
||||||
|
|
||||||
DEBUGF 1,"Waiting for DnStall\n"
|
DEBUGF 1,"Waiting for DnStall\n"
|
||||||
mov ecx, 6000
|
mov ecx, 6000
|
||||||
.wait_for_stall:
|
.wait_for_stall:
|
||||||
in ax, dx ; read REG_INT_STATUS
|
in ax, dx ; read REG_INT_STATUS
|
||||||
test ah, 10000b
|
test ah, 10000b
|
||||||
jz .dnstall_ok
|
jz .dnstall_ok
|
||||||
dec ecx
|
dec ecx
|
||||||
jnz .wait_for_stall
|
jnz .wait_for_stall
|
||||||
|
|
||||||
.dnstall_ok:
|
.dnstall_ok:
|
||||||
DEBUGF 1,"DnStall ok!\n"
|
DEBUGF 1,"DnStall ok!\n"
|
||||||
mov eax, [esp] ; prev_tx_frame
|
|
||||||
mov ecx, [device.prev_dpd]
|
mov ecx, [device.prev_dpd]
|
||||||
mov [ecx+dpd.next_ptr], eax
|
mov [ecx+dpd.next_ptr], eax
|
||||||
|
|
||||||
set_io 0
|
set_io 0
|
||||||
set_io REG_DN_LIST_PTR
|
set_io REG_DN_LIST_PTR
|
||||||
in eax, dx
|
in eax, dx
|
||||||
|
|
||||||
test eax, eax
|
test eax, eax
|
||||||
|
pop eax
|
||||||
jnz .dnunstall
|
jnz .dnunstall
|
||||||
|
|
||||||
; if Dn_List_Ptr has been cleared fill it up
|
; if Dn_List_Ptr has been cleared fill it up
|
||||||
DEBUGF 1,"DnList Ptr has been cleared\n"
|
DEBUGF 1,"DnList Ptr has been cleared\n"
|
||||||
mov eax, [esp]
|
|
||||||
out dx, eax
|
out dx, eax
|
||||||
|
|
||||||
.dnunstall:
|
.dnunstall:
|
||||||
; DnUnStall
|
; DnUnStall
|
||||||
set_io 0
|
set_io 0
|
||||||
set_io REG_COMMAND
|
set_io REG_COMMAND
|
||||||
mov ax, ((110b shl 11)+3)
|
mov ax, ((110b shl 11)+3)
|
||||||
out dx, ax
|
out dx, ax
|
||||||
|
|
||||||
.finish_pop:
|
.finish:
|
||||||
pop [device.prev_tx_frame]
|
mov [device.prev_dpd], esi
|
||||||
pop [device.prev_dpd]
|
|
||||||
|
|
||||||
.finish:
|
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
ret
|
ret 8
|
||||||
|
|
||||||
|
.fail:
|
||||||
|
stdcall KernelFree, [esp+4]
|
||||||
|
ret 8
|
||||||
|
|
||||||
|
|
||||||
;---------------------------------
|
;---------------------------------
|
||||||
@ -2581,7 +2528,9 @@ int_vortex:
|
|||||||
|
|
||||||
.read_frame:
|
.read_frame:
|
||||||
; program buffer address to read in
|
; 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
|
test eax, eax
|
||||||
jz .finish
|
jz .finish
|
||||||
|
|
||||||
@ -2672,14 +2621,13 @@ int_vortex:
|
|||||||
align 4
|
align 4
|
||||||
int_boomerang:
|
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
|
; find pointer of device wich made IRQ occur
|
||||||
|
|
||||||
mov esi, BOOMERANG_LIST
|
mov esi, BOOMERANG_LIST
|
||||||
mov ecx, [BOOMERANG_DEVICES]
|
mov ecx, [BOOMERANG_DEVICES]
|
||||||
|
|
||||||
; DEBUGF 1,"Devices: %u\n", ecx
|
|
||||||
test ecx, ecx
|
test ecx, ecx
|
||||||
jz .fail
|
jz .fail
|
||||||
.nextdevice:
|
.nextdevice:
|
||||||
@ -2705,7 +2653,6 @@ int_boomerang:
|
|||||||
.got_it:
|
.got_it:
|
||||||
|
|
||||||
DEBUGF 1,"Device: %x Status: %x ", ebx, eax
|
DEBUGF 1,"Device: %x Status: %x ", ebx, eax
|
||||||
|
|
||||||
push ax
|
push ax
|
||||||
; disable all INTS
|
; disable all INTS
|
||||||
|
|
||||||
@ -2713,13 +2660,6 @@ int_boomerang:
|
|||||||
mov ax, SetIntrEnb
|
mov ax, SetIntrEnb
|
||||||
out dx, ax
|
out dx, ax
|
||||||
|
|
||||||
;; acknowledge all int sources
|
|
||||||
;
|
|
||||||
; mov ax, word [esp]
|
|
||||||
; and ax, 0xff
|
|
||||||
; or ax, AckIntr
|
|
||||||
; out dx, ax
|
|
||||||
|
|
||||||
;--------------------------------------------------------------------------
|
;--------------------------------------------------------------------------
|
||||||
test word[esp], UpComplete
|
test word[esp], UpComplete
|
||||||
jz .noRX
|
jz .noRX
|
||||||
@ -2730,75 +2670,59 @@ int_boomerang:
|
|||||||
DEBUGF 1,"UpComplete\n"
|
DEBUGF 1,"UpComplete\n"
|
||||||
|
|
||||||
; check if packet is uploaded
|
; check if packet is uploaded
|
||||||
mov eax, [device.curr_upd]
|
mov esi, [device.curr_upd]
|
||||||
test byte [eax+upd.pkt_status+1], 0x80 ; upPktComplete
|
test byte [esi+upd.pkt_status+1], 0x80 ; upPktComplete
|
||||||
jz .finish
|
jz .finish
|
||||||
|
DEBUGF 1, "Current upd: %x\n", esi
|
||||||
; packet is uploaded check for any error
|
; packet is uploaded check for any error
|
||||||
.check_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
|
jz .copy_packet_length
|
||||||
DEBUGF 1,"Error in packet\n"
|
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
|
jmp .finish
|
||||||
.copy_packet_length:
|
.copy_packet_length:
|
||||||
mov ecx, [eax+upd.pkt_status]
|
mov ecx, [esi+upd.pkt_status]
|
||||||
and ecx, 0x1fff
|
and ecx, 0x1fff
|
||||||
cmp ecx, MAX_ETH_PKT_SIZE
|
|
||||||
jbe .copy_packet
|
|
||||||
and [eax+upd.pkt_status], 0
|
|
||||||
jmp .finish
|
|
||||||
|
|
||||||
.copy_packet:
|
; cmp ecx, MAX_ETH_PKT_SIZE
|
||||||
DEBUGF 1, " data hw addr:%x\n", [eax+upd.frag_addr]
|
; jbe .copy_packet
|
||||||
|
; and [esi+upd.pkt_status], 0
|
||||||
|
; jmp .finish
|
||||||
|
; .copy_packet:
|
||||||
|
|
||||||
mov esi, [eax+upd.realaddr]
|
DEBUGF 1, "Received %u bytes in buffer %x\n", ecx, [esi+upd.realaddr]:8
|
||||||
|
|
||||||
push esi ecx
|
|
||||||
stdcall KernelAlloc, ecx ; Allocate a buffer to put packet into
|
|
||||||
pop ecx esi
|
|
||||||
test eax, eax
|
|
||||||
jz .finish
|
|
||||||
|
|
||||||
push dword .loop ;.finish
|
push dword .loop ;.finish
|
||||||
push ecx eax
|
push ecx
|
||||||
mov edi, eax
|
push [esi+upd.realaddr]
|
||||||
|
|
||||||
DEBUGF 1, " copying %u bytes from %x to %x\n", ecx, esi, edi
|
|
||||||
|
|
||||||
; update statistics
|
; update statistics
|
||||||
inc [device.packets_rx]
|
inc [device.packets_rx]
|
||||||
|
|
||||||
add dword [device.bytes_rx], ecx
|
add dword [device.bytes_rx], ecx
|
||||||
adc dword [device.bytes_rx + 4], 0
|
adc dword [device.bytes_rx + 4], 0
|
||||||
|
|
||||||
; copy packet data
|
; update UPD (Alloc new buffer for next packet)
|
||||||
shr cx , 1
|
stdcall KernelAlloc, MAX_ETH_FRAME_SIZE
|
||||||
jnc .nb
|
mov [esi + upd.realaddr], eax
|
||||||
movsb
|
GetRealAddr
|
||||||
.nb:
|
mov [esi + upd.frag_addr], eax
|
||||||
shr cx , 1
|
and [esi + upd.pkt_status], 0
|
||||||
jnc .nw
|
mov [esi + upd.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31)
|
||||||
movsw
|
|
||||||
.nw:
|
|
||||||
rep movsd
|
|
||||||
|
|
||||||
mov eax, [device.curr_upd]
|
; Update UPD pointer
|
||||||
DEBUGF 1, "current upd: %x\n", eax
|
add esi, upd.size
|
||||||
and [eax + upd.pkt_status], 0 ; clear the ring buffer entry for reuse
|
lea ecx, [device.upd_buffer+(NUM_RX_DESC)*upd.size]
|
||||||
mov [eax + upd.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31) ;;;
|
cmp esi, ecx
|
||||||
add eax, upd.size
|
jl @f
|
||||||
|
lea esi, [device.upd_buffer]
|
||||||
mov ecx, [device.upd_buffer]
|
@@:
|
||||||
add ecx, (NUM_RX_DESC)*upd.size
|
mov [device.curr_upd], esi
|
||||||
|
DEBUGF 1, "Next upd: %x\n", esi
|
||||||
cmp eax, ecx
|
|
||||||
cmovae eax, [device.upd_buffer]
|
|
||||||
mov [device.curr_upd], eax
|
|
||||||
DEBUGF 1, "next upd: %x\n", eax
|
|
||||||
|
|
||||||
jmp EthReceiver
|
jmp EthReceiver
|
||||||
|
|
||||||
.loop:
|
.loop:
|
||||||
|
|
||||||
mov ebx, [esp]
|
mov ebx, [esp]
|
||||||
jmp .receive
|
jmp .receive
|
||||||
|
|
||||||
@ -2811,14 +2735,38 @@ int_boomerang:
|
|||||||
in eax, dx
|
in eax, dx
|
||||||
test ah, 0x20 ; UpStalled
|
test ah, 0x20 ; UpStalled
|
||||||
jz .noUpUnStall
|
jz .noUpUnStall
|
||||||
|
|
||||||
|
DEBUGF 1, "upUnStalling\n"
|
||||||
; issue upUnStall command
|
; issue upUnStall command
|
||||||
set_io REG_COMMAND
|
set_io REG_COMMAND
|
||||||
mov ax, ((11b shl 12)+1) ; upUnStall
|
mov ax, ((11b shl 12)+1) ; upUnStall
|
||||||
out dx, ax
|
out dx, ax
|
||||||
DEBUGF 1, "upUnStalling\n"
|
|
||||||
.noUpUnStall:
|
|
||||||
|
|
||||||
|
;;;; FIXME: make upunstall work
|
||||||
|
|
||||||
|
.noUpUnStall:
|
||||||
.noRX:
|
.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
|
pop ax
|
||||||
|
|
||||||
set_io 0
|
set_io 0
|
||||||
@ -2826,11 +2774,6 @@ int_boomerang:
|
|||||||
or ax, AckIntr
|
or ax, AckIntr
|
||||||
out dx, ax
|
out dx, ax
|
||||||
|
|
||||||
; set_io REG_COMMAND
|
|
||||||
; mov ax, AckIntr + IntLatch
|
|
||||||
; out dx, ax
|
|
||||||
|
|
||||||
|
|
||||||
set_io REG_INT_STATUS
|
set_io REG_INT_STATUS
|
||||||
in ax, dx
|
in ax, dx
|
||||||
test ax, S_5_INTS
|
test ax, S_5_INTS
|
||||||
@ -2841,18 +2784,14 @@ int_boomerang:
|
|||||||
mov ax, SetIntrEnb + S_5_INTS
|
mov ax, SetIntrEnb + S_5_INTS
|
||||||
out dx, ax
|
out dx, ax
|
||||||
|
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; End of code
|
; End of code
|
||||||
|
|
||||||
align 4 ; Place all initialised data here
|
align 4 ; Place all initialised data here
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
macro strtbl name, [string]
|
macro strtbl name, [string]
|
||||||
{
|
{
|
||||||
common
|
common
|
||||||
@ -2866,7 +2805,7 @@ forward
|
|||||||
|
|
||||||
VORTEX_DEVICES dd 0
|
VORTEX_DEVICES dd 0
|
||||||
BOOMERANG_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
|
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
|
; 3c920B-EMB-WNM Tornado
|
||||||
HW_VERSIONS_SIZE = $ - hw_versions
|
HW_VERSIONS_SIZE = $ - hw_versions
|
||||||
|
|
||||||
|
|
||||||
include_debug_strings ; All data wich FDO uses will be included here
|
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
|
section '.data' data readable writable align 16 ; place all uninitialized data place here
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; 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 ;;
|
;; Distributed under terms of the GNU General Public License ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; RTL8029/ne2000 driver for KolibriOS ;;
|
;; 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 ;;
|
;; Written by hidnplayr@kolibrios.org ;;
|
||||||
;; with help from CleverMouse ;;
|
;; with help from CleverMouse ;;
|
||||||
@ -11,55 +14,46 @@
|
|||||||
;; GNU GENERAL PUBLIC LICENSE ;;
|
;; GNU GENERAL PUBLIC LICENSE ;;
|
||||||
;; Version 2, June 1991 ;;
|
;; 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
|
format MS COFF
|
||||||
|
|
||||||
API_VERSION equ 0x01000100
|
API_VERSION equ 0x01000100
|
||||||
|
DRIVER_VERSION equ 5
|
||||||
|
|
||||||
DEBUG equ 1
|
MAX_DEVICES equ 16
|
||||||
__DEBUG__ equ 1
|
|
||||||
__DEBUG_LEVEL__ equ 1
|
DEBUG equ 1
|
||||||
|
__DEBUG__ equ 1
|
||||||
|
__DEBUG_LEVEL__ equ 1
|
||||||
|
|
||||||
include 'proc32.inc'
|
include 'proc32.inc'
|
||||||
include 'imports.inc'
|
include 'imports.inc'
|
||||||
include 'fdo.inc'
|
include 'fdo.inc'
|
||||||
include 'netdrv.inc'
|
include 'netdrv.inc'
|
||||||
|
|
||||||
OS_BASE equ 0
|
|
||||||
new_app_base equ 0x60400000
|
|
||||||
PROC_BASE equ OS_BASE+0x0080000
|
|
||||||
|
|
||||||
|
|
||||||
virtual at ebx
|
virtual at ebx
|
||||||
|
|
||||||
device:
|
device:
|
||||||
|
|
||||||
ETH_DEVICE
|
ETH_DEVICE
|
||||||
|
|
||||||
.io_addr dd ?
|
.io_addr dd ?
|
||||||
.irq_line db ?
|
.irq_line db ?
|
||||||
.pci_bus db ?
|
.pci_bus db ?
|
||||||
.pci_dev db ?
|
.pci_dev db ?
|
||||||
|
|
||||||
.flags db ?
|
.flags db ?
|
||||||
.vendor db ?
|
.vendor db ?
|
||||||
.asic_base dw ?
|
.asic_base dw ?
|
||||||
.memsize db ?
|
.memsize db ?
|
||||||
.rx_start db ?
|
.rx_start db ?
|
||||||
.tx_start db ?
|
.tx_start db ?
|
||||||
.bmem dd ?
|
.bmem dd ?
|
||||||
.rmem dd ?
|
.rmem dd ?
|
||||||
.romdata rb 16
|
.romdata rb 16
|
||||||
|
|
||||||
.size = $ - device
|
.size = $ - device
|
||||||
|
|
||||||
end virtual
|
end virtual
|
||||||
|
|
||||||
@ -68,8 +62,6 @@ public START
|
|||||||
public service_proc
|
public service_proc
|
||||||
public version
|
public version
|
||||||
|
|
||||||
MAX_DEVICES equ 16 ; Max number of devices this driver may handle
|
|
||||||
|
|
||||||
P0_PSTART equ 0x01
|
P0_PSTART equ 0x01
|
||||||
P0_PSTOP equ 0x02
|
P0_PSTOP equ 0x02
|
||||||
P0_BOUND equ 0x03
|
P0_BOUND equ 0x03
|
||||||
@ -234,8 +226,8 @@ proc service_proc stdcall, ioctl:dword
|
|||||||
|
|
||||||
; check if the device is already listed
|
; check if the device is already listed
|
||||||
|
|
||||||
mov esi, DEVICE_LIST
|
mov esi, device_list
|
||||||
mov ecx, [DEVICES]
|
mov ecx, [devices]
|
||||||
test ecx, ecx
|
test ecx, ecx
|
||||||
jz .firstdevice_pci
|
jz .firstdevice_pci
|
||||||
|
|
||||||
@ -269,8 +261,8 @@ proc service_proc stdcall, ioctl:dword
|
|||||||
|
|
||||||
.isa:
|
.isa:
|
||||||
|
|
||||||
mov esi, DEVICE_LIST
|
mov esi, device_list
|
||||||
mov ecx, [DEVICES]
|
mov ecx, [devices]
|
||||||
test ecx, ecx
|
test ecx, ecx
|
||||||
jz .firstdevice_isa
|
jz .firstdevice_isa
|
||||||
mov al , [eax+3]
|
mov al , [eax+3]
|
||||||
@ -305,9 +297,9 @@ proc service_proc stdcall, ioctl:dword
|
|||||||
test eax, eax
|
test eax, eax
|
||||||
jnz .err ; If an error occured, exit
|
jnz .err ; If an error occured, exit
|
||||||
|
|
||||||
mov eax, [DEVICES]
|
mov eax, [devices]
|
||||||
mov [DEVICE_LIST+4*eax], ebx
|
mov [device_list+4*eax], ebx
|
||||||
inc [DEVICES]
|
inc [devices]
|
||||||
|
|
||||||
mov [device.type], NET_TYPE_ETH
|
mov [device.type], NET_TYPE_ETH
|
||||||
call NetRegDev
|
call NetRegDev
|
||||||
@ -346,7 +338,7 @@ endp
|
|||||||
|
|
||||||
create_new_struct:
|
create_new_struct:
|
||||||
|
|
||||||
cmp [DEVICES], MAX_DEVICES
|
cmp [devices], MAX_DEVICES
|
||||||
jge .fail
|
jge .fail
|
||||||
|
|
||||||
push edx
|
push edx
|
||||||
@ -572,7 +564,7 @@ nsr_001:
|
|||||||
nsr_002:
|
nsr_002:
|
||||||
out dx, al
|
out dx, al
|
||||||
|
|
||||||
;clear remote bytes count
|
; clear remote bytes count
|
||||||
set_io 0
|
set_io 0
|
||||||
|
|
||||||
xor al, al
|
xor al, al
|
||||||
@ -584,7 +576,7 @@ nsr_002:
|
|||||||
out dx, al
|
out dx, al
|
||||||
|
|
||||||
|
|
||||||
;initialize Receive configuration register
|
; initialize Receive configuration register
|
||||||
set_io P0_RCR
|
set_io P0_RCR
|
||||||
mov al, 0x20 ; monitor mode
|
mov al, 0x20 ; monitor mode
|
||||||
out dx, al
|
out dx, al
|
||||||
@ -670,6 +662,9 @@ nsr_002:
|
|||||||
mov ecx, 6
|
mov ecx, 6
|
||||||
rep stosd
|
rep stosd
|
||||||
|
|
||||||
|
; Set the mtu, kernel will be able to send now
|
||||||
|
mov [device.mtu], 1514
|
||||||
|
|
||||||
; Indicate that we have successfully reset the card
|
; Indicate that we have successfully reset the card
|
||||||
DEBUGF 2,"Done!\n"
|
DEBUGF 2,"Done!\n"
|
||||||
|
|
||||||
@ -733,10 +728,14 @@ transmit:
|
|||||||
adc dword [device.bytes_tx + 4], 0
|
adc dword [device.bytes_tx + 4], 0
|
||||||
|
|
||||||
.finish:
|
.finish:
|
||||||
|
call Kernelfree
|
||||||
|
add esp, 4
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.err:
|
.err:
|
||||||
|
call Kernelfree
|
||||||
|
add esp, 4
|
||||||
or eax, -1
|
or eax, -1
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -752,8 +751,8 @@ int_handler:
|
|||||||
DEBUGF 2,"IRQ %x ",eax:2
|
DEBUGF 2,"IRQ %x ",eax:2
|
||||||
|
|
||||||
; find pointer of device wich made INT occur
|
; find pointer of device wich made INT occur
|
||||||
mov esi, DEVICE_LIST
|
mov esi, device_list
|
||||||
mov ecx, [DEVICES]
|
mov ecx, [devices]
|
||||||
.nextdevice:
|
.nextdevice:
|
||||||
mov ebx, [esi]
|
mov ebx, [esi]
|
||||||
|
|
||||||
@ -1197,8 +1196,8 @@ epw_005: ; Wait for Remote DMA Complete
|
|||||||
;all initialized data place here
|
;all initialized data place here
|
||||||
align 4
|
align 4
|
||||||
|
|
||||||
DEVICES dd 0
|
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 'RTL8029/ne2000',0 ;max 16 chars include zero
|
my_service db 'RTL8029/ne2000',0 ;max 16 chars include zero
|
||||||
|
|
||||||
device_1 db 'Realtek 8029',0
|
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
|
section '.data' data readable writable align 16 ;place all uninitialized data place here
|
||||||
|
|
||||||
DEVICE_LIST rd MAX_DEVICES
|
device_list rd MAX_DEVICES
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,22 +3,24 @@
|
|||||||
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
|
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
;; Distributed under terms of the GNU General Public License ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; Realtek 8139 driver for KolibriOS ;;
|
;; Realtek 8139 driver for KolibriOS ;;
|
||||||
|
;; ;;
|
||||||
|
;; based on RTL8139.asm driver for menuetos ;;
|
||||||
|
;; and realtek8139.asm for SolarOS by Eugen Brasoveanu ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; Written by hidnplayr@kolibrios.org ;;
|
;; Written by hidnplayr@kolibrios.org ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; 0.1 - x march 2009 ;;
|
|
||||||
;; 0.2 - 8 november 2009 ;;
|
|
||||||
;; ;;
|
|
||||||
;; GNU GENERAL PUBLIC LICENSE ;;
|
;; GNU GENERAL PUBLIC LICENSE ;;
|
||||||
;; Version 2, June 1991 ;;
|
;; Version 2, June 1991 ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
|
||||||
format MS COFF
|
format MS COFF
|
||||||
|
|
||||||
API_VERSION equ 0x01000100
|
API_VERSION equ 0x01000100
|
||||||
|
DRIVER_VERSION equ 5
|
||||||
|
|
||||||
|
MAX_DEVICES equ 16
|
||||||
|
|
||||||
DEBUG equ 1
|
DEBUG equ 1
|
||||||
__DEBUG__ equ 1
|
__DEBUG__ equ 1
|
||||||
@ -29,46 +31,10 @@ include 'imports.inc'
|
|||||||
include 'fdo.inc'
|
include 'fdo.inc'
|
||||||
include 'netdrv.inc'
|
include 'netdrv.inc'
|
||||||
|
|
||||||
OS_BASE equ 0
|
|
||||||
new_app_base equ 0x60400000
|
|
||||||
PROC_BASE equ OS_BASE+0x0080000
|
|
||||||
|
|
||||||
public START
|
public START
|
||||||
public service_proc
|
public service_proc
|
||||||
public version
|
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_IDR0 equ 0x00
|
||||||
REG_MAR0 equ 0x08 ; multicast filter register 0
|
REG_MAR0 equ 0x08 ; multicast filter register 0
|
||||||
REG_MAR4 equ 0x0c ; multicast filter register 4
|
REG_MAR4 equ 0x0c ; multicast filter register 4
|
||||||
@ -169,8 +135,8 @@ end virtual
|
|||||||
|
|
||||||
RX_BUFFER_SIZE equ (8192 shl RBLEN);+16
|
RX_BUFFER_SIZE equ (8192 shl RBLEN);+16
|
||||||
MAX_ETH_FRAME_SIZE equ 1516 ; exactly 1514 wthout CRC
|
MAX_ETH_FRAME_SIZE equ 1516 ; exactly 1514 wthout CRC
|
||||||
|
|
||||||
NUM_TX_DESC equ 4
|
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_REG_ETH_ID equ 7 ; MAC offset
|
||||||
EE_93C46_READ_CMD equ (6 shl 6) ; 110b + 6bit address
|
EE_93C46_READ_CMD equ (6 shl 6) ; 110b + 6bit address
|
||||||
@ -228,6 +194,30 @@ end virtual
|
|||||||
TSR_CRS equ 1 SHL 31
|
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
|
section '.flat' code readable align 16
|
||||||
|
|
||||||
@ -298,8 +288,8 @@ proc service_proc stdcall, ioctl:dword
|
|||||||
|
|
||||||
; check if the device is already listed
|
; check if the device is already listed
|
||||||
|
|
||||||
mov esi, RTL8139_LIST
|
mov esi, device_list
|
||||||
mov ecx, [RTL8139_DEV]
|
mov ecx, [devices]
|
||||||
test ecx, ecx
|
test ecx, ecx
|
||||||
jz .firstdevice
|
jz .firstdevice
|
||||||
|
|
||||||
@ -315,11 +305,11 @@ proc service_proc stdcall, ioctl:dword
|
|||||||
|
|
||||||
; This device doesnt have its own eth_device structure yet, lets create one
|
; This device doesnt have its own eth_device structure yet, lets create one
|
||||||
.firstdevice:
|
.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
|
jge .fail
|
||||||
|
|
||||||
push edx
|
push edx
|
||||||
stdcall KernelAlloc, device.size ; Allocate the buffer for eth_device structure
|
stdcall KernelAlloc, device.size ; Allocate the buffer for eth_device structure
|
||||||
pop edx
|
pop edx
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .fail
|
jz .fail
|
||||||
@ -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.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
|
; 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
|
test eax, eax
|
||||||
jnz .err ; If an error occured, exit
|
jnz .err ; If an error occured, exit
|
||||||
|
|
||||||
mov eax, [RTL8139_DEV] ; Add the device structure to our device list
|
mov eax, [devices] ; Add the device structure to our device list
|
||||||
mov [RTL8139_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 [RTL8139_DEV] ;
|
inc [devices] ;
|
||||||
|
|
||||||
|
|
||||||
mov [device.type], NET_TYPE_ETH
|
mov [device.type], NET_TYPE_ETH
|
||||||
call NetRegDev
|
call NetRegDev
|
||||||
@ -393,7 +382,7 @@ proc service_proc stdcall, ioctl:dword
|
|||||||
|
|
||||||
.err:
|
.err:
|
||||||
stdcall KernelFree, dword [device.rx_buffer]
|
stdcall KernelFree, dword [device.rx_buffer]
|
||||||
stdcall KernelFree, dword [device.tx_buffer]
|
;; stdcall KernelFree, dword [device.tx_buffer]
|
||||||
stdcall KernelFree, ebx
|
stdcall KernelFree, ebx
|
||||||
|
|
||||||
|
|
||||||
@ -537,7 +526,7 @@ reset:
|
|||||||
DEBUGF 1,"\nCould not attach int handler!\n"
|
DEBUGF 1,"\nCould not attach int handler!\n"
|
||||||
; or eax, -1
|
; or eax, -1
|
||||||
; ret
|
; ret
|
||||||
@@:
|
@@:
|
||||||
|
|
||||||
; reset chip
|
; reset chip
|
||||||
|
|
||||||
@ -613,6 +602,7 @@ reset:
|
|||||||
|
|
||||||
mov [device.rx_data_offset], eax
|
mov [device.rx_data_offset], eax
|
||||||
mov [device.curr_tx_desc], al
|
mov [device.curr_tx_desc], al
|
||||||
|
mov [device.last_tx_desc], al
|
||||||
|
|
||||||
; clear packet/byte counters
|
; clear packet/byte counters
|
||||||
|
|
||||||
@ -625,21 +615,6 @@ reset:
|
|||||||
set_io REG_MPC
|
set_io REG_MPC
|
||||||
out dx , eax
|
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
|
; set RxBuffer address, init RX buffer offset
|
||||||
|
|
||||||
mov eax, [device.rx_buffer]
|
mov eax, [device.rx_buffer]
|
||||||
@ -658,6 +633,9 @@ reset:
|
|||||||
|
|
||||||
call read_mac
|
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
|
; Indicate that we have successfully reset the card
|
||||||
|
|
||||||
DEBUGF 2,"Done!\n"
|
DEBUGF 2,"Done!\n"
|
||||||
@ -675,7 +653,6 @@ reset:
|
|||||||
;; pointer to device structure in ebx ;;
|
;; pointer to device structure in ebx ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
transmit:
|
transmit:
|
||||||
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8]
|
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8]
|
||||||
@ -686,71 +663,69 @@ transmit:
|
|||||||
[eax+13]:2,[eax+12]:2
|
[eax+13]:2,[eax+12]:2
|
||||||
|
|
||||||
cmp dword [esp+8], MAX_ETH_FRAME_SIZE
|
cmp dword [esp+8], MAX_ETH_FRAME_SIZE
|
||||||
jg .finish ; packet is too long
|
jg .fail
|
||||||
cmp dword [esp+8], 60
|
cmp dword [esp+8], 60
|
||||||
jl .finish ; packet is too short
|
jl .fail
|
||||||
|
|
||||||
; check descriptor
|
; check if we own the discriptor
|
||||||
DEBUGF 1,"Checking descriptor, "
|
set_io 0
|
||||||
movzx ecx, [device.curr_tx_desc]
|
movzx ecx, [device.curr_tx_desc]
|
||||||
mov edx, [device.io_addr]
|
shl ecx, 2
|
||||||
lea edx, [edx+ecx*4+REG_TSD0]
|
lea edx, [edx+ecx+REG_TSD0]
|
||||||
in ax, dx
|
in ax, dx
|
||||||
test ax, 0x1fff ; or no size given
|
test ax, (1 shl BIT_OWN)
|
||||||
jz .send_packet
|
jz .wait_to_send
|
||||||
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, "
|
|
||||||
|
|
||||||
push edx ebx ; TODO : rtl8139 internal timer should be used instead
|
.send_packet:
|
||||||
stdcall Sleep, TX_TIMEOUT ; ? What registers does this destroy ?
|
; Set the buffer address
|
||||||
pop ebx edx
|
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 the size of the buffer
|
||||||
and ax, (1 shl BIT_TOK) or (1 shl BIT_OWN)
|
set_io 0
|
||||||
cmp ax, (1 shl BIT_TOK) or (1 shl BIT_OWN)
|
lea edx, [edx+ecx+REG_TSD0]
|
||||||
jz .send_packet ; if chip hung, reset it
|
mov eax, [esp+8]
|
||||||
push dx
|
; or eax, (ERTXTH shl BIT_ERTXTH) ; Early threshold
|
||||||
call reset ; reset the card
|
out dx , eax
|
||||||
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
|
|
||||||
|
|
||||||
|
; Update stats
|
||||||
|
inc [device.packets_tx]
|
||||||
add dword [device.bytes_tx], eax
|
add dword [device.bytes_tx], eax
|
||||||
adc dword [device.bytes_tx + 4], 0
|
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)
|
; get next descriptor
|
||||||
out dx , eax ;
|
|
||||||
|
|
||||||
; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ...
|
|
||||||
inc [device.curr_tx_desc]
|
inc [device.curr_tx_desc]
|
||||||
and [device.curr_tx_desc], 3
|
and [device.curr_tx_desc], 3
|
||||||
|
|
||||||
DEBUGF 1," - Packet Sent! "
|
DEBUGF 1,"Packet Sent! "
|
||||||
.finish:
|
xor eax, eax
|
||||||
DEBUGF 1," - Done!\n"
|
ret 8
|
||||||
ret
|
|
||||||
|
.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 ;;
|
;; Interrupt handler ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
int_handler:
|
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
|
; find pointer of device wich made IRQ occur
|
||||||
|
|
||||||
mov esi, RTL8139_LIST
|
mov esi, device_list
|
||||||
mov ecx, [RTL8139_DEV]
|
mov ecx, [devices]
|
||||||
test ecx, ecx
|
test ecx, ecx
|
||||||
jz .fail
|
jz .fail
|
||||||
.nextdevice:
|
.nextdevice:
|
||||||
@ -799,7 +773,6 @@ int_handler:
|
|||||||
|
|
||||||
;----------------------------------------------------
|
;----------------------------------------------------
|
||||||
; Received packet ok?
|
; Received packet ok?
|
||||||
|
|
||||||
test ax, ISR_ROK
|
test ax, ISR_ROK
|
||||||
jz @f
|
jz @f
|
||||||
push ax
|
push ax
|
||||||
@ -836,7 +809,6 @@ int_handler:
|
|||||||
test eax, eax ; Test if we allocated succesfully
|
test eax, eax ; Test if we allocated succesfully
|
||||||
jz .abort
|
jz .abort
|
||||||
|
|
||||||
|
|
||||||
mov edi, eax ; Where we will copy too
|
mov edi, eax ; Where we will copy too
|
||||||
|
|
||||||
mov esi, [esp] ; The buffer we will copy from
|
mov esi, [esp] ; The buffer we will copy from
|
||||||
@ -914,60 +886,78 @@ int_handler:
|
|||||||
|
|
||||||
;----------------------------------------------------
|
;----------------------------------------------------
|
||||||
; Transmit error ?
|
; Transmit error ?
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
test ax, ISR_TER
|
test ax, ISR_TER
|
||||||
jz @f
|
jz @f
|
||||||
|
|
||||||
push ax
|
; push ax
|
||||||
cmp [device.curr_tx_desc], 4
|
; cmp [device.curr_tx_desc], 4
|
||||||
jz .notxd
|
; 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
|
|
||||||
;
|
;
|
||||||
; .nofd:
|
; set_io 0
|
||||||
pop ax
|
; 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 ?
|
; Transmit ok ?
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
test ax, ISR_TOK
|
test ax, ISR_TOK
|
||||||
jz @f
|
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 ?
|
; Rx buffer overflow ?
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
test ax, ISR_RXOVW
|
test ax, ISR_RXOVW
|
||||||
jz @f
|
jz @f
|
||||||
@ -975,16 +965,14 @@ int_handler:
|
|||||||
push ax
|
push ax
|
||||||
DEBUGF 2,"RX-buffer overflow!\n"
|
DEBUGF 2,"RX-buffer overflow!\n"
|
||||||
|
|
||||||
mov edx, [device.io_addr]
|
set_io 0
|
||||||
add edx, REG_ISR
|
set_io REG_ISR
|
||||||
mov ax , ISR_FIFOOVW or ISR_RXOVW
|
mov ax , ISR_FIFOOVW or ISR_RXOVW
|
||||||
out dx , ax
|
out dx , ax
|
||||||
pop ax
|
pop ax
|
||||||
|
|
||||||
;----------------------------------------------------
|
;----------------------------------------------------
|
||||||
; Packet underrun? ?
|
; Packet underrun?
|
||||||
|
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
test ax, ISR_PUN
|
test ax, ISR_PUN
|
||||||
jz @f
|
jz @f
|
||||||
@ -993,23 +981,21 @@ int_handler:
|
|||||||
|
|
||||||
;----------------------------------------------------
|
;----------------------------------------------------
|
||||||
; Receive FIFO overflow ?
|
; Receive FIFO overflow ?
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
test ax, ISR_FIFOOVW
|
test ax, ISR_FIFOOVW
|
||||||
jz @f
|
jz @f
|
||||||
|
|
||||||
push ax
|
push ax
|
||||||
DEBUGF 2,"RX fifo overflox!\n"
|
DEBUGF 2,"RX fifo overflow!\n"
|
||||||
|
|
||||||
mov edx, [device.io_addr]
|
set_io 0
|
||||||
add edx, REG_ISR
|
set_io REG_ISR
|
||||||
mov ax , ISR_FIFOOVW or ISR_RXOVW
|
mov ax , ISR_FIFOOVW or ISR_RXOVW
|
||||||
out dx , ax
|
out dx , ax
|
||||||
pop ax
|
pop ax
|
||||||
|
|
||||||
;----------------------------------------------------
|
;----------------------------------------------------
|
||||||
; Something about Cable changed ?
|
; Something about Cable changed ?
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
test ax, ISR_LENCHG
|
test ax, ISR_LENCHG
|
||||||
jz .fail
|
jz .fail
|
||||||
@ -1017,11 +1003,7 @@ int_handler:
|
|||||||
DEBUGF 2,"Cable changed!\n"
|
DEBUGF 2,"Cable changed!\n"
|
||||||
call cable
|
call cable
|
||||||
|
|
||||||
; If none of the above events happened, just exit clearing int
|
|
||||||
|
|
||||||
.fail:
|
.fail:
|
||||||
|
|
||||||
DEBUGF 1,"\n"
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
@ -1213,47 +1195,48 @@ read_eeprom:
|
|||||||
|
|
||||||
; End of code
|
; End of code
|
||||||
|
|
||||||
|
section '.data' data readable writable align 16 ; place all uninitialized data place here
|
||||||
align 4 ; Place all initialised data here
|
align 4 ; Place all initialised data here
|
||||||
|
|
||||||
RTL8139_DEV dd 0
|
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 'RTL8139',0 ; max 16 chars include zero
|
my_service db 'RTL8139',0 ; max 16 chars include zero
|
||||||
|
|
||||||
device_1 db 'Realtek 8139',0
|
device_1 db 'Realtek 8139',0
|
||||||
device_2 db 'Realtek 8139A',0
|
device_2 db 'Realtek 8139A',0
|
||||||
device_3 db 'Realtek 8139B',0
|
device_3 db 'Realtek 8139B',0
|
||||||
device_4 db 'Realtek 8139C',0
|
device_4 db 'Realtek 8139C',0
|
||||||
device_5 db 'Realtek 8100',0
|
device_5 db 'Realtek 8100',0
|
||||||
device_6 db 'Realtek 8139D',0
|
device_6 db 'Realtek 8139D',0
|
||||||
device_7 db 'Realtek 8139CP',0
|
device_7 db 'Realtek 8139CP',0
|
||||||
device_8 db 'Realtek 8101',0
|
device_8 db 'Realtek 8101',0
|
||||||
device_unknown db 'Unknown RTL8139 clone', 0
|
device_unknown db 'Unknown RTL8139 clone', 0
|
||||||
|
|
||||||
crosslist dd device_1
|
crosslist:
|
||||||
dd device_2
|
dd device_1
|
||||||
dd device_3
|
dd device_2
|
||||||
dd device_4
|
dd device_3
|
||||||
dd device_5
|
dd device_4
|
||||||
dd device_6
|
dd device_5
|
||||||
dd device_7
|
dd device_6
|
||||||
dd device_8
|
dd device_7
|
||||||
dd device_unknown
|
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_RTL8139A
|
db VER_RTL8139
|
||||||
db VER_RTL8139B
|
db VER_RTL8139A
|
||||||
db VER_RTL8139C
|
db VER_RTL8139B
|
||||||
db VER_RTL8100
|
db VER_RTL8139C
|
||||||
db VER_RTL8139D
|
db VER_RTL8100
|
||||||
db VER_RTL8139CP
|
db VER_RTL8139D
|
||||||
db VER_RTL8101
|
db VER_RTL8139CP
|
||||||
db 0
|
db VER_RTL8101
|
||||||
|
db 0
|
||||||
|
|
||||||
HW_VER_ARRAY_SIZE = $-hw_ver_array
|
HW_VER_ARRAY_SIZE = $-hw_ver_array
|
||||||
|
|
||||||
include_debug_strings ; All data wich FDO uses will be included here
|
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
|
||||||
|
|
||||||
RTL8139_LIST rd MAX_RTL8139 ; This list contains all pointers to device structures the driver is handling
|
|
||||||
|
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; 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 ;;
|
;; Distributed under terms of the GNU General Public License ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; DEC 21x4x driver for KolibriOS ;;
|
;; DEC 21x4x driver for KolibriOS ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; Based on dec21140.Asm from Solar OS by ;;
|
;; Based on dec21140.Asm from Solar OS by ;;
|
||||||
;; Eugen Brasoveanu, ;;
|
;; Eugen Brasoveanu, ;;
|
||||||
;; Ontanu Bogdan Valentin ;;
|
;; Ontanu Bogdan Valentin ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; Written by hidnplayr@kolibrios.org ;;
|
;; Written by hidnplayr@kolibrios.org ;;
|
||||||
;; ;;
|
|
||||||
;; 0.1 - 5 june 2010 ;;
|
|
||||||
;; ;;
|
;; ;;
|
||||||
;; GNU GENERAL PUBLIC LICENSE ;;
|
;; GNU GENERAL PUBLIC LICENSE ;;
|
||||||
;; Version 2, June 1991 ;;
|
;; Version 2, June 1991 ;;
|
||||||
@ -21,6 +19,9 @@
|
|||||||
format MS COFF
|
format MS COFF
|
||||||
|
|
||||||
API_VERSION equ 0x01000100
|
API_VERSION equ 0x01000100
|
||||||
|
DRIVER_VERSION equ 5
|
||||||
|
|
||||||
|
MAX_DEVICES equ 16
|
||||||
|
|
||||||
DEBUG equ 1
|
DEBUG equ 1
|
||||||
__DEBUG__ equ 1
|
__DEBUG__ equ 1
|
||||||
@ -31,42 +32,32 @@ include 'imports.inc'
|
|||||||
include 'fdo.inc'
|
include 'fdo.inc'
|
||||||
include 'netdrv.inc'
|
include 'netdrv.inc'
|
||||||
|
|
||||||
OS_BASE equ 0
|
|
||||||
new_app_base equ 0x60400000
|
|
||||||
PROC_BASE equ OS_BASE+0x0080000
|
|
||||||
|
|
||||||
public START
|
public START
|
||||||
public service_proc
|
public service_proc
|
||||||
public version
|
public version
|
||||||
|
|
||||||
|
|
||||||
virtual at ebx
|
virtual at ebx
|
||||||
|
|
||||||
device:
|
device:
|
||||||
|
|
||||||
ETH_DEVICE
|
ETH_DEVICE
|
||||||
|
|
||||||
; device specific
|
.rx_p_des dd ? ; descriptors ring with received packets
|
||||||
.rx_p_des dd ? ; descriptors ring with received packets
|
.tx_p_des dd ? ; descriptors ring with 'to transmit' packets
|
||||||
.tx_p_des dd ? ; descriptors ring with 'to transmit' packets
|
.tx_free_des dd ? ; Tx descriptors available
|
||||||
.tx_free_des dd ? ; Tx descriptors available
|
.tx_wr_des dd ? ; Tx current descriptor to write data to
|
||||||
.tx_wr_des dd ? ; Tx current descriptor to write data to
|
.tx_rd_des dd ? ; Tx current descriptor to read TX completion
|
||||||
.tx_rd_des dd ? ; Tx current descriptor to read TX completion
|
.rx_crt_des dd ? ; Rx current descriptor
|
||||||
.rx_crt_des dd ? ; Rx current descriptor
|
|
||||||
|
|
||||||
.io_addr dd ?
|
.io_addr dd ?
|
||||||
.pci_bus db ?
|
.pci_bus db ?
|
||||||
.pci_dev db ?
|
.pci_dev db ?
|
||||||
.irq_line db ?
|
.irq_line db ?
|
||||||
|
|
||||||
.size = $ - device
|
.size = $ - device
|
||||||
|
|
||||||
end virtual
|
end virtual
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
MAX_DEVICES equ 16
|
|
||||||
|
|
||||||
;-------------------------------------------
|
;-------------------------------------------
|
||||||
; configuration registers
|
; configuration registers
|
||||||
;-------------------------------------------
|
;-------------------------------------------
|
||||||
@ -381,7 +372,7 @@ proc service_proc stdcall, ioctl:dword
|
|||||||
|
|
||||||
; check if the device is already listed
|
; check if the device is already listed
|
||||||
|
|
||||||
mov esi, DEVICE_LIST
|
mov esi, device_list
|
||||||
mov ecx, [devices]
|
mov ecx, [devices]
|
||||||
test ecx, ecx
|
test ecx, ecx
|
||||||
jz .firstdevice
|
jz .firstdevice
|
||||||
@ -442,7 +433,7 @@ proc service_proc stdcall, ioctl:dword
|
|||||||
; Ok, the eth_device structure is ready, let's probe the device
|
; Ok, the eth_device structure is ready, let's probe the device
|
||||||
; Because initialization fires IRQ, IRQ handler must be aware of this 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 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] ;
|
inc [devices] ;
|
||||||
|
|
||||||
call probe ; this function will output in eax
|
call probe ; this function will output in eax
|
||||||
@ -771,6 +762,9 @@ reset:
|
|||||||
mov ecx, 6
|
mov ecx, 6
|
||||||
rep stosd
|
rep stosd
|
||||||
|
|
||||||
|
; Set the mtu, kernel will be able to send now
|
||||||
|
mov [device.mtu], 1514
|
||||||
|
|
||||||
DEBUGF 1,"Reset done\n"
|
DEBUGF 1,"Reset done\n"
|
||||||
|
|
||||||
ret
|
ret
|
||||||
@ -1000,15 +994,18 @@ transmit:
|
|||||||
|
|
||||||
DEBUGF 1,"transmit ok\n"
|
DEBUGF 1,"transmit ok\n"
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
|
call Kernelfree
|
||||||
|
add esp, 4
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.fail:
|
.fail:
|
||||||
DEBUGF 1,"transmit failed\n"
|
DEBUGF 1,"transmit failed\n"
|
||||||
or eax, -1
|
or eax, -1
|
||||||
|
call Kernelfree
|
||||||
|
add esp, 4
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; Interrupt handler ;;
|
;; Interrupt handler ;;
|
||||||
@ -1025,7 +1022,7 @@ int_handler:
|
|||||||
mov ecx, [devices]
|
mov ecx, [devices]
|
||||||
test ecx, ecx
|
test ecx, ecx
|
||||||
jz .fail
|
jz .fail
|
||||||
mov esi, DEVICE_LIST
|
mov esi, device_list
|
||||||
.nextdevice:
|
.nextdevice:
|
||||||
mov ebx, dword [esi]
|
mov ebx, dword [esi]
|
||||||
|
|
||||||
@ -1701,17 +1698,16 @@ mdio_write: ;int phy_id: edx, int location: edi, int value: ax)
|
|||||||
|
|
||||||
|
|
||||||
; End of code
|
; End of code
|
||||||
|
|
||||||
align 4 ; Place all initialised data here
|
align 4 ; Place all initialised data here
|
||||||
|
|
||||||
devices dd 0
|
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
|
my_service db 'DEC21X4X',0 ; max 16 chars include zero
|
||||||
|
|
||||||
include_debug_strings ; All data wich FDO uses will be included here
|
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
|
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 {
|
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 {
|
;struc ETH_DEVICE {
|
||||||
macro ETH_DEVICE {
|
macro ETH_DEVICE {
|
||||||
NET_DEVICE
|
NET_DEVICE
|
||||||
; pointers to procedures
|
|
||||||
.unload dd ?
|
.set_mode dd ?
|
||||||
.reset dd ?
|
.get_mode dd ?
|
||||||
.transmit dd ?
|
|
||||||
.set_MAC dd ?
|
.set_MAC dd ?
|
||||||
.get_MAC dd ?
|
.get_MAC dd ?
|
||||||
.set_mode dd ?
|
|
||||||
.get_mode dd ?
|
.mode dd ?
|
||||||
; status
|
.mac dp ?
|
||||||
.bytes_tx dq ?
|
dp ? ; qword alignment
|
||||||
.bytes_rx dq ?
|
|
||||||
.packets_tx dd ?
|
|
||||||
.packets_rx dd ?
|
|
||||||
.mode dd ?
|
|
||||||
.name dd ?
|
|
||||||
.mac dp ?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
macro SLIP_DEVICE {
|
macro SLIP_DEVICE {
|
||||||
NET_DEVICE
|
NET_DEVICE
|
||||||
; pointers to procedures
|
|
||||||
.unload dd ?
|
|
||||||
.reset dd ?
|
|
||||||
.transmit dd ?
|
|
||||||
.set_mode dd ?
|
.set_mode dd ?
|
||||||
.get_mode dd ?
|
.get_mode dd ?
|
||||||
; status
|
|
||||||
.bytes_tx dq ?
|
|
||||||
.bytes_rx dq ?
|
|
||||||
.packets_tx dd ?
|
|
||||||
.packets_rx dd ?
|
|
||||||
.mode dd ?
|
.mode dd ?
|
||||||
.name dd ?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro GetRealAddr {
|
macro GetRealAddr {
|
||||||
@ -235,7 +237,7 @@ macro GetRealAddr {
|
|||||||
push eax
|
push eax
|
||||||
call GetPgAddr
|
call GetPgAddr
|
||||||
and dword [esp], (PAGESIZE - 1)
|
and dword [esp], (PAGESIZE - 1)
|
||||||
add eax, dword [esp]
|
or eax, dword [esp]
|
||||||
add esp, 4
|
add esp, 4
|
||||||
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -112,7 +112,7 @@ ARP_init:
|
|||||||
;
|
;
|
||||||
; This function resets all ARP variables
|
; This function resets all ARP variables
|
||||||
;
|
;
|
||||||
; IN: eax = IPv4 address
|
; IN: eax = IPv4 address
|
||||||
; OUT: eax = -1 on error, else eax = first two bytes of mac
|
; OUT: eax = -1 on error, else eax = first two bytes of mac
|
||||||
; ( high 16 bits are zero)
|
; ( high 16 bits are zero)
|
||||||
; ebx = last four bytes of mac ; TODO: special eax value for 'request send'
|
; ebx = last four bytes of mac ; TODO: special eax value for 'request send'
|
||||||
@ -130,18 +130,18 @@ ARP_IP_to_MAC:
|
|||||||
; else
|
; else
|
||||||
; destination is remote, so pass to gateway
|
; 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]
|
mov ebx, [IP_LIST + edx]
|
||||||
and ebx, [SUBNET_LIST+edx]
|
and ebx, [SUBNET_LIST + edx]
|
||||||
|
|
||||||
mov ecx, eax
|
mov ecx, eax
|
||||||
and ecx, [SUBNET_LIST+edx]
|
and ecx, [SUBNET_LIST + edx]
|
||||||
|
|
||||||
cmp ecx, ebx
|
cmp ecx, ebx
|
||||||
je .local
|
je .local
|
||||||
|
|
||||||
mov eax, [GATEWAY_LIST+edx]
|
mov eax, [GATEWAY_LIST + edx]
|
||||||
DEBUGF 1,"requested IP is not on subnet, using gateway\n"
|
DEBUGF 1,"requested IP is not on subnet, using gateway\n"
|
||||||
|
|
||||||
.local:
|
.local:
|
||||||
@ -274,7 +274,8 @@ ARP_create_request:
|
|||||||
DEBUGF 1,"ARP Packet for device %x created successfully\n", ebx
|
DEBUGF 1,"ARP Packet for device %x created successfully\n", ebx
|
||||||
|
|
||||||
push edx ecx
|
push edx ecx
|
||||||
jmp NET_send
|
call [ebx + NET_DEVICE.transmit]
|
||||||
|
ret
|
||||||
|
|
||||||
.exit:
|
.exit:
|
||||||
add esp, 8
|
add esp, 8
|
||||||
@ -572,7 +573,8 @@ ARP_handler:
|
|||||||
|
|
||||||
DEBUGF 1,"ARP_Handler - Sending reply \n"
|
DEBUGF 1,"ARP_Handler - Sending reply \n"
|
||||||
|
|
||||||
jmp NET_send ; And send it!
|
call [ebx + NET_DEVICE.transmit]
|
||||||
|
ret
|
||||||
|
|
||||||
.exit:
|
.exit:
|
||||||
call kernel_free
|
call kernel_free
|
||||||
|
@ -172,10 +172,10 @@ IPv4_handler: ; TODO: implement handler for IP options
|
|||||||
cmp [edx + IPv4_Packet.DestinationAddress], -1
|
cmp [edx + IPv4_Packet.DestinationAddress], -1
|
||||||
je .ip_ok
|
je .ip_ok
|
||||||
|
|
||||||
; ; maybe it's a multicast then
|
; maybe it's a multicast then
|
||||||
;
|
|
||||||
; mov eax, [edx + IPv4_Packet.DestinationAddress]
|
mov eax, [edx + IPv4_Packet.DestinationAddress]
|
||||||
; and eax, 0xff000000
|
and eax, 0xff000000
|
||||||
; cmp eax, 224 shl 24
|
; cmp eax, 224 shl 24
|
||||||
; je .ip_ok
|
; je .ip_ok
|
||||||
|
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
$Revision$
|
$Revision$
|
||||||
|
|
||||||
ETH_QUEUE_SIZE equ 16
|
|
||||||
|
|
||||||
struct ETH_FRAME
|
struct ETH_FRAME
|
||||||
.DstMAC dp ? ; destination MAC-address
|
.DstMAC dp ? ; destination MAC-address
|
||||||
.SrcMAC dp ? ; source MAC-address
|
.SrcMAC dp ? ; source MAC-address
|
||||||
@ -28,20 +26,14 @@ ends
|
|||||||
virtual at NET_DEVICE.end
|
virtual at NET_DEVICE.end
|
||||||
|
|
||||||
ETH_DEVICE:
|
ETH_DEVICE:
|
||||||
.unload dd ?
|
|
||||||
.reset dd ?
|
|
||||||
.transmit dd ?
|
|
||||||
.set_MAC dd ?
|
|
||||||
.get_MAC dd ?
|
|
||||||
.set_mode dd ?
|
.set_mode dd ?
|
||||||
.get_mode dd ?
|
.get_mode dd ?
|
||||||
|
|
||||||
.bytes_tx dq ?
|
.set_MAC dd ?
|
||||||
.bytes_rx dq ?
|
.get_MAC dd ?
|
||||||
.packets_tx dd ?
|
|
||||||
.packets_rx dd ?
|
|
||||||
.mode dd ?
|
.mode dd ?
|
||||||
.name dd ?
|
|
||||||
.mac dp ?
|
.mac dp ?
|
||||||
|
|
||||||
end virtual
|
end virtual
|
||||||
@ -108,6 +100,9 @@ ETH_receiver:
|
|||||||
cmp ax, ETHER_ARP
|
cmp ax, ETHER_ARP
|
||||||
je ARP_handler
|
je ARP_handler
|
||||||
|
|
||||||
|
; cmp ax, ETHER_PPP_DISCOVERY
|
||||||
|
; je PPPOE_discovery
|
||||||
|
|
||||||
DEBUGF 2,"Unknown ethernet packet type %x\n", ax
|
DEBUGF 2,"Unknown ethernet packet type %x\n", ax
|
||||||
|
|
||||||
.dump:
|
.dump:
|
||||||
@ -138,7 +133,10 @@ ETH_create_packet:
|
|||||||
|
|
||||||
DEBUGF 1,"Creating Ethernet Packet (size=%u): \n", ecx
|
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
|
jg .exit
|
||||||
|
|
||||||
push ecx di eax ebx edx
|
push ecx di eax ebx edx
|
||||||
@ -171,7 +169,7 @@ ETH_create_packet:
|
|||||||
mov ebx, [NET_DRV_LIST + ebx]
|
mov ebx, [NET_DRV_LIST + ebx]
|
||||||
|
|
||||||
cmp edx, 46 + ETH_FRAME.Data ; If data size is less then 46, add padding bytes
|
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
|
mov edx, 46 + ETH_FRAME.Data
|
||||||
.continue:
|
.continue:
|
||||||
|
|
||||||
@ -240,23 +238,23 @@ ETH_API:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
.packets_tx:
|
.packets_tx:
|
||||||
mov eax, dword [eax + ETH_DEVICE.packets_tx]
|
mov eax, dword [eax + NET_DEVICE.packets_tx]
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.packets_rx:
|
.packets_rx:
|
||||||
mov eax, dword [eax + ETH_DEVICE.packets_rx]
|
mov eax, dword [eax + NET_DEVICE.packets_rx]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.bytes_tx:
|
.bytes_tx:
|
||||||
mov ebx, dword [eax + ETH_DEVICE.bytes_tx + 4]
|
mov ebx, dword [eax + NET_DEVICE.bytes_tx + 4]
|
||||||
mov eax, dword [eax + ETH_DEVICE.bytes_tx]
|
mov eax, dword [eax + NET_DEVICE.bytes_tx]
|
||||||
mov [esp+20+4], ebx ; TODO: fix this ugly code
|
mov [esp+20+4], ebx ; TODO: fix this ugly code
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.bytes_rx:
|
.bytes_rx:
|
||||||
mov ebx, dword [eax + ETH_DEVICE.bytes_rx + 4]
|
mov ebx, dword [eax + NET_DEVICE.bytes_rx + 4]
|
||||||
mov eax, dword [eax + ETH_DEVICE.bytes_rx]
|
mov eax, dword [eax + NET_DEVICE.bytes_rx]
|
||||||
mov [esp+20+4], ebx ; TODO: fix this ugly code
|
mov [esp+20+4], ebx ; TODO: fix this ugly code
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -270,8 +268,7 @@ ETH_API:
|
|||||||
.write_mac:
|
.write_mac:
|
||||||
push ecx
|
push ecx
|
||||||
push dx
|
push dx
|
||||||
mov eax, [eax + ETH_DEVICE.set_MAC]
|
call [eax + ETH_DEVICE.set_MAC]
|
||||||
call eax
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.in_queue:
|
.in_queue:
|
||||||
|
@ -209,8 +209,8 @@ ICMP_input:
|
|||||||
pop ecx edx ebx
|
pop ecx edx ebx
|
||||||
mov word [edx + ICMP_Packet.Checksum], ax
|
mov word [edx + ICMP_Packet.Checksum], ax
|
||||||
|
|
||||||
jmp NET_send ; Send the reply
|
call [ebx + NET_DEVICE.transmit]
|
||||||
; and return to caller of this proc
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -251,7 +251,7 @@ ICMP_input:
|
|||||||
add esp, 4
|
add esp, 4
|
||||||
sub edx, esi
|
sub edx, esi
|
||||||
mov edi, edx
|
mov edi, edx
|
||||||
;;; jmp SOCKET_input
|
jmp SOCKET_input
|
||||||
|
|
||||||
.dump:
|
.dump:
|
||||||
DEBUGF 1,"ICMP_Handler - dumping\n"
|
DEBUGF 1,"ICMP_Handler - dumping\n"
|
||||||
@ -264,24 +264,22 @@ ICMP_input:
|
|||||||
|
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
;
|
;
|
||||||
; Note: ICMP only works on top of IP protocol :)
|
; ICMP_output
|
||||||
;
|
;
|
||||||
; inputs:
|
; IN: eax = dest ip
|
||||||
;
|
; ebx = source ip
|
||||||
; eax = dest ip
|
; ecx = data length
|
||||||
; ebx = source ip
|
; dh = type
|
||||||
; ecx = data length
|
; dl = code
|
||||||
; dh = type
|
; high 16 bits of edx = fragment id (for IP header)
|
||||||
; dl = code
|
; esi = data offset
|
||||||
; high 16 bits of edx = fragment id (for IP header)
|
; edi = identifier shl 16 + sequence number
|
||||||
; esi = data offset
|
|
||||||
; edi = identifier shl 16 + sequence number
|
|
||||||
;
|
;
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
align 4
|
align 4
|
||||||
ICMP_output:
|
ICMP_output:
|
||||||
|
|
||||||
DEBUGF 1,"Create ICMP Packet\n"
|
DEBUGF 1,"Creating ICMP Packet\n"
|
||||||
|
|
||||||
push esi edi edx
|
push esi edi edx
|
||||||
|
|
||||||
@ -292,7 +290,7 @@ ICMP_output:
|
|||||||
call IPv4_create_packet
|
call IPv4_create_packet
|
||||||
jz .exit
|
jz .exit
|
||||||
|
|
||||||
DEBUGF 1,"full icmp packet size: %u\n", edx
|
DEBUGF 1,"full icmp packet size: %u\n", edx
|
||||||
|
|
||||||
pop eax
|
pop eax
|
||||||
mov word [edi + ICMP_Packet.Type], ax ; Write both type and code bytes at once
|
mov word [edi + ICMP_Packet.Type], ax ; Write both type and code bytes at once
|
||||||
@ -320,13 +318,12 @@ ICMP_output:
|
|||||||
rep movsb
|
rep movsb
|
||||||
|
|
||||||
sub edi, edx ;;; TODO: find a better way to remember start of packet
|
sub edi, edx ;;; TODO: find a better way to remember start of packet
|
||||||
mov ecx, [ebx + ETH_DEVICE.transmit]
|
push edx edi
|
||||||
push edx edi ecx
|
DEBUGF 1,"Sending ICMP Packet\n"
|
||||||
DEBUGF 1,"Sending ICMP Packet\n"
|
call [ebx + NET_DEVICE.transmit]
|
||||||
ret ; Send the packet (create_packet routine outputs pointer to routine to send packet in eax)
|
ret
|
||||||
|
|
||||||
.exit:
|
.exit:
|
||||||
DEBUGF 1,"Creating ICMP Packet failed\n"
|
DEBUGF 1,"Creating ICMP Packet failed\n"
|
||||||
add esp, 3*4
|
add esp, 3*4
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -74,7 +74,6 @@ virtual at IP_SOCKET.end
|
|||||||
.OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state)
|
.OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state)
|
||||||
|
|
||||||
.t_state dd ? ; TCB state
|
.t_state dd ? ; TCB state
|
||||||
.t_timer dd ? ; TCB timer (seconds)
|
|
||||||
.t_rxtshift dd ?
|
.t_rxtshift dd ?
|
||||||
.t_rxtcur dd ?
|
.t_rxtcur dd ?
|
||||||
.t_dupacks dd ?
|
.t_dupacks dd ?
|
||||||
@ -144,6 +143,16 @@ virtual at IP_SOCKET.end
|
|||||||
.ts_recent_age dd ?
|
.ts_recent_age dd ?
|
||||||
.last_ack_sent 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:
|
||||||
end virtual
|
end virtual
|
||||||
|
|
||||||
@ -335,7 +344,7 @@ SOCKET_bind:
|
|||||||
jz s_error
|
jz s_error
|
||||||
|
|
||||||
.got_port:
|
.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 word [eax + UDP_SOCKET.LocalPort], bx
|
||||||
|
|
||||||
mov ebx, dword [edx + 4]
|
mov ebx, dword [edx + 4]
|
||||||
@ -391,7 +400,7 @@ SOCKET_connect:
|
|||||||
mov bx , word [edx + 2]
|
mov bx , word [edx + 2]
|
||||||
mov word [eax + UDP_SOCKET.RemotePort], bx
|
mov word [eax + UDP_SOCKET.RemotePort], bx
|
||||||
mov [eax + UDP_SOCKET.firstpacket], 0
|
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 ebx, dword [edx + 4]
|
||||||
mov dword [eax + IP_SOCKET.RemoteIP], ebx
|
mov dword [eax + IP_SOCKET.RemoteIP], ebx
|
||||||
@ -408,6 +417,8 @@ SOCKET_connect:
|
|||||||
add [TCP_sequence_num], 6400
|
add [TCP_sequence_num], 6400
|
||||||
mov [eax + TCP_SOCKET.ISS], ebx
|
mov [eax + TCP_SOCKET.ISS], ebx
|
||||||
|
|
||||||
|
mov [eax + TCP_SOCKET.timer_keepalive], 120 ; 120*630ms => 75,6 seconds
|
||||||
|
|
||||||
lea ebx, [eax + SOCKET.lock]
|
lea ebx, [eax + SOCKET.lock]
|
||||||
call wait_mutex
|
call wait_mutex
|
||||||
|
|
||||||
@ -417,7 +428,7 @@ SOCKET_connect:
|
|||||||
|
|
||||||
mov bx , word [edx + 2]
|
mov bx , word [edx + 2]
|
||||||
mov [eax + TCP_SOCKET.RemotePort], bx
|
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 ebx, dword [edx + 4]
|
||||||
mov [eax + IP_SOCKET.RemoteIP], ebx
|
mov [eax + IP_SOCKET.RemoteIP], ebx
|
||||||
@ -435,6 +446,8 @@ SOCKET_connect:
|
|||||||
call SOCKET_find_port
|
call SOCKET_find_port
|
||||||
@@:
|
@@:
|
||||||
|
|
||||||
|
DEBUGF 1,"remote port: %u\n", [eax + TCP_SOCKET.LocalPort]:2
|
||||||
|
|
||||||
; mov [eax + TCP_SOCKET.t_state], TCB_SYN_SENT
|
; mov [eax + TCP_SOCKET.t_state], TCB_SYN_SENT
|
||||||
call TCP_output
|
call TCP_output
|
||||||
|
|
||||||
|
@ -35,8 +35,10 @@ MIN_EPHEMERAL_PORT equ 49152
|
|||||||
MAX_EPHEMERAL_PORT equ 61000
|
MAX_EPHEMERAL_PORT equ 61000
|
||||||
|
|
||||||
; Ethernet protocol numbers
|
; Ethernet protocol numbers
|
||||||
ETHER_ARP equ 0x0608
|
ETHER_ARP equ 0x0608
|
||||||
ETHER_IPv4 equ 0x0008 ; Reversed from 0800 for intel
|
ETHER_IPv4 equ 0x0008 ; Reversed from 0800 for intel
|
||||||
|
ETHER_PPP_DISCOVERY equ 0x6388
|
||||||
|
ETHER_PPP_SESSION equ 0x6488
|
||||||
|
|
||||||
;Protocol family
|
;Protocol family
|
||||||
AF_UNSPEC equ 0
|
AF_UNSPEC equ 0
|
||||||
@ -76,7 +78,20 @@ NET_TYPE_SLIP equ 2
|
|||||||
virtual at 0
|
virtual at 0
|
||||||
|
|
||||||
NET_DEVICE:
|
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:
|
||||||
|
|
||||||
end virtual
|
end virtual
|
||||||
@ -193,26 +208,17 @@ stack_handler:
|
|||||||
je .exit
|
je .exit
|
||||||
mov [net_10ms], eax
|
mov [net_10ms], eax
|
||||||
|
|
||||||
if ETH_QUEUE
|
test [net_10ms], 0x0f ; 160ms
|
||||||
call ETH_handler
|
jnz .exit
|
||||||
call ETH_send_queued
|
|
||||||
end if
|
|
||||||
call TCP_10ms
|
|
||||||
|
|
||||||
inc [net_tmr_count]
|
; call TCP_timer_160ms
|
||||||
cmp [net_tmr_count], 50
|
|
||||||
je .500ms
|
|
||||||
cmp [net_tmr_count], 100
|
|
||||||
jne .exit
|
|
||||||
|
|
||||||
|
test [net_10ms], 0x3f ; 640ms
|
||||||
|
jnz .exit
|
||||||
|
|
||||||
|
; call TCP_timer_640ms
|
||||||
call ARP_decrease_entry_ttls
|
call ARP_decrease_entry_ttls
|
||||||
call IPv4_decrease_fragment_ttls
|
call IPv4_decrease_fragment_ttls
|
||||||
call TCP_timer_1000ms
|
|
||||||
|
|
||||||
mov [net_tmr_count], 0
|
|
||||||
|
|
||||||
.500ms:
|
|
||||||
call TCP_500ms
|
|
||||||
|
|
||||||
.exit:
|
.exit:
|
||||||
ret
|
ret
|
||||||
@ -380,34 +386,6 @@ NET_ptr_to_num:
|
|||||||
pop ecx
|
pop ecx
|
||||||
ret
|
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
|
; checksum_1
|
||||||
@ -563,7 +541,7 @@ sys_network:
|
|||||||
jnz @f
|
jnz @f
|
||||||
|
|
||||||
mov esi, [esi + NET_DRV_LIST]
|
mov esi, [esi + NET_DRV_LIST]
|
||||||
mov esi, [esi + ETH_DEVICE.name]
|
mov esi, [esi + NET_DEVICE.name]
|
||||||
mov edi, ecx
|
mov edi, ecx
|
||||||
|
|
||||||
mov ecx, 64 ; max length
|
mov ecx, 64 ; max length
|
||||||
@ -578,7 +556,7 @@ sys_network:
|
|||||||
jnz @f
|
jnz @f
|
||||||
|
|
||||||
mov esi, [esi + NET_DRV_LIST]
|
mov esi, [esi + NET_DRV_LIST]
|
||||||
call [esi + ETH_DEVICE.reset]
|
call [esi + NET_DEVICE.reset]
|
||||||
jmp .return
|
jmp .return
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
@ -587,7 +565,7 @@ sys_network:
|
|||||||
jnz @f
|
jnz @f
|
||||||
|
|
||||||
mov esi, [esi + NET_DRV_LIST]
|
mov esi, [esi + NET_DRV_LIST]
|
||||||
call [esi + ETH_DEVICE.unload]
|
call [esi + NET_DEVICE.unload]
|
||||||
jmp .return
|
jmp .return
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
@ -645,13 +623,13 @@ sys_protocols:
|
|||||||
cmp ax , ETHER_ARP
|
cmp ax , ETHER_ARP
|
||||||
je ARP_API
|
je ARP_API
|
||||||
|
|
||||||
cmp ax , 1337
|
cmp ax , 1337 ;;;;;
|
||||||
je ETH_API
|
je ETH_API
|
||||||
|
|
||||||
add esp, 4 ; if we reached here, no function was called, so we need to balance stack
|
add esp, 4 ; if we reached here, no function was called, so we need to balance stack
|
||||||
|
|
||||||
.doesnt_exist:
|
.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
|
mov eax, -1
|
||||||
|
|
||||||
.return:
|
.return:
|
||||||
|
@ -58,6 +58,22 @@ TCP_OPT_MAXSEG equ 2 ; Maximum Segment Size.
|
|||||||
TCP_OPT_WINDOW equ 3 ; window scale
|
TCP_OPT_WINDOW equ 3 ; window scale
|
||||||
TCP_OPT_TIMESTAMP equ 8
|
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
|
struct TCP_segment
|
||||||
.SourcePort dw ?
|
.SourcePort dw ?
|
||||||
.DestinationPort dw ?
|
.DestinationPort dw ?
|
||||||
@ -113,24 +129,56 @@ TCP_init:
|
|||||||
mov ecx, (6*IP_MAX_INTERFACES)
|
mov ecx, (6*IP_MAX_INTERFACES)
|
||||||
rep stosd
|
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
|
ret
|
||||||
|
|
||||||
|
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
;
|
;
|
||||||
; decrease socket ttls
|
|
||||||
;
|
|
||||||
; IN: /
|
|
||||||
; OUT: /
|
|
||||||
;
|
|
||||||
; destroys: eax
|
|
||||||
;
|
;
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
align 4
|
align 4
|
||||||
TCP_timer_1000ms:
|
TCP_timer_640ms:
|
||||||
; scan through all the active TCP sockets, decrementing active timers
|
|
||||||
|
; 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
|
mov eax, net_sockets
|
||||||
.loop:
|
.loop:
|
||||||
@ -142,62 +190,40 @@ TCP_timer_1000ms:
|
|||||||
cmp [eax + SOCKET.Type], IP_PROTO_TCP
|
cmp [eax + SOCKET.Type], IP_PROTO_TCP
|
||||||
jne .loop
|
jne .loop
|
||||||
|
|
||||||
cmp [eax + TCP_SOCKET.t_timer], 0
|
dec [eax + TCP_SOCKET.timer_retransmission]
|
||||||
jne .decrement_tcb
|
jnz .check_more2
|
||||||
;;;;;; cmp [eax + TCP_SOCKET.wndsizeTimer], 0
|
|
||||||
jne .decrement_wnd
|
|
||||||
jmp .loop
|
|
||||||
|
|
||||||
.decrement_tcb:
|
DEBUGF 1,"socket %x: Retransmission timer expired\n", eax
|
||||||
; decrement it, delete socket if TCB timer = 0 & socket in timewait state
|
|
||||||
dec [eax + TCP_SOCKET.t_timer]
|
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
|
jnz .loop
|
||||||
|
|
||||||
cmp [eax + TCP_SOCKET.t_state], TCB_TIMED_WAIT
|
DEBUGF 1,"socket %x: persist timer expired\n", eax
|
||||||
jne .loop
|
|
||||||
|
|
||||||
push [eax + SOCKET.NextPtr]
|
|
||||||
call SOCKET_free
|
|
||||||
pop eax
|
|
||||||
jmp .check_only
|
|
||||||
|
|
||||||
.decrement_wnd:
|
|
||||||
;;;;;; dec [eax + TCP_SOCKET.wndsizeTimer]
|
|
||||||
|
|
||||||
|
jmp .loop
|
||||||
.exit:
|
.exit:
|
||||||
ret
|
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:
|
; TCP_input:
|
||||||
@ -374,8 +400,9 @@ TCP_input:
|
|||||||
;-------------------------------------
|
;-------------------------------------
|
||||||
; Reset idle timer and keepalive timer
|
; 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
|
; Process TCP options if not in LISTEN state
|
||||||
@ -475,13 +502,14 @@ TCP_input:
|
|||||||
; Delete acknowledged bytes from send buffer
|
; Delete acknowledged bytes from send buffer
|
||||||
|
|
||||||
; Stop retransmit timer
|
; Stop retransmit timer
|
||||||
|
mov [ebx + TCP_SOCKET.timer_ack], 0
|
||||||
|
|
||||||
; Awaken waiting processes
|
; Awaken waiting processes
|
||||||
|
mov eax, ebx
|
||||||
|
call SOCKET_notify_owner
|
||||||
|
|
||||||
; Generate more output
|
; Generate more output
|
||||||
|
call TCP_output
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
jmp .drop
|
jmp .drop
|
||||||
|
|
||||||
@ -518,8 +546,9 @@ TCP_input:
|
|||||||
add [ebx + TCP_SOCKET.RCV_NXT], ecx
|
add [ebx + TCP_SOCKET.RCV_NXT], ecx
|
||||||
|
|
||||||
; Add the data to the socket buffer
|
; Add the data to the socket buffer
|
||||||
|
mov eax, ebx
|
||||||
; The receiving process is awakened (by sorwakeup).
|
;;; mov...
|
||||||
|
call SOCKET_input
|
||||||
|
|
||||||
; The delayed-ACK flag is set and the input processing is complete.
|
; The delayed-ACK flag is set and the input processing is complete.
|
||||||
|
|
||||||
@ -679,8 +708,8 @@ align 4
|
|||||||
jle @f
|
jle @f
|
||||||
mov [ebx + TCP_SOCKET.SND_NXT], eax
|
mov [ebx + TCP_SOCKET.SND_NXT], eax
|
||||||
|
|
||||||
|
mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval
|
||||||
; TODO: turn off retransmission timer
|
mov [ebx + TCP_SOCKET.timer_retransmission], 0
|
||||||
|
|
||||||
mov eax, [edx + TCP_segment.SequenceNumber]
|
mov eax, [edx + TCP_segment.SequenceNumber]
|
||||||
mov [ebx + TCP_SOCKET.IRS], eax
|
mov [ebx + TCP_SOCKET.IRS], eax
|
||||||
@ -937,18 +966,6 @@ align 4
|
|||||||
jg .ack_dup
|
jg .ack_dup
|
||||||
jl .ack_nodup
|
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:
|
.ack_dup:
|
||||||
@ -960,7 +977,7 @@ align 4
|
|||||||
;;;; 887
|
;;;; 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
|
; for the other side's cached packets, retrace it
|
||||||
|
|
||||||
;;;; 888 - 902
|
;;;; 888 - 902
|
||||||
@ -971,6 +988,14 @@ align 4
|
|||||||
|
|
||||||
;;;;; 903 - 926
|
;;;;; 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
|
; Open congestion window in response to ACKs
|
||||||
@ -1428,7 +1453,7 @@ TCP_pull_out_of_band:
|
|||||||
;
|
;
|
||||||
; TCP_output
|
; TCP_output
|
||||||
;
|
;
|
||||||
; IN: eax = socket pointer
|
; IN: eax = socket pointer
|
||||||
;; esi = ptr to data
|
;; esi = ptr to data
|
||||||
;; ecx = number of data bytes
|
;; ecx = number of data bytes
|
||||||
;
|
;
|
||||||
@ -1614,7 +1639,7 @@ TCP_output:
|
|||||||
|
|
||||||
.enter_persist:
|
.enter_persist:
|
||||||
|
|
||||||
DEBUGF 1,"Entering pesist state\n"
|
DEBUGF 1,"Entering persist state\n"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1748,7 +1773,7 @@ TCP_output:
|
|||||||
;;;; jz .fail
|
;;;; jz .fail
|
||||||
|
|
||||||
push edx eax
|
push edx eax
|
||||||
call NET_send
|
call [ebx + NET_DEVICE.transmit]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;----------------
|
;----------------
|
||||||
@ -1831,12 +1856,9 @@ TCP_output:
|
|||||||
|
|
||||||
|
|
||||||
DEBUGF 1,"Sending TCP Packet to device %x\n", ebx
|
DEBUGF 1,"Sending TCP Packet to device %x\n", ebx
|
||||||
mov esi, [ebx + ETH_DEVICE.transmit]
|
call [ebx + NET_DEVICE.transmit]
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;-------------------------
|
;-------------------------
|
||||||
;
|
;
|
||||||
; TCP_outflags
|
; 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
|
; IN: eax = socket ptr
|
||||||
|
; -or-
|
||||||
|
; edx = packet ptr (eax must be 0)
|
||||||
|
; cl = flags
|
||||||
;
|
;
|
||||||
; OUT: /
|
; OUT: /
|
||||||
;
|
;
|
||||||
@ -1916,6 +1941,113 @@ TCP_respond:
|
|||||||
|
|
||||||
DEBUGF 1,"TCP_respond\n"
|
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
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
@ -252,8 +252,8 @@ UDP_output:
|
|||||||
|
|
||||||
DEBUGF 1,"Sending UDP Packet to device %x\n", ebx
|
DEBUGF 1,"Sending UDP Packet to device %x\n", ebx
|
||||||
|
|
||||||
jmp NET_send
|
call [ebx + NET_DEVICE.transmit]
|
||||||
|
ret
|
||||||
.fail:
|
.fail:
|
||||||
add esp, 8+8
|
add esp, 8+8
|
||||||
ret
|
ret
|
||||||
|
Loading…
Reference in New Issue
Block a user