forked from KolibriOS/kolibrios
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:
parent
2a755c9a3d
commit
fdf02e4b52
@ -144,26 +144,30 @@ include '../netdrv.inc'
|
||||
EE_93C56_CMD_LENGTH = 11 ; start bit + cmd + 8bit ddress
|
||||
|
||||
; 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_RTL8139AG = 1110100b
|
||||
VER_RTL8139A_G = 1110010b
|
||||
VER_RTL8139B = 1111000b
|
||||
VER_RTL8130 = VER_RTL8139B
|
||||
VER_RTL8130 = 1111100b
|
||||
VER_RTL8139C = 1110100b
|
||||
VER_RTL8100 = 1111010b
|
||||
VER_RTL8100B = 1110101b
|
||||
VER_RTL8139D = VER_RTL8100B
|
||||
VER_RTL8139CP = 1110110b
|
||||
VER_RTL8100_8139D = 1110101b
|
||||
VER_RTL8101 = 1110111b
|
||||
|
||||
IDX_RTL8139 = 0
|
||||
IDX_RTL8139A = 1
|
||||
IDX_RTL8139B = 2
|
||||
IDX_RTL8139C = 3
|
||||
IDX_RTL8100 = 4
|
||||
IDX_RTL8139D = 5
|
||||
IDX_RTL8139D = 6
|
||||
IDX_RTL8101 = 7
|
||||
IDX_UNKNOWN = 0
|
||||
IDX_RTL8139 = 1
|
||||
IDX_RTL8139_K = 2
|
||||
IDX_RTL8139A = 3
|
||||
IDX_RTL8139A_G = 4
|
||||
IDX_RTL8139B = 5
|
||||
IDX_RTL8130 = 6
|
||||
IDX_RTL8139C = 7
|
||||
IDX_RTL8100 = 8
|
||||
IDX_RTL8100_8139D = 9
|
||||
IDX_RTL8101 = 10
|
||||
|
||||
HW_VERSIONS = 10
|
||||
|
||||
ISR_SERR = 1 shl 15
|
||||
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
|
||||
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
|
||||
|
||||
@ -327,8 +331,8 @@ proc service_proc stdcall, ioctl:dword
|
||||
invoke PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
|
||||
mov [ebx + device.irq_line], al
|
||||
|
||||
DEBUGF 1, "Hooking into device, dev:%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
|
||||
DEBUGF 1, "Hooking into device, devfn:%x, bus:%x, irq:%x, I/O addr:%x\n",\
|
||||
[ebx + device.pci_dev]:2,[ebx + device.pci_bus]:2,[ebx + device.irq_line]:2,[ebx + device.io_addr]:4
|
||||
|
||||
; Allocate the receive buffer
|
||||
|
||||
@ -377,7 +381,7 @@ proc service_proc stdcall, ioctl:dword
|
||||
dec [devices]
|
||||
|
||||
.err:
|
||||
DEBUGF 2, "Error, removing all data !\n"
|
||||
DEBUGF 2, "Fatal error occured, aborting\n"
|
||||
invoke KernelFree, [ebx + device.rx_buffer]
|
||||
invoke KernelFree, ebx
|
||||
|
||||
@ -421,82 +425,82 @@ probe:
|
||||
|
||||
; Make the device a bus master
|
||||
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
|
||||
|
||||
; get chip version
|
||||
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
|
||||
; wake up old chips
|
||||
set_io [ebx + device.io_addr], 0
|
||||
set_io [ebx + device.io_addr], REG_HLTCLK
|
||||
mov al, 'R' ; run the clock
|
||||
out dx, al
|
||||
|
||||
; unlock config and BMCR registers
|
||||
set_io [ebx + device.io_addr], REG_9346CR
|
||||
mov al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EEM0)
|
||||
out dx, al
|
||||
; get chip version
|
||||
set_io [ebx + device.io_addr], REG_TXCONFIG
|
||||
in eax, dx
|
||||
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
|
||||
jae .new_chip
|
||||
|
||||
; 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))
|
||||
out dx, al
|
||||
jmp .finish_wake_up
|
||||
jmp .done
|
||||
|
||||
; set LWAKE pin to active high (default value).
|
||||
; it is for Wake-On-LAN functionality of some motherboards.
|
||||
; this signal is used to inform the motherboard to execute a wake-up process.
|
||||
; only at newer chips.
|
||||
.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)
|
||||
and al, not (1 shl BIT_LWACT)
|
||||
out dx, al
|
||||
|
||||
;
|
||||
set_io [ebx + device.io_addr], REG_CONFIG4
|
||||
in al, dx
|
||||
and al, not (1 shl BIT_LWPTN)
|
||||
out dx, al
|
||||
|
||||
; lock config and BMCR registers
|
||||
.finish_wake_up:
|
||||
xor al, al
|
||||
set_io [ebx + device.io_addr], 0
|
||||
set_io [ebx + device.io_addr], REG_9346CR
|
||||
out dx, al
|
||||
|
||||
.done:
|
||||
DEBUGF 1, "probing done!\n"
|
||||
|
||||
xor eax, eax
|
||||
|
||||
ret
|
||||
|
||||
|
||||
@ -516,16 +520,16 @@ reset:
|
||||
mov al, 1 shl BIT_RST
|
||||
out dx, al
|
||||
mov cx, 1000 ; wait no longer for the reset
|
||||
.wait_for_reset:
|
||||
@@:
|
||||
in al, dx
|
||||
test al, 1 shl BIT_RST
|
||||
jz .reset_completed ; RST remains 1 during reset
|
||||
jz @f ; RST remains 1 during reset
|
||||
dec cx
|
||||
jns .wait_for_reset
|
||||
jnz @r
|
||||
DEBUGF 2, "Reset timeout!\n"
|
||||
or eax, -1
|
||||
ret
|
||||
.reset_completed:
|
||||
@@:
|
||||
|
||||
; Read MAC address
|
||||
call read_mac
|
||||
@ -539,7 +543,7 @@ reset:
|
||||
DEBUGF 2, "Could not attach int handler!\n"
|
||||
or eax, -1
|
||||
ret
|
||||
@@:
|
||||
@@:
|
||||
|
||||
; unlock config and BMCR registers
|
||||
set_io [ebx + device.io_addr], 0
|
||||
@ -620,6 +624,7 @@ reset:
|
||||
; Set the mtu, kernel will be able to send now
|
||||
mov [ebx + device.mtu], 1514
|
||||
|
||||
; Detect current link status
|
||||
call link
|
||||
|
||||
; 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
|
||||
|
||||
device_1 db 'Realtek 8139',0
|
||||
device_2 db 'Realtek 8139A',0
|
||||
device_3 db 'Realtek 8139B',0
|
||||
device_4 db 'Realtek 8139C',0
|
||||
device_5 db 'Realtek 8100',0
|
||||
device_6 db 'Realtek 8139D',0
|
||||
device_7 db 'Realtek 8139CP',0
|
||||
device_8 db 'Realtek 8101',0
|
||||
device_unknown db 'Unknown RTL8139 clone', 0
|
||||
sz_unknown db 'Unknown RTL8139 clone', 0
|
||||
sz_RTL8139 db 'Realtek 8139',0
|
||||
sz_RTL8139_K db 'Realtek 8139 rev K',0
|
||||
sz_RTL8139A db 'Realtek 8139A',0
|
||||
sz_RTL8139A_G db 'Realtek 8139A rev G',0
|
||||
sz_RTL8139B db 'Realtek 8139B',0
|
||||
sz_RTL8130 db 'Realtek 8130',0
|
||||
sz_RTL8139C db 'Realtek 8139C',0
|
||||
sz_RTL8100 db 'Realtek 8100',0
|
||||
sz_RTL8100_8139D db 'Realtek 8100B / 8139D',0
|
||||
sz_RTL8101 db 'Realtek 8101',0
|
||||
|
||||
crosslist:
|
||||
dd device_1
|
||||
dd device_2
|
||||
dd device_3
|
||||
dd device_4
|
||||
dd device_5
|
||||
dd device_6
|
||||
dd device_7
|
||||
dd device_8
|
||||
dd device_unknown
|
||||
hw_ver_names:
|
||||
dd sz_unknown
|
||||
dd sz_RTL8139
|
||||
dd sz_RTL8139_K
|
||||
dd sz_RTL8139A
|
||||
dd sz_RTL8139A_G
|
||||
dd sz_RTL8139B
|
||||
dd sz_RTL8130
|
||||
dd sz_RTL8139C
|
||||
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_K
|
||||
db VER_RTL8139A
|
||||
db VER_RTL8139A_G
|
||||
db VER_RTL8139B
|
||||
db VER_RTL8130
|
||||
db VER_RTL8139C
|
||||
db VER_RTL8100
|
||||
db VER_RTL8139D
|
||||
db VER_RTL8139CP
|
||||
db VER_RTL8100_8139D
|
||||
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
|
||||
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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user