Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 5049 → Rev 5050

/drivers/ethernet/RTL8169.asm
18,32 → 18,29
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
format MS COFF
format PE DLL native
entry START
 
API_VERSION = 0x01000100
DRIVER_VERSION = 5
CURRENT_API = 0x0200
COMPATIBLE_API = 0x0100
API_VERSION = (COMPATIBLE_API shl 16) + CURRENT_API
 
MAX_DEVICES = 16
 
DEBUG = 1
__DEBUG__ = 1
__DEBUG_LEVEL__ = 2
__DEBUG_LEVEL__ = 2 ; 1 = verbose, 2 = errors only
 
NUM_TX_DESC = 4
NUM_RX_DESC = 4
 
section '.flat' readable writable executable
 
include '../proc32.inc'
include '../struct.inc'
include '../macros.inc'
include '../proc32.inc'
include '../imports.inc'
include '../fdo.inc'
include '../netdrv.inc'
include '../netdrv_pe.inc'
 
public START
public service_proc
public version
 
 
REG_MAC0 = 0x0 ; Ethernet hardware address
REG_MAR0 = 0x8 ; Multicast filter
REG_TxDescStartAddr = 0x20
228,59 → 225,46
PCFG_METHOD_2 = 0x02 ; PHY Reg 0x03 bit0-3 == 0x0001
PCFG_METHOD_3 = 0x03 ; PHY Reg 0x03 bit0-3 == 0x0002
 
virtual at 0
tx_desc:
.status dd ?
.vlan_tag dd ?
.buf_addr dq ?
.size = $
rb (NUM_TX_DESC-1)*tx_desc.size
.buf_soft_addr dd ?
end virtual
struct tx_desc
status dd ?
vlan_tag dd ?
buf_addr dq ?
ends
tx_desc.buf_soft_addr = NUM_TX_DESC*sizeof.tx_desc
 
virtual at 0
rx_desc:
.status dd ?
.vlan_tag dd ?
.buf_addr dq ?
.size = $
rb (NUM_RX_DESC-1)*rx_desc.size
.buf_soft_addr dd ?
end virtual
struct rx_desc
status dd ?
vlan_tag dd ?
buf_addr dq ?
ends
rx_desc.buf_soft_addr = NUM_RX_DESC*sizeof.rx_desc
 
virtual at ebx
struct device ETH_DEVICE
 
device:
io_addr dd ?
pci_bus dd ?
pci_dev dd ?
irq_line db ?
rb 3 ; align 4
mmio_addr dd ? ; memory map physical address
chipset dd ?
pcfg dd ?
mcfg dd ?
cur_rx dd ? ; Index into the Rx descriptor buffer of next Rx pkt
cur_tx dd ? ; Index into the Tx descriptor buffer of next Rx pkt
TxDescArrays dd ? ; Index of Tx Descriptor buffer
RxDescArrays dd ? ; Index of Rx Descriptor buffer
TxDescArray dd ? ; Index of 256-alignment Tx Descriptor buffer
RxDescArray dd ? ; Index of 256-alignment Rx Descriptor buffer
 
ETH_DEVICE
rb 0x100-($ and 0xff) ; align 256
tx_ring rb NUM_TX_DESC * sizeof.tx_desc * 2
 
.io_addr dd ?
.pci_bus dd ?
.pci_dev dd ?
.irq_line db ?
rb 0x100-($ and 0xff) ; align 256
rx_ring rb NUM_RX_DESC * sizeof.rx_desc * 2
 
rb 256-(($ - device) and 255) ; align 256
.tx_ring rb NUM_TX_DESC * tx_desc.size * 2
ends
 
rb 256-(($ - device) and 255) ; align 256
.rx_ring rb NUM_RX_DESC * rx_desc.size * 2
 
