Fixed eeprom reading for certain chips, detect PHY ID, improved reset.

git-svn-id: svn://kolibrios.org@6717 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2016-11-15 21:34:09 +00:00
parent 4fcfa2351b
commit 97e49e498f

View File

@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; i8255x (Intel eepro 100) driver for KolibriOS ;;
@ -43,21 +43,34 @@ include '../macros.inc'
include '../fdo.inc'
include '../netdrv.inc'
; Serial EEPROM
; I/O registers
REG_SCB_STATUS = 0
REG_SCB_CMD = 2
REG_SCB_PTR = 4
REG_PORT = 8
REG_EEPROM = 14
REG_MDI_CTRL = 16
; Port commands
PORT_SOFT_RESET = 0x0
PORT_SELF_TEST = 0x1
PORT_SELECTIVE_RESET = 0x2
PORT_DUMP = 0x3
PORT_DUMP_WAKEUP = 0x7
PORT_PTR_MASK = 0xfffffff0
; Serial EEPROM
EE_SK = 1 shl 0 ; serial clock
EE_CS = 1 shl 1 ; chip select
EE_DI = 1 shl 2 ; data in
EE_DO = 1 shl 3 ; data out
EE_MASK = EE_SK + EE_CS + EE_DI + EE_DO
; opcodes, first bit is start bit and must be 1
EE_READ = 110b
EE_WRITE = 101b
EE_ERASE = 111b
; The SCB accepts the following controls for the Tx and Rx units:
CU_START = 0x0010
CU_RESUME = 0x0020
CU_STATSADDR = 0x0040
@ -73,13 +86,6 @@ RX_RESUMENR = 0x0007
INT_MASK = 0x0100
DRVR_INT = 0x0200 ; Driver generated interrupt
REG_SCB_STATUS = 0
REG_SCB_CMD = 2
REG_SCB_PTR = 4
REG_PORT = 8
REG_EEPROM = 14
REG_MDI_CTRL = 16
PHY_100a = 0x000003E0
PHY_100c = 0x035002A8
PHY_82555_tx = 0x015002A8
@ -318,7 +324,7 @@ proc service_proc stdcall, ioctl:dword
mov [ebx + device.reset], reset
mov [ebx + device.transmit], transmit
mov [ebx + device.unload], unload
mov [ebx + device.name], my_service
mov [ebx + device.name], devicename
; save the pci bus and device numbers
@ -338,23 +344,18 @@ 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, 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, addr:%x\n",\
[ebx + device.pci_dev]:2,[ebx + device.pci_bus]:2,[ebx + device.irq_line]:2,[ebx + device.io_addr]:4
; Ok, the eth_device structure is ready, let's probe the device
pushf
cli ; disable ints untilm initialisation is done
call probe ; this function will output in eax
test eax, eax
jnz .err ; If an error occured, exit
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)
inc [devices] ;
popf
call probe ; this function will output in eax
test eax, eax
jnz .err ; If an error occured, exit
mov [ebx + device.type], NET_TYPE_ETH
invoke NetRegDev
@ -375,7 +376,6 @@ proc service_proc stdcall, ioctl:dword
ret
; If an error occured, remove all allocated data and exit (returning -1 in eax)
.err:
invoke KernelFree, ebx
@ -423,7 +423,7 @@ 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
;---------------------------
@ -452,11 +452,6 @@ probe:
.found:
call ee_get_width
call MAC_read_eeprom
;;; TODO: detect phy
;----------
@ -480,16 +475,45 @@ reset:
DEBUGF 1,"Resetting\n"
;---------------
; reset the card
;----------------
; Selective reset
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], REG_EEPROM
mov eax, PORT_SELECTIVE_RESET
out dx, eax
mov esi, 1
invoke Sleep
;-----------
; Soft reset
set_io [ebx + device.io_addr], REG_PORT
xor eax, eax ; Software Reset
mov eax, PORT_SOFT_RESET
out dx, eax
mov esi, 10
invoke Sleep ; Give the card time to warm up.
invoke Sleep
;-------------
; Read PHY IDs
mov cx, 1
mov dx, MII_PHYSID1
call mdio_read
DEBUGF 1, "PHY ID1: 0x%x\n", ax
mov cx, 1
mov dx, MII_PHYSID2
call mdio_read
DEBUGF 1, "PHY ID2: 0x%x\n", ax
;---------------------
; Read MAC from eeprom
call ee_get_width
call mac_read_eeprom
;---------------------------------
; Tell device where to store stats
@ -991,15 +1015,15 @@ ee_read: ; esi = address to read
movzx ecx, [ebx + device.ee_bus_width]
add ecx, 3
mov al, EE_CS
out dx, al
mov ax, 0x4800 + EE_CS
out dx, ax
call udelay
;-----------------------
; Write this to the chip
.loop:
mov al, EE_CS + EE_SK
mov al, EE_CS
shl esi, 1
jnc @f
or al, EE_DI
@ -1007,7 +1031,7 @@ ee_read: ; esi = address to read
out dx, al
call udelay
and al, not EE_SK
or al, EE_SK
out dx, al
call udelay
@ -1021,7 +1045,11 @@ ee_read: ; esi = address to read
.loop2:
shl esi, 1
mov al, EE_CS + EE_SK
mov al, EE_CS
out dx, al
call udelay
or al, EE_SK
out dx, al
call udelay
@ -1031,18 +1059,13 @@ ee_read: ; esi = address to read
inc esi
@@:
mov al, EE_CS
out dx, al
call udelay
loop .loop2
;-----------------------
; de-activate the eeprom
xor ax, ax
out dx, ax
xor al, al
out dx, al
DEBUGF 1,"0x%x\n", esi:4
ret
@ -1069,14 +1092,14 @@ ee_write: ; esi = address to write to, di = data
movzx ecx, [ebx + device.ee_bus_width]
add ecx, 3
mov al, EE_CS ; enable chip
out dx, al
mov ax, 0x4800 + EE_CS ; enable chip
out dx, ax
;-----------------------
; Write this to the chip
.loop:
mov al, EE_CS + EE_SK
mov al, EE_CS
shl esi, 1
jnc @f
or al, EE_DI
@ -1084,7 +1107,7 @@ ee_write: ; esi = address to write to, di = data
out dx, al
call udelay
and al, not EE_SK
or al, EE_SK
out dx, al
call udelay
@ -1096,7 +1119,7 @@ ee_write: ; esi = address to write to, di = data
mov ecx, 16
.loop2:
mov al, EE_CS + EE_SK
mov al, EE_CS
shl di, 1
jnc @f
or al, EE_DI
@ -1104,7 +1127,7 @@ ee_write: ; esi = address to write to, di = data
out dx, al
call udelay
and al, not EE_SK
or al, EE_SK
out dx, al
call udelay
@ -1127,23 +1150,23 @@ ee_get_width:
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], REG_EEPROM
mov al, EE_CS ; activate eeprom
out dx, al
mov ax, 0x4800 + EE_CS ; activate eeprom
out dx, ax
call udelay
mov si, EE_READ shl 13
xor ecx, ecx
.loop:
mov al, EE_CS + EE_SK
mov al, EE_CS
shl si, 1
jnc @f
or al, EE_DI
@@:
out dx, al
out dx, ax
call udelay
and al, not EE_SK
out dx, al
or al, EE_SK
out dx, ax
call udelay
inc ecx
@ -1166,7 +1189,6 @@ ee_get_width:
.give_up:
DEBUGF 2, "Eeprom not found!\n"
xor al, al
out dx, al ; de-activate eeprom
@ -1195,9 +1217,8 @@ mdio_read:
DEBUGF 1,"MDIO read\n"
shl ecx, 21 ; PHY addr
shl edx, 16 ; PHY reg addr
mov eax, ecx
shl edx, 16 ; PHY reg addr
or eax, edx
or eax, 10b shl 26 ; read opcode
@ -1213,6 +1234,8 @@ mdio_read:
ret
; ax = data
; cx = phy addr
; dx = phy reg addr
@ -1245,14 +1268,9 @@ mdio_write:
ret
read_mac:
ret
align 4
MAC_read_eeprom:
mac_read_eeprom:
mov esi, 0
call ee_read
@ -1270,16 +1288,6 @@ MAC_read_eeprom:
ret
align 4
MAC_write:
;;;;
ret
; End of code
@ -1297,7 +1305,6 @@ confcmd_data db 22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1
device_id_list:
dw 0x1029
dw 0x1030
dw 0x1031