Added more hardware diversities, refactored chip wake up procedure, set PCI_CMD_PIO bit to allow access to devices which have this bit disabled by default.

git-svn-id: svn://kolibrios.org@6711 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2016-11-14 16:28:33 +00:00
parent 2a755c9a3d
commit fdf02e4b52

View File

@ -144,26 +144,30 @@ include '../netdrv.inc'
EE_93C56_CMD_LENGTH = 11 ; start bit + cmd + 8bit ddress EE_93C56_CMD_LENGTH = 11 ; start bit + cmd + 8bit ddress
; See chapter "5.7 Transmit Configuration Register" of RTL8139D(L).pdf ; See chapter "5.7 Transmit Configuration Register" of RTL8139D(L).pdf
VER_RTL8139 = 1100000b VER_RTL8139 = 1000000b
VER_RTL8139_K = 1100000b
VER_RTL8139A = 1110000b VER_RTL8139A = 1110000b
VER_RTL8139AG = 1110100b VER_RTL8139A_G = 1110010b
VER_RTL8139B = 1111000b VER_RTL8139B = 1111000b
VER_RTL8130 = VER_RTL8139B VER_RTL8130 = 1111100b
VER_RTL8139C = 1110100b VER_RTL8139C = 1110100b
VER_RTL8100 = 1111010b VER_RTL8100 = 1111010b
VER_RTL8100B = 1110101b VER_RTL8100_8139D = 1110101b
VER_RTL8139D = VER_RTL8100B
VER_RTL8139CP = 1110110b
VER_RTL8101 = 1110111b VER_RTL8101 = 1110111b
IDX_RTL8139 = 0 IDX_UNKNOWN = 0
IDX_RTL8139A = 1 IDX_RTL8139 = 1
IDX_RTL8139B = 2 IDX_RTL8139_K = 2
IDX_RTL8139C = 3 IDX_RTL8139A = 3
IDX_RTL8100 = 4 IDX_RTL8139A_G = 4
IDX_RTL8139D = 5 IDX_RTL8139B = 5
IDX_RTL8139D = 6 IDX_RTL8130 = 6
IDX_RTL8101 = 7 IDX_RTL8139C = 7
IDX_RTL8100 = 8
IDX_RTL8100_8139D = 9
IDX_RTL8101 = 10
HW_VERSIONS = 10
ISR_SERR = 1 shl 15 ISR_SERR = 1 shl 15
ISR_TIMEOUT = 1 shl 14 ISR_TIMEOUT = 1 shl 14
@ -300,7 +304,7 @@ proc service_proc stdcall, ioctl:dword
cmp [devices], MAX_DEVICES ; First check if the driver can handle one more card cmp [devices], MAX_DEVICES ; First check if the driver can handle one more card
jae .fail jae .fail
allocate_and_clear ebx, sizeof.device, .fail ; Allocate the buffer for device structure allocate_and_clear ebx, sizeof.device, .fail ; Allocate the buffer for device structure
; Fill in the direct call addresses into the struct ; Fill in the direct call addresses into the struct
@ -327,8 +331,8 @@ proc service_proc stdcall, ioctl:dword
invoke PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line invoke PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
mov [ebx + device.irq_line], al mov [ebx + device.irq_line], al
DEBUGF 1, "Hooking into device, dev:%x, bus:%x, irq:%x, I/O addr:%x\n",\ DEBUGF 1, "Hooking into device, devfn:%x, bus:%x, irq:%x, I/O addr:%x\n",\
[ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:4 [ebx + device.pci_dev]:2,[ebx + device.pci_bus]:2,[ebx + device.irq_line]:2,[ebx + device.io_addr]:4
; Allocate the receive buffer ; Allocate the receive buffer
@ -377,7 +381,7 @@ proc service_proc stdcall, ioctl:dword
dec [devices] dec [devices]
.err: .err:
DEBUGF 2, "Error, removing all data !\n" DEBUGF 2, "Fatal error occured, aborting\n"
invoke KernelFree, [ebx + device.rx_buffer] invoke KernelFree, [ebx + device.rx_buffer]
invoke KernelFree, ebx invoke KernelFree, ebx
@ -421,82 +425,82 @@ probe:
; Make the device a bus master ; Make the device a bus master
invoke PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command invoke PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
or al, PCI_CMD_MASTER or al, PCI_CMD_MASTER or PCI_CMD_PIO
invoke PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax invoke PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
; get chip version ; wake up old chips
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], REG_TXCONFIG + 2
in ax, dx
shr ah, 2
shr ax, 6
and al, 01111111b
; now find it in our array
mov ecx, HW_VER_ARRAY_SIZE-1
.chip_ver_loop:
cmp al, [hw_ver_array + ecx]
je .chip_ver_found
dec ecx
jns .chip_ver_loop
.unknown:
mov ecx, 8
.chip_ver_found:
cmp ecx, 8
ja .unknown
mov [ebx + device.hw_ver_id], cl
mov ecx, [crosslist+ecx*4]
mov [ebx + device.name], ecx
DEBUGF 1, "Chip version: %s\n", ecx
; wake up the chip
set_io [ebx + device.io_addr], 0 set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], REG_HLTCLK set_io [ebx + device.io_addr], REG_HLTCLK
mov al, 'R' ; run the clock mov al, 'R' ; run the clock
out dx, al out dx, al
; unlock config and BMCR registers ; get chip version
set_io [ebx + device.io_addr], REG_9346CR set_io [ebx + device.io_addr], REG_TXCONFIG
mov al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EEM0) in eax, dx
out dx, al shr eax, 16
shr ah, 2
shr ax, 6
and al, 0x7f
DEBUGF 1, "Chip version: %x\n", eax:2
; now find it in our array
mov ecx, HW_VERSIONS
@@:
cmp al, [hw_ver_array + ecx]
je @f
dec ecx
jnz @r
@@:
mov [ebx + device.hw_ver_id], cl
mov ecx, [hw_ver_names+ecx*4]
mov [ebx + device.name], ecx
DEBUGF 1, "Chip version: %s\n", ecx
; enable power management
set_io [ebx + device.io_addr], REG_CONFIG1
in al, dx
cmp [ebx + device.hw_ver_id], IDX_RTL8139B cmp [ebx + device.hw_ver_id], IDX_RTL8139B
jae .new_chip jae .new_chip
; wake up older chips ; wake up older chips
.old_chip:
DEBUGF 1, "Wake up chip old style\n"
set_io [ebx + device.io_addr], REG_CONFIG1
in al, dx
and al, not ((1 shl BIT_SLEEP) or (1 shl BIT_PWRDWN)) and al, not ((1 shl BIT_SLEEP) or (1 shl BIT_PWRDWN))
out dx, al out dx, al
jmp .finish_wake_up jmp .done
; set LWAKE pin to active high (default value). ; set LWAKE pin to active high (default value).
; it is for Wake-On-LAN functionality of some motherboards. ; it is for Wake-On-LAN functionality of some motherboards.
; this signal is used to inform the motherboard to execute a wake-up process. ; this signal is used to inform the motherboard to execute a wake-up process.
; only at newer chips. ; only at newer chips.
.new_chip: .new_chip:
DEBUGF 1, "Wake up chip new style\n"
; unlock config and BMCR registers
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], REG_9346CR
mov al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EEM0)
out dx, al
;
set_io [ebx + device.io_addr], REG_CONFIG1
in al, dx
or al, (1 shl BIT_PMEn) or al, (1 shl BIT_PMEn)
and al, not (1 shl BIT_LWACT) and al, not (1 shl BIT_LWACT)
out dx, al out dx, al
;
set_io [ebx + device.io_addr], REG_CONFIG4 set_io [ebx + device.io_addr], REG_CONFIG4
in al, dx in al, dx
and al, not (1 shl BIT_LWPTN) and al, not (1 shl BIT_LWPTN)
out dx, al out dx, al
; lock config and BMCR registers ; lock config and BMCR registers
.finish_wake_up:
xor al, al xor al, al
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], REG_9346CR set_io [ebx + device.io_addr], REG_9346CR
out dx, al out dx, al
.done:
DEBUGF 1, "probing done!\n" DEBUGF 1, "probing done!\n"
xor eax, eax xor eax, eax
ret ret
@ -516,16 +520,16 @@ reset:
mov al, 1 shl BIT_RST mov al, 1 shl BIT_RST
out dx, al out dx, al
mov cx, 1000 ; wait no longer for the reset mov cx, 1000 ; wait no longer for the reset
.wait_for_reset: @@:
in al, dx in al, dx
test al, 1 shl BIT_RST test al, 1 shl BIT_RST
jz .reset_completed ; RST remains 1 during reset jz @f ; RST remains 1 during reset
dec cx dec cx
jns .wait_for_reset jnz @r
DEBUGF 2, "Reset timeout!\n" DEBUGF 2, "Reset timeout!\n"
or eax, -1 or eax, -1
ret ret
.reset_completed: @@:
; Read MAC address ; Read MAC address
call read_mac call read_mac
@ -539,7 +543,7 @@ reset:
DEBUGF 2, "Could not attach int handler!\n" DEBUGF 2, "Could not attach int handler!\n"
or eax, -1 or eax, -1
ret ret
@@: @@:
; unlock config and BMCR registers ; unlock config and BMCR registers
set_io [ebx + device.io_addr], 0 set_io [ebx + device.io_addr], 0
@ -620,6 +624,7 @@ reset:
; Set the mtu, kernel will be able to send now ; Set the mtu, kernel will be able to send now
mov [ebx + device.mtu], 1514 mov [ebx + device.mtu], 1514
; Detect current link status
call link call link
; Indicate that we have successfully reset the card ; Indicate that we have successfully reset the card
@ -1122,43 +1127,47 @@ include '../peimport.inc'
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 sz_unknown db 'Unknown RTL8139 clone', 0
device_2 db 'Realtek 8139A',0 sz_RTL8139 db 'Realtek 8139',0
device_3 db 'Realtek 8139B',0 sz_RTL8139_K db 'Realtek 8139 rev K',0
device_4 db 'Realtek 8139C',0 sz_RTL8139A db 'Realtek 8139A',0
device_5 db 'Realtek 8100',0 sz_RTL8139A_G db 'Realtek 8139A rev G',0
device_6 db 'Realtek 8139D',0 sz_RTL8139B db 'Realtek 8139B',0
device_7 db 'Realtek 8139CP',0 sz_RTL8130 db 'Realtek 8130',0
device_8 db 'Realtek 8101',0 sz_RTL8139C db 'Realtek 8139C',0
device_unknown db 'Unknown RTL8139 clone', 0 sz_RTL8100 db 'Realtek 8100',0
sz_RTL8100_8139D db 'Realtek 8100B / 8139D',0
sz_RTL8101 db 'Realtek 8101',0
crosslist: hw_ver_names:
dd device_1 dd sz_unknown
dd device_2 dd sz_RTL8139
dd device_3 dd sz_RTL8139_K
dd device_4 dd sz_RTL8139A
dd device_5 dd sz_RTL8139A_G
dd device_6 dd sz_RTL8139B
dd device_7 dd sz_RTL8130
dd device_8 dd sz_RTL8139C
dd device_unknown dd sz_RTL8100
dd sz_RTL8100_8139D
dd sz_RTL8101
hw_ver_array: ; 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 0
db VER_RTL8139 db VER_RTL8139
db VER_RTL8139_K
db VER_RTL8139A db VER_RTL8139A
db VER_RTL8139A_G
db VER_RTL8139B db VER_RTL8139B
db VER_RTL8130
db VER_RTL8139C db VER_RTL8139C
db VER_RTL8100 db VER_RTL8100
db VER_RTL8139D db VER_RTL8100_8139D
db VER_RTL8139CP
db VER_RTL8101 db VER_RTL8101
db 0
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
align 4 align 4
devices dd 0 devices dd 0
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