tpc:
.mmio_addr dd ? ; memory map physical address
.chipset dd ?
.pcfg dd ?
.mcfg dd ?
.cur_rx dd ? ; Index into the Rx descriptor buffer of next Rx pkt
.cur_tx dd ? ; Index into the Tx descriptor buffer of next Rx pkt
.TxDescArrays dd ? ; Index of Tx Descriptor buffer
.RxDescArrays dd ? ; Index of Rx Descriptor buffer
.TxDescArray dd ? ; Index of 256-alignment Tx Descriptor buffer
.RxDescArray dd ? ; Index of 256-alignment Rx Descriptor buffer
 
device_size = $ - device
 
end virtual
 
intr_mask = ISB_LinkChg or ISB_RxOverflow or ISB_RxFIFOOver or ISB_TxErr or ISB_TxOK or ISB_RxErr or ISB_RxOK
rx_config = (RX_FIFO_THRESH shl RXC_FIFOShift) or (RX_DMA_BURST shl RXC_DMAShift) or 0x0000000E
 
289,7 → 273,7
 
push esi ecx
mov esi, msec
call Sleep
invoke Sleep
pop ecx esi
 
}
296,7 → 280,7
 
macro WRITE_GMII_REG RegAddr, value {
 
set_io REG_PHYAR
set_io [ebx + device.io_addr], REG_PHYAR
if value eq ax
and eax, 0x0000ffff
or eax, 0x80000000 + (RegAddr shl 16)
312,7 → 296,7
 
local .error, .done
 
set_io REG_PHYAR
set_io [ebx + device.io_addr], REG_PHYAR
mov eax, RegAddr shl 16
out dx, eax
 
366,8 → 350,6
 
 
 
section '.flat' code readable align 16
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; proc START ;;
375,20 → 357,16
;; (standard driver proc) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
proc START stdcall, state:dword
proc START c, reason:dword, cmdline:dword
 
cmp [state], 1
jne .exit
cmp [reason], DRV_ENTRY
jne .fail
 
.entry:
 
DEBUGF 2,"Loading %s driver\n", my_service
stdcall RegService, my_service, service_proc
DEBUGF 2,"Loading driver\n"
invoke RegService, my_service, service_proc
ret
 
.fail:
.exit:
xor eax, eax
ret
 
402,7 → 380,6
;; (standard driver proc) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
proc service_proc stdcall, ioctl:dword
 
mov edx, [ioctl]
444,9 → 421,9
mov ax, [eax+1] ;
.nextdevice:
mov ebx, [esi]
cmp al, byte[device.pci_bus]
cmp al, byte[ebx + device.pci_bus]
jne @f
cmp ah, byte[device.pci_dev]
cmp ah, byte[ebx + device.pci_dev]
je .find_devicenum ; Device is already loaded, let's find it's device number
@@:
add esi, 4
458,34 → 435,35
cmp [devices], MAX_DEVICES ; First check if the driver can handle one more card
jae .fail
 
allocate_and_clear ebx, device_size, .fail ; Allocate memory to put the device structure in
allocate_and_clear ebx, sizeof.device, .fail ; Allocate memory to put the device structure in
 
; Fill in the direct call addresses into the struct
 
mov [device.reset], reset
mov [device.transmit], transmit
mov [device.unload], unload
mov [device.name], my_service
mov [ebx + device.reset], reset
mov [ebx + device.transmit], transmit
mov [ebx + device.unload], unload
mov [ebx + device.name], my_service
 
; save the pci bus and device numbers
 
mov eax, [edx + IOCTL.input]
movzx ecx, byte[eax+1]
mov [device.pci_bus], ecx
mov [ebx + device.pci_bus], ecx
movzx ecx, byte[eax+2]
mov [device.pci_dev], ecx
mov [ebx + device.pci_dev], ecx
 
; Now, it's time to find the base io addres of the PCI device
 
PCI_find_io
mov [tpc.mmio_addr], eax ; CHECKME
stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
mov [ebx + device.io_addr], eax
 
; We've found the io address, find IRQ now
 
PCI_find_irq
invoke PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
mov [ebx + device.irq_line], al
 
DEBUGF 2,"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]:8
[ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:8
 
; Ok, the eth_device structure is ready, let's probe the device
; Because initialization fires IRQ, IRQ handler must be aware of this device
497,8 → 475,8
test eax, eax
jnz .err2 ; If an error occured, exit
 
mov [device.type], NET_TYPE_ETH
call NetRegDev
mov [ebx + device.type], NET_TYPE_ETH
invoke NetRegDev
 
cmp eax, -1
je .destroy
509,7 → 487,7
 
.find_devicenum:
DEBUGF 2,"Trying to find device number of already registered device\n"
call NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx
invoke NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx
; into a device number in edi
mov eax, edi ; Application wants it in eax instead
DEBUGF 2,"Kernel says: %u\n", eax
524,7 → 502,7
dec [devices]
.err:
DEBUGF 2,"removing device structure\n"
stdcall KernelFree, ebx
invoke KernelFree, ebx
.fail:
or eax, -1
ret
544,17 → 522,20
 
DEBUGF 1,"init_board\n"
 
PCI_make_bus_master
; Make the device a bus master
invoke PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
or al, PCI_CMD_MASTER
invoke PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
 
; Soft reset the chip
set_io 0
set_io REG_ChipCmd
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], REG_ChipCmd
mov al, CMD_Reset
out dx, al
 
; Check that the chip has finished the reset
mov ecx, 1000
set_io REG_ChipCmd
set_io [ebx + device.io_addr], REG_ChipCmd
@@: in al, dx
test al, CMD_Reset
jz @f
562,7 → 543,7
loop @b
@@:
; identify config method
set_io REG_TxConfig
set_io [ebx + device.io_addr], REG_TxConfig
in eax, dx
and eax, 0x7c800000
DEBUGF 1,"init_board: TxConfig & 0x7c800000 = 0x%x\n", eax
573,37 → 554,37
cmp ecx, [esi]
jne @b
mov eax, [esi+4]
mov [tpc.mcfg], eax
mov [ebx + device.mcfg], eax
 
mov [tpc.pcfg], PCFG_METHOD_3
mov [ebx + device.pcfg], PCFG_METHOD_3
READ_GMII_REG 3
and al, 0x0f
or al, al
jnz @f
mov [tpc.pcfg], PCFG_METHOD_1
mov [ebx + device.pcfg], PCFG_METHOD_1
jmp .pconf
@@: dec al
jnz .pconf
mov [tpc.pcfg], PCFG_METHOD_2
mov [ebx + device.pcfg], PCFG_METHOD_2
.pconf:
 
; identify chip attached to board
mov ecx, 10
mov eax, [tpc.mcfg]
mov eax, [ebx + device.mcfg]
@@: dec ecx
js @f
cmp eax, [rtl_chip_info + ecx*8]
jne @b
mov [tpc.chipset], ecx
mov [ebx + device.chipset], ecx
jmp .match
@@:
; if unknown chip, assume array element #0, original RTL-8169 in this case
DEBUGF 1,"init_board: PCI device: unknown chip version, assuming RTL-8169\n"
set_io REG_TxConfig
set_io [ebx + device.io_addr], REG_TxConfig
in eax, dx
DEBUGF 1,"init_board: PCI device: TxConfig = 0x%x\n", eax
 
mov [tpc.chipset], 0
mov [ebx + device.chipset], 0
 
xor eax, eax
inc eax
636,20 → 617,25
call PHY_config
 
DEBUGF 1,"Set MAC Reg C+CR Offset 0x82h = 0x01h\n"
set_io 0
set_io 0x82
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], 0x82
mov al, 0x01
out dx, al
cmp [tpc.mcfg], MCFG_METHOD_03
cmp [ebx + device.mcfg], MCFG_METHOD_03
jae @f
DEBUGF 1,"Set PCI Latency=0x40\n"
PCI_adjust_latency 0x40
; Adjust PCI latency to be at least 64
invoke PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.max_latency
cmp al, 64
jae @f
mov al, 64
invoke PciWrite8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.max_latency, eax
@@:
cmp [tpc.mcfg], MCFG_METHOD_02
cmp [ebx + device.mcfg], MCFG_METHOD_02
jne @f
DEBUGF 1,"Set MAC Reg C+CR Offset 0x82h = 0x01h\n"
set_io 0
set_io 0x82
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], 0x82
mov al, 0x01
out dx, al
DEBUGF 1,"Set PHY Reg 0x0bh = 0x00h\n"
656,8 → 642,8
WRITE_GMII_REG 0x0b, 0x0000 ; w 0x0b 15 0 0
@@:
; if TBI is not enabled
set_io 0
set_io REG_PHYstatus
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], REG_PHYstatus
in al, dx
test al, PHYS_TBI_Enable
jz .tbi_dis
680,12 → 666,12
; wait for auto-negotiation process
@@: dec ecx
jz @f
set_io 0
set_io [ebx + device.io_addr], 0
READ_GMII_REG PHY_STAT_REG
udelay 1 ; 100
test eax, PHY_Auto_Neco_Comp
jz @b
set_io REG_PHYstatus
set_io [ebx + device.io_addr], REG_PHYstatus
in al, dx
jmp @f
.tbi_dis:
707,13 → 693,13
 
DEBUGF 1,"resetting\n"
 
lea eax, [device.tx_ring]
mov [tpc.TxDescArrays], eax
mov [tpc.TxDescArray], eax
lea eax, [ebx + device.tx_ring]
mov [ebx + device.TxDescArrays], eax
mov [ebx + device.TxDescArray], eax
 
lea eax, [device.rx_ring]
mov [tpc.RxDescArrays], eax
mov [tpc.RxDescArray], eax
lea eax, [ebx + device.rx_ring]
mov [ebx + device.RxDescArrays], eax
mov [ebx + device.RxDescArray], eax
 
call init_ring
call hw_start
721,14 → 707,14
; clear packet/byte counters
 
xor eax, eax
lea edi, [device.bytes_tx]
lea edi, [ebx + device.bytes_tx]
mov ecx, 6
rep stosd
 
mov [device.mtu], 1500
mov [ebx + device.mtu], 1500
 
; Set link state to unknown
mov [device.state], ETH_LINK_UNKOWN
mov [ebx + device.state], ETH_LINK_UNKNOWN
 
DEBUGF 2,"init OK!\n"
xor eax, eax
741,11 → 727,11
align 4
PHY_config:
 
DEBUGF 1,"hw_PHY_config: priv.mcfg=%d, priv.pcfg=%d\n", [tpc.mcfg], [tpc.pcfg]
DEBUGF 1,"hw_PHY_config: priv.mcfg=%d, priv.pcfg=%d\n", [ebx + device.mcfg], [ebx + device.pcfg]
 
cmp [tpc.mcfg], MCFG_METHOD_04
cmp [ebx + device.mcfg], MCFG_METHOD_04
jne .not_4
set_io 0
set_io [ebx + device.io_addr], 0
; WRITE_GMII_REG 0x1F, 0x0001
; WRITE_GMII_REG 0x1b, 0x841e
; WRITE_GMII_REG 0x0e, 0x7bfb
755,12 → 741,12
WRITE_GMII_REG 0x1F, 0x0000
jmp .exit
.not_4:
cmp [tpc.mcfg], MCFG_METHOD_02
cmp [ebx + device.mcfg], MCFG_METHOD_02
je @f
cmp [tpc.mcfg], MCFG_METHOD_03
cmp [ebx + device.mcfg], MCFG_METHOD_03
jne .not_2_or_3
@@:
set_io 0
set_io [ebx + device.io_addr], 0
WRITE_GMII_REG 0x1F, 0x0001
WRITE_GMII_REG 0x15, 0x1000
WRITE_GMII_REG 0x18, 0x65C7
804,7 → 790,7
WRITE_GMII_REG 0x0B, 0x0000
jmp .exit
.not_2_or_3:
DEBUGF 1,"tpc.mcfg=%d, discard hw PHY config\n", [tpc.mcfg]
DEBUGF 1,"mcfg=%d, discard hw PHY config\n", [ebx + device.mcfg]
.exit:
ret
 
817,19 → 803,19
 
; IFF_ALLMULTI
; Too many to filter perfectly -- accept all multicasts
set_io 0
set_io REG_RxConfig
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], REG_RxConfig
in eax, dx
mov ecx, [tpc.chipset]
mov ecx, [ebx + device.chipset]
and eax, [rtl_chip_info + ecx * 8 + 4] ; RxConfigMask
or eax, rx_config or (RXM_AcceptBroadcast or RXM_AcceptMulticast or RXM_AcceptMyPhys)
out dx, eax
 
; Multicast hash filter
set_io REG_MAR0 + 0
set_io [ebx + device.io_addr], REG_MAR0 + 0
or eax, -1
out dx, eax
set_io REG_MAR0 + 4
set_io [ebx + device.io_addr], REG_MAR0 + 4
out dx, eax
 
ret
841,30 → 827,31
DEBUGF 1,"init_ring\n"
 
xor eax, eax
mov [tpc.cur_rx], eax
mov [tpc.cur_tx], eax
mov [ebx + device.cur_rx], eax
mov [ebx + device.cur_tx], eax
 
lea edi, [device.tx_ring]
mov ecx, (NUM_TX_DESC * tx_desc.size) / 4
lea edi, [ebx + device.tx_ring]
mov ecx, (NUM_TX_DESC * sizeof.tx_desc) / 4
rep stosd
 
lea edi, [device.rx_ring]
mov ecx, (NUM_RX_DESC * rx_desc.size) / 4
lea edi, [ebx + device.rx_ring]
mov ecx, (NUM_RX_DESC * sizeof.rx_desc) / 4
rep stosd
 
mov edi, [tpc.RxDescArray]
mov edi, [ebx + device.RxDescArray]
mov ecx, NUM_RX_DESC
.loop:
push ecx
stdcall KernelAlloc, RX_BUF_SIZE
mov [edi + rx_desc.buf_soft_addr], eax
call GetPgAddr
invoke KernelAlloc, RX_BUF_SIZE
mov dword [edi + rx_desc.buf_soft_addr], eax
invoke GetPgAddr
mov dword [edi + rx_desc.buf_addr], eax
mov [edi + rx_desc.status], DSB_OWNbit or RX_BUF_SIZE
add edi, rx_desc.size
add edi, sizeof.rx_desc
pop ecx
loop .loop
or [edi - rx_desc.size + rx_desc.status], DSB_EORbit
dec ecx
jnz .loop
or [edi - sizeof.rx_desc + rx_desc.status], DSB_EORbit
 
ret
 
875,13 → 862,19
DEBUGF 1,"hw_start\n"
 
; attach int handler
movzx eax, [device.irq_line]
movzx eax, [ebx + device.irq_line]
DEBUGF 1,"Attaching int handler to irq %x\n", eax:1
stdcall AttachIntHandler, eax, int_handler, dword 0
invoke AttachIntHandler, eax, int_handler, ebx
test eax, eax
jnz @f
DEBUGF 2,"Could not attach int handler!\n"
or eax, -1
ret
@@:
 
; Soft reset the chip
set_io 0
set_io REG_ChipCmd
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], REG_ChipCmd
mov al, CMD_Reset
out dx, al
 
888,7 → 881,7
DEBUGF 1,"Waiting for chip to reset... "
; Check that the chip has finished the reset
mov ecx, 1000
set_io REG_ChipCmd
set_io [ebx + device.io_addr], REG_ChipCmd
@@: in al, dx
test al, CMD_Reset
jz @f
897,45 → 890,45
@@:
DEBUGF 1,"done!\n"
 
set_io REG_Cfg9346
set_io [ebx + device.io_addr], REG_Cfg9346
mov al, CFG_9346_Unlock
out dx, al
 
set_io REG_ChipCmd
set_io [ebx + device.io_addr], REG_ChipCmd
mov al, CMD_TxEnb or CMD_RxEnb
out dx, al
 
set_io REG_ETThReg
set_io [ebx + device.io_addr], REG_ETThReg
mov al, ETTh
out dx, al
 
; For gigabit rtl8169
set_io REG_RxMaxSize
set_io [ebx + device.io_addr], REG_RxMaxSize
mov ax, RxPacketMaxSize
out dx, ax
 
; Set Rx Config register
set_io REG_RxConfig
set_io [ebx + device.io_addr], REG_RxConfig
in ax, dx
mov ecx, [tpc.chipset]
mov ecx, [ebx + device.chipset]
and eax, [rtl_chip_info + ecx * 8 + 4] ; RxConfigMask
or eax, rx_config
out dx, eax
 
; Set DMA burst size and Interframe Gap Time
set_io REG_TxConfig
set_io [ebx + device.io_addr], REG_TxConfig
mov eax, (TX_DMA_BURST shl TXC_DMAShift) or (InterFrameGap shl TXC_InterFrameGapShift)
out dx, eax
 
set_io REG_CPlusCmd
set_io [ebx + device.io_addr], REG_CPlusCmd
in ax, dx
out dx, ax
 
in ax, dx
or ax, 1 shl 3
cmp [tpc.mcfg], MCFG_METHOD_02
cmp [ebx + device.mcfg], MCFG_METHOD_02
jne @f
cmp [tpc.mcfg], MCFG_METHOD_03
cmp [ebx + device.mcfg], MCFG_METHOD_03
jne @f
or ax,1 shl 14
DEBUGF 1,"Set MAC Reg C+CR Offset 0xE0: bit-3 and bit-14\n"
943,10 → 936,10
@@:
DEBUGF 1,"Set MAC Reg C+CR Offset 0xE0: bit-3\n"
.set:
set_io REG_CPlusCmd
set_io [ebx + device.io_addr], REG_CPlusCmd
out dx, ax
 
set_io 0xE2
set_io [ebx + device.io_addr], 0xE2
; mov ax, 0x1517
; out dx, ax
; mov ax, 0x152a
957,24 → 950,24
out dx, ax
 
xor eax, eax
mov [tpc.cur_rx], eax
lea eax, [device.tx_ring]
GetRealAddr
set_io REG_TxDescStartAddr
mov [ebx + device.cur_rx], eax
lea eax, [ebx + device.tx_ring]
invoke GetPhysAddr
set_io [ebx + device.io_addr], REG_TxDescStartAddr
out dx, eax
set_io REG_TxDescStartAddr + 4
set_io [ebx + device.io_addr], REG_TxDescStartAddr + 4
xor eax, eax
out dx, eax
 
lea eax, [device.rx_ring]
GetRealAddr
set_io REG_RxDescStartAddr
lea eax, [ebx + device.rx_ring]
invoke GetPhysAddr
set_io [ebx + device.io_addr], REG_RxDescStartAddr
out dx, eax
xor eax, eax
set_io REG_RxDescStartAddr + 4
set_io [ebx + device.io_addr], REG_RxDescStartAddr + 4
out dx, eax
 
set_io REG_Cfg9346
set_io [ebx + device.io_addr], REG_Cfg9346
mov al, CFG_9346_Lock
out dx, al
 
981,20 → 974,20
udelay 10
 
xor eax, eax
set_io REG_RxMissed
set_io [ebx + device.io_addr], REG_RxMissed
out dx, eax
 
call set_rx_mode
 
set_io 0
set_io [ebx + device.io_addr], 0
; no early-rx interrupts
set_io REG_MultiIntr
set_io [ebx + device.io_addr], REG_MultiIntr
in ax, dx
and ax, 0xF000
out dx, ax
 
; set interrupt mask
set_io REG_IntrMask
set_io [ebx + device.io_addr], REG_IntrMask
mov ax, intr_mask
out dx, ax
 
1005,10 → 998,10
align 4
read_mac:
 
set_io 0
set_io REG_MAC0
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], REG_MAC0
xor ecx, ecx
lea edi, [device.mac]
lea edi, [ebx + device.mac]
mov ecx, 6
 
; Get MAC address. FIXME: read EEPROM
1018,7 → 1011,7
loop @r
 
DEBUGF 1,"MAC = %x-%x-%x-%x-%x-%x\n",\
[device.mac+0]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2
[ebx + device.mac+0]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,[ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
 
ret
 
1028,9 → 1021,6
ret 6
 
 
 
 
 
;***************************************************************************
; Function
; transmit
1041,25 → 1031,30
; eax, edx, esi, edi
;
;***************************************************************************
align 4
transmit:
 
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [esp+4], [esp+8]
mov eax, [esp+4]
proc transmit stdcall bufferptr, buffersize
 
pushf
cli
 
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
mov eax, [bufferptr]
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 [buffersize], 1514
ja .fail
cmp [buffersize], 60
jb .fail
 
;----------------------------------
; Find currentTX descriptor address
 
mov eax, tx_desc.size
mul [tpc.cur_tx]
lea esi, [eax + device.tx_ring]
mov eax, sizeof.tx_desc
mul [ebx + device.cur_tx]
lea esi, [ebx + device.tx_ring + eax]
 
DEBUGF 1,"Using TX desc: %x\n", esi
 
1066,17 → 1061,17
;---------------------------
; Program the packet pointer
 
mov eax, [esp + 4]
mov eax, [bufferptr]
mov [esi + tx_desc.buf_soft_addr], eax
GetRealAddr
invoke GetPhysAddr
mov dword [esi + tx_desc.buf_addr], eax
 
;------------------------
; Program the packet size
 
mov eax, [esp + 8]
mov eax, [buffersize]
@@: or eax, DSB_OWNbit or DSB_FSbit or DSB_LSbit
cmp [tpc.cur_tx], NUM_TX_DESC - 1
cmp [ebx + device.cur_tx], NUM_TX_DESC - 1
jne @f
or eax, DSB_EORbit
@@: mov [esi + tx_desc.status], eax
1084,8 → 1079,8
;-----------------------------------------
; Set the polling bit (start transmission)
 
set_io 0
set_io REG_TxPoll
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], REG_TxPoll
mov al, 0x40 ; set polling bit
out dx, al
 
1092,27 → 1087,31
;-----------------------
; Update TX descriptor
 
inc [tpc.cur_tx]
and [tpc.cur_tx], NUM_TX_DESC - 1
inc [ebx + device.cur_tx]
and [ebx + device.cur_tx], NUM_TX_DESC - 1
 
;-------------
; Update stats
 
inc [device.packets_tx]
mov eax, [esp + 8]
add dword [device.bytes_tx], eax
adc dword [device.bytes_tx + 4], 0
inc [ebx + device.packets_tx]
mov eax, [buffersize]
add dword [ebx + device.bytes_tx], eax
adc dword [ebx + device.bytes_tx + 4], 0
 
xor eax, eax
ret 8
popf
ret
 
.fail:
DEBUGF 1,"transmit failed\n"
stdcall KernelFree, [esp+4]
DEBUGF 2,"Transmit failed\n"
invoke KernelFree, [bufferptr]
popf
or eax, -1
ret 8
ret
 
endp
 
 
;;;DSB_OWNbit
 
 
1138,8 → 1137,8
.nextdevice:
mov ebx, [esi]
 
set_io 0
set_io REG_IntrStatus
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], REG_IntrStatus
in ax, dx
test ax, ax
jnz .got_it
1155,7 → 1154,7
 
.got_it:
 
DEBUGF 1,"Device: %x Status: %x ", ebx, ax
DEBUGF 1,"Device: %x Status: %x\n", ebx, ax
 
cmp ax, 0xFFFF ; if so, hardware is no longer present
je .fail
1171,18 → 1170,16
 
.check_more:
pop ebx
DEBUGF 1,"ebx = 0x%x\n", ebx
mov eax, rx_desc.size
mul [tpc.cur_rx]
lea esi, [eax + device.rx_ring]
mov eax, sizeof.rx_desc
mul [ebx + device.cur_rx]
lea esi, [ebx + device.rx_ring + eax]
 
DEBUGF 1,"RxDesc.status = 0x%x\n", [esi + rx_desc.status]
 
mov eax, [esi + rx_desc.status]
test eax, DSB_OWNbit ;;;
jnz .rx_return
 
DEBUGF 1,"tpc.cur_rx = %u\n", [tpc.cur_rx]
DEBUGF 1,"cur_rx = %u\n", [ebx + device.cur_rx]
 
test eax, SD_RxRES
jnz .rx_return ;;;;; RX error!
1197,18 → 1194,18
;-------------
; Update stats
 
add dword [device.bytes_rx], eax
adc dword [device.bytes_rx + 4], 0
inc dword [device.packets_rx]
add dword [ebx + device.bytes_rx], eax
adc dword [ebx + device.bytes_rx + 4], 0
inc [ebx + device.packets_rx]
 
push [esi + rx_desc.buf_soft_addr]
pushd [esi + rx_desc.buf_soft_addr]
 
;----------------------
; Allocate a new buffer
 
stdcall KernelAlloc, RX_BUF_SIZE
invoke KernelAlloc, RX_BUF_SIZE
mov [esi + rx_desc.buf_soft_addr], eax
GetRealAddr
invoke GetPhysAddr
mov dword [esi + rx_desc.buf_addr], eax
 
;---------------
1215,18 → 1212,19
; re set OWN bit
 
mov eax, DSB_OWNbit or RX_BUF_SIZE
cmp [tpc.cur_rx], NUM_RX_DESC - 1
cmp [ebx + device.cur_rx], NUM_RX_DESC - 1
jne @f
or eax, DSB_EORbit
@@: mov [esi + rx_desc.status], eax
@@:
mov [esi + rx_desc.status], eax
 
;--------------
; Update rx ptr
 
inc [tpc.cur_rx]
and [tpc.cur_rx], NUM_RX_DESC - 1
inc [ebx + device.cur_rx]
and [ebx + device.cur_rx], NUM_RX_DESC - 1
 
jmp Eth_input
jmp [Eth_input]
.rx_return:
 
pop ax
1242,9 → 1240,9
DEBUGF 1,"TX ok!\n"
 
mov ecx, NUM_TX_DESC
lea esi, [device.tx_ring]
lea esi, [ebx + device.tx_ring]
.txloop:
cmp [esi + tx_desc.buf_soft_addr], 0
cmp dword [esi + tx_desc.buf_soft_addr], 0
jz .maybenext
 
test [esi + tx_desc.status], DSB_OWNbit
1252,12 → 1250,12
 
push ecx
DEBUGF 1,"Freeing up TX desc: %x\n", esi
stdcall KernelFree, [esi + tx_desc.buf_soft_addr]
invoke KernelFree, [esi + tx_desc.buf_soft_addr]
pop ecx
and [esi + tx_desc.buf_soft_addr], 0
and dword [esi + tx_desc.buf_soft_addr], 0
 
.maybenext:
add esi, tx_desc.size
add esi, sizeof.tx_desc
dec ecx
jnz .txloop
 
1267,8 → 1265,8
;-------
; Finish
 
set_io 0
set_io REG_IntrStatus
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], REG_IntrStatus
out dx, ax ; ACK all interrupts
 
.fail:
1280,17 → 1278,13
 
 
 
; End of code
 
data fixups
end data
 
include '../peimport.inc'
 
 
 
 
; End of code
align 4 ; Place all initialised data here
 
devices dd 0
version dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
my_service db 'RTL8169',0 ; max 16 chars include zero
 
include_debug_strings ; All data wich FDO uses will be included here
1327,9 → 1321,8
name_13 db "RTL8101e", 0 ; PCI-E 8139
name_14_15 db "RTL8100e", 0 ; PCI-E 8139
 
 
section '.data' data readable writable align 16 ; place all uninitialized data place here
 
align 4
devices dd 0
device_list rd MAX_DEVICES ; This list contains all pointers to device structures the driver is handling