MTD80x network driver: Now in PE format. Added link detection and more specific device names. Fixed typo in PE network drivers.

git-svn-id: svn://kolibrios.org@4580 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2014-02-20 19:35:01 +00:00
parent 9fbd54b84a
commit f2707b7f34
4 changed files with 278 additions and 338 deletions

View File

@ -635,7 +635,7 @@ start_i8254x:
mov eax, [esi + REG_ICR] ; Clear pending interrupts mov eax, [esi + REG_ICR] ; Clear pending interrupts
mov [ebx + device.mtu], 1514 mov [ebx + device.mtu], 1514
mov [ebx + device.state], ETH_LINK_UNKOWN ; Set link state to unknown mov [ebx + device.state], ETH_LINK_UNKNOWN ; Set link state to unknown
xor eax, eax xor eax, eax
ret ret

View File

@ -14,10 +14,12 @@
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
format MS COFF format PE DLL native
entry START
API_VERSION = 0x01000100 CURRENT_API = 0x0200
DRIVER_VERSION = 5 COMPATIBLE_API = 0x0100
API_VERSION = (COMPATIBLE_API shl 16) + CURRENT_API
MAX_DEVICES = 16 MAX_DEVICES = 16
@ -28,17 +30,13 @@ format MS COFF
NUM_TX_DESC = 6 NUM_TX_DESC = 6
NUM_RX_DESC = 12 NUM_RX_DESC = 12
section '.flat' readable writable executable
include '../proc32.inc'
include '../struct.inc' include '../struct.inc'
include '../macros.inc' include '../macros.inc'
include '../proc32.inc'
include '../imports.inc'
include '../fdo.inc' include '../fdo.inc'
include '../netdrv.inc' include '../netdrv_pe.inc'
public START
public service_proc
public version
; for different PHY ; for different PHY
@ -249,68 +247,45 @@ public version
virtual at 0 struct descriptor
status dd ?
control dd ?
buffer dd ?
next_desc dd ?
mtd_desc: next_desc_logical dd ?
.status dd ? skbuff dd ?
.control dd ? reserved1 dd ?
.buffer dd ? reserved2 dd ?
.next_desc dd ? ends
.next_desc_logical dd ?
.skbuff dd ?
.reserved1 dd ?
.reserved2 dd ?
.size = $
end virtual
virtual at ebx struct device ETH_DEVICE
device: io_addr dd ?
pci_bus dd ?
ETH_DEVICE pci_dev dd ?
irq_line db ?
.tx_desc rb NUM_TX_DESC*mtd_desc.size dev_id dw ?
.rx_desc rb NUM_RX_DESC*mtd_desc.size flags dd ?
crvalue dd ?
.io_addr dd ? bcrvalue dd ?
.pci_bus dd ? cur_rx dd ?
.pci_dev dd ? cur_tx dd ?
.irq_line db ? default_port dd ?
.dev_id dw ? PHYType dd ?
.flags dd ?
.crvalue dd ?
.bcrvalue dd ?
.cur_rx dd ?
.cur_tx dd ?
; These values are keep track of the transceiver/media in use.
.linkok dd ?
.line_speed dd ?
.duplexmode dd ?
.default_port dd ?
.PHYType dd ?
; MII transceiver section. ; MII transceiver section.
mii_cnt dd ? ; MII device addresses.
phys db ? ; MII device addresses.
.mii_cnt dd ? ; MII device addresses. ; descriptors
.phys db ? ; MII device addresses. rb 0x100 - ($ and 0xff) ; align 256
tx_desc rb NUM_TX_DESC*sizeof.descriptor
rx_desc rb NUM_RX_DESC*sizeof.descriptor
device_size = $ - device ends
end virtual
section '.flat' code readable align 16
;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;; ;; ;;
@ -319,21 +294,17 @@ section '.flat' code readable align 16
;; (standard driver proc) ;; ;; (standard driver proc) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 4 proc START c, reason:dword, cmdline:dword
proc START stdcall, state:dword
cmp [state], 1 cmp [reason], DRV_ENTRY
jne .exit jne .fail
.entry: DEBUGF 1,"Loading driver\n"
invoke RegService, my_service, service_proc
DEBUGF 2,"Loading driver\n"
stdcall RegService, my_service, service_proc
ret ret
.fail: .fail:
.exit: xor eax, eax
xor eax, eax
ret ret
endp endp
@ -346,7 +317,6 @@ endp
;; (standard driver proc) ;; ;; (standard driver proc) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 4
proc service_proc stdcall, ioctl:dword proc service_proc stdcall, ioctl:dword
mov edx, [ioctl] mov edx, [ioctl]
@ -388,9 +358,9 @@ proc service_proc stdcall, ioctl:dword
mov ax, [eax+1] ; mov ax, [eax+1] ;
.nextdevice: .nextdevice:
mov ebx, [esi] mov ebx, [esi]
cmp al, byte[device.pci_bus] cmp al, byte[ebx + device.pci_bus]
jne @f 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 je .find_devicenum ; Device is already loaded, let's find it's device number
@@: @@:
add esi, 4 add esi, 4
@ -402,33 +372,35 @@ 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, device_size, .fail allocate_and_clear ebx, sizeof.device, .fail
; Fill in the direct call addresses into the struct ; Fill in the direct call addresses into the struct
mov [device.reset], reset mov [ebx + device.reset], reset
mov [device.transmit], transmit mov [ebx + device.transmit], transmit
mov [device.unload], unload mov [ebx + device.unload], unload
mov [device.name], my_service mov [ebx + device.name], my_service
; save the pci bus and device numbers ; save the pci bus and device numbers
mov eax, [edx + IOCTL.input] mov eax, [edx + IOCTL.input]
movzx ecx, byte[eax+1] movzx ecx, byte[eax+1]
mov [device.pci_bus], ecx mov [ebx + device.pci_bus], ecx
movzx ecx, byte[eax+2] 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 ; Now, it's time to find the base io addres of the PCI device
PCI_find_io 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 ; 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",\ 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]: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 ; 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
@ -440,8 +412,8 @@ proc service_proc stdcall, ioctl:dword
test eax, eax test eax, eax
jnz .err2 ; If an error occured, exit jnz .err2 ; If an error occured, exit
mov [device.type], NET_TYPE_ETH mov [ebx + device.type], NET_TYPE_ETH
call NetRegDev invoke NetRegDev
cmp eax, -1 cmp eax, -1
je .destroy je .destroy
@ -452,7 +424,7 @@ proc service_proc stdcall, ioctl:dword
.find_devicenum: .find_devicenum:
DEBUGF 2,"Trying to find device number of already registered device\n" 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 ; into a device number in edi
mov eax, edi ; Application wants it in eax instead mov eax, edi ; Application wants it in eax instead
DEBUGF 2,"Kernel says: %u\n", eax DEBUGF 2,"Kernel says: %u\n", eax
@ -467,7 +439,7 @@ proc service_proc stdcall, ioctl:dword
dec [devices] dec [devices]
.err: .err:
DEBUGF 2,"removing device structure\n" DEBUGF 2,"removing device structure\n"
stdcall KernelFree, ebx invoke KernelFree, ebx
.fail: .fail:
or eax, -1 or eax, -1
ret ret
@ -501,7 +473,7 @@ unload:
; - call unregister function in kernel ; - call unregister function in kernel
; - Remove all allocated structures and buffers the card used ; - Remove all allocated structures and buffers the card used
or eax,-1 or eax, -1
ret ret
@ -514,55 +486,58 @@ ret
align 4 align 4
probe: probe:
DEBUGF 2,"Probing device\n" DEBUGF 1,"Probing\n"
PCI_make_bus_master ; Make the device a bus master
invoke PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
stdcall PciRead32, [device.pci_bus], [device.pci_dev], 0 or al, PCI_CMD_MASTER
invoke PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
; Check vendor/device id's
invoke PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], 0
cmp ax, 0x1516 cmp ax, 0x1516
jne .notfound jne .notfound
shr eax, 16 shr eax, 16
mov [device.dev_id], ax mov [ebx + device.dev_id], ax
cmp ax, 0x0800 cmp ax, 0x0800
je .has_mii_xcvr je .mtd800
cmp ax, 0x0803 cmp ax, 0x0803
je .has_chip_xcvr je .mtd803
cmp ax, 0x0891 cmp ax, 0x0891
je .has_mii_xcvr je .mtd891
.notfound: .notfound:
DEBUGF 1,"Device not supported!\n" DEBUGF 2,"Device not supported!\n"
xor eax, eax xor eax, eax
dec eax dec eax
ret ret
.has_chip_xcvr: .mtd803:
mov [ebx + device.name], sz_mtd803
DEBUGF 1,"Device has chip xcvr\n" DEBUGF 1,"Device has chip xcvr\n"
jmp .xcvr_set jmp .xcvr_set
.has_mii_xcvr: .mtd800:
DEBUGF 1,"Device has mii xcvr\n" DEBUGF 1,"Device has mii xcvr\n"
mov [ebx + device.name], sz_mtd800
jmp .xcvr_set
.mtd891:
DEBUGF 1,"Device has mii xcvr\n"
mov [ebx + device.name], sz_mtd800
.xcvr_set: .xcvr_set:
call read_mac call read_mac
; Reset the chip to erase previous misconfiguration. ; Reset the chip to erase previous misconfiguration.
set_io [ebx + device.io_addr], 0
set_io 0 set_io [ebx + device.io_addr], BCR
set_io BCR
xor eax, eax xor eax, eax
inc eax inc eax
out dx, eax out dx, eax
; find the connected MII xcvrs ; find the connected MII xcvrs
cmp [ebx + device.dev_id], 0x0803
cmp [device.dev_id], 0x0803
je .is_803 je .is_803
; int phy, phy_idx = 0; ; int phy, phy_idx = 0;
@ -606,25 +581,22 @@ probe:
jmp .no_803 jmp .no_803
.is_803: .is_803:
mov [ebx + device.phys], 32
mov [device.phys], 32
; get phy type ; get phy type
set_io 0 set_io [ebx + device.io_addr], 0
set_io PHYIDENTIFIER set_io [ebx + device.io_addr], PHYIDENTIFIER
in eax, dx in eax, dx
cmp eax, MysonPHYID cmp eax, MysonPHYID
jne @f jne @f
mov [ebx + device.PHYType], MysonPHY
mov [device.PHYType], MysonPHY DEBUGF 1,"Myson PHY\n"
DEBUGF 1,"MysonPHY\n"
jmp .no_803 jmp .no_803
@@: @@:
mov [device.PHYType], OtherPHY
DEBUGF 1,"OtherPHY\n"
mov [ebx + device.PHYType], OtherPHY
DEBUGF 1,"Other PHY\n"
.no_803: .no_803:
;------- ;-------
@ -637,23 +609,20 @@ reset:
DEBUGF 1,"Resetting\n" DEBUGF 1,"Resetting\n"
;-------------------------------- ; attach irq handler
; insert irq handler on given irq movzx eax, [ebx + device.irq_line]
movzx eax, [device.irq_line]
DEBUGF 1,"Attaching int handler to irq %x\n", eax:1 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 test eax, eax
jnz @f jnz @f
DEBUGF 1,"Could not attach int handler!\n" DEBUGF 2,"Could not attach int handler!\n"
or eax, -1 or eax, -1
ret ret
@@: @@:
; Reset the chip to erase previous misconfiguration. ; Reset the chip to erase previous misconfiguration.
set_io [ebx + device.io_addr], 0
set_io 0 set_io [ebx + device.io_addr], BCR
set_io BCR
xor eax, eax xor eax, eax
inc eax inc eax
out dx, eax out dx, eax
@ -662,60 +631,49 @@ reset:
; Initialize other registers. ; Initialize other registers.
; Configure the PCI bus bursts and FIFO thresholds. ; Configure the PCI bus bursts and FIFO thresholds.
mov [ebx + device.bcrvalue], 0x10 ; little-endian, 8 burst length
mov [ebx + device.crvalue], 0xa00 ; 128 burst length
mov [device.bcrvalue], 0x10 ; little-endian, 8 burst length cmp [ebx + device.dev_id], 0x891
mov [device.crvalue], 0xa00 ; 128 burst length
cmp [device.dev_id], 0x891
jne @f jne @f
or [device.bcrvalue], 0x200 ; set PROG bit or [ebx + device.bcrvalue], 0x200 ; set PROG bit
or [device.crvalue], 0x02000000 ; set enhanced bit or [ebx + device.crvalue], 0x02000000 ; set enhanced bit
@@: @@:
or [ebx + device.crvalue], RxEnable + TxThreshold + TxEnable
or [device.crvalue], RxEnable + TxThreshold + TxEnable
call set_rx_mode call set_rx_mode
set_io 0 set_io [ebx + device.io_addr], 0
set_io BCR set_io [ebx + device.io_addr], BCR
mov eax, [device.bcrvalue] mov eax, [ebx + device.bcrvalue]
out dx, eax out dx, eax
set_io TCRRCR set_io [ebx + device.io_addr], TCRRCR
mov eax, [device.crvalue] mov eax, [ebx + device.crvalue]
out dx, eax out dx, eax
call getlinkstatus call getlinkstatus
call getlinktype
; Restart Rx engine if stopped. ; Restart Rx engine if stopped.
set_io [ebx + device.io_addr], 0
set_io 0 set_io [ebx + device.io_addr], RXPDR
set_io RXPDR
xor eax, eax xor eax, eax
out dx, eax out dx, eax
; Enable interrupts ; Enable interrupts
set_io [ebx + device.io_addr], ISR
set_io 0
set_io ISR
mov eax, FBE or TUNF or CNTOVF or RBU or TI or RI mov eax, FBE or TUNF or CNTOVF or RBU or TI or RI
out dx, eax out dx, eax
set_io IMR set_io [ebx + device.io_addr], IMR
out dx, eax out dx, eax
; clear packet/byte counters ; clear packet/byte counters
xor eax, eax xor eax, eax
lea edi, [device.bytes_tx] lea edi, [ebx + device.bytes_tx]
mov ecx, 6 mov ecx, 6
rep stosd rep stosd
mov [device.mtu], 1514 mov [ebx + device.mtu], 1514
; Set link state to unknown
mov [device.state], ETH_LINK_UNKOWN
xor eax, eax xor eax, eax
ret ret
@ -728,73 +686,69 @@ init_ring:
DEBUGF 1,"initializing rx and tx ring\n" DEBUGF 1,"initializing rx and tx ring\n"
; Initialize all Rx descriptors ; Initialize all Rx descriptors
lea esi, [ebx + device.rx_desc]
lea esi, [device.rx_desc] mov [ebx + device.cur_rx], esi
mov [device.cur_rx], esi
mov ecx, NUM_RX_DESC mov ecx, NUM_RX_DESC
.rx_desc_loop: .rx_desc_loop:
mov [esi + mtd_desc.status], RXOWN mov [esi + descriptor.status], RXOWN
mov [esi + mtd_desc.control], 1536 shl RBSShift mov [esi + descriptor.control], 1536 shl RBSShift
lea eax, [esi + mtd_desc.size] lea eax, [esi + sizeof.descriptor]
mov [esi + mtd_desc.next_desc_logical], eax mov [esi + descriptor.next_desc_logical], eax
push ecx esi push ecx esi
GetRealAddr invoke GetPhysAddr
mov [esi + mtd_desc.next_desc], eax mov [esi + descriptor.next_desc], eax
stdcall KernelAlloc, 1536 invoke KernelAlloc, 1536
pop esi pop esi
push esi push esi
mov [esi + mtd_desc.skbuff], eax mov [esi + descriptor.skbuff], eax
call GetPgAddr invoke GetPgAddr
pop esi ecx pop esi ecx
mov [esi + mtd_desc.buffer], eax mov [esi + descriptor.buffer], eax
add esi, mtd_desc.size add esi, sizeof.descriptor
loop .rx_desc_loop loop .rx_desc_loop
; Mark the last entry as wrapping the ring. ; Mark the last entry as wrapping the ring.
lea eax, [ebx + device.rx_desc]
lea eax, [device.rx_desc] mov [esi - sizeof.descriptor + descriptor.next_desc_logical], eax
mov [esi - mtd_desc.size + mtd_desc.next_desc_logical], eax
push esi push esi
GetRealAddr invoke GetPhysAddr
pop esi pop esi
mov [esi - mtd_desc.size + mtd_desc.next_desc], eax mov [esi - sizeof.descriptor + descriptor.next_desc], eax
set_io 0 set_io [ebx + device.io_addr], 0
set_io RXLBA set_io [ebx + device.io_addr], RXLBA
out dx, eax out dx, eax
; Initialize all Tx descriptors ; Initialize all Tx descriptors
lea esi, [ebx + device.tx_desc]
lea esi, [device.tx_desc] mov [ebx + device.cur_tx], esi
mov [device.cur_tx], esi
mov ecx, NUM_TX_DESC mov ecx, NUM_TX_DESC
.tx_desc_loop: .tx_desc_loop:
mov [esi + mtd_desc.status], 0 mov [esi + descriptor.status], 0
lea eax, [esi + mtd_desc.size] lea eax, [esi + sizeof.descriptor]
mov [esi + mtd_desc.next_desc_logical], eax mov [esi + descriptor.next_desc_logical], eax
push ecx esi push ecx esi
GetRealAddr invoke GetPhysAddr
pop esi ecx pop esi ecx
mov [esi + mtd_desc.next_desc], eax mov [esi + descriptor.next_desc], eax
mov [esi + mtd_desc.skbuff], 0 mov [esi + descriptor.skbuff], 0
add esi, mtd_desc.size add esi, sizeof.descriptor
loop .tx_desc_loop loop .tx_desc_loop
; Mark the last entry as wrapping the ring. ; Mark the last entry as wrapping the ring.
lea eax, [ebx + device.tx_desc]
lea eax, [device.tx_desc] mov [esi - sizeof.descriptor + descriptor.next_desc_logical], eax
mov [esi - mtd_desc.size + mtd_desc.next_desc_logical], eax
push esi push esi
GetRealAddr invoke GetPhysAddr
pop esi pop esi
mov [esi - mtd_desc.size + mtd_desc.next_desc], eax mov [esi - sizeof.descriptor + descriptor.next_desc], eax
set_io 0 set_io [ebx + device.io_addr], 0
set_io TXLBA set_io [ebx + device.io_addr], TXLBA
out dx, eax out dx, eax
ret ret
@ -806,17 +760,16 @@ set_rx_mode:
DEBUGF 1,"Setting RX mode\n" DEBUGF 1,"Setting RX mode\n"
; Too many to match, or accept all multicasts. ; Too many to match, or accept all multicasts.
set_io [ebx + device.io_addr], 0
set_io 0 set_io [ebx + device.io_addr], MAR0
set_io MAR0
xor eax, eax xor eax, eax
not eax not eax
out dx, eax out dx, eax
set_io MAR1 set_io [ebx + device.io_addr], MAR1
out dx, eax out dx, eax
and [device.crvalue], not (RxModeMask) and [ebx + device.crvalue], not (RxModeMask)
or [device.crvalue], AcceptBroadcast + AcceptMulticast + AcceptMyPhys or [ebx + device.crvalue], AcceptBroadcast + AcceptMulticast + AcceptMyPhys
ret ret
@ -826,79 +779,53 @@ getlinkstatus:
DEBUGF 1,"Getting link status\n" DEBUGF 1,"Getting link status\n"
mov [device.linkok], 0 mov [ebx + device.state], ETH_LINK_DOWN ; assume link is dead
cmp [device.PHYType], MysonPHY cmp [ebx + device.PHYType], MysonPHY
jne .no_myson_phy jne .no_myson_phy
set_io [ebx + device.io_addr], 0
set_io 0 set_io [ebx + device.io_addr], BMCRSR
set_io BMCRSR
mov ecx, 1000
.loop1:
in eax, dx in eax, dx
test eax, LinkIsUp2 test eax, LinkIsUp2
jnz .link_ok jnz getlinktype
push ecx edx ebx
mov esi, 10
call Sleep
pop ebx edx ecx
loop .loop1
ret ret
.no_myson_phy: .no_myson_phy:
set_io [ebx + device.io_addr], 0
; for (i = 0; i < DelayTime; ++i) { set_io [ebx + device.io_addr], BMCRSR
; if (mdio_read(nic, mtdx.phys[0], MII_BMSR) & BMSR_LSTATUS) { in eax, dx
; mtdx.linkok = 1; test eax, LinkIsUp
; return; jnz getlinktype
; }
; m80x_delay(100);
ret ret
.link_ok:
DEBUGF 1,"Link is up\n"
inc [device.linkok]
ret
align 4
getlinktype: getlinktype:
DEBUGF 1,"Getting link type\n" DEBUGF 1,"Getting link type\n"
cmp [ebx + device.PHYType], MysonPHY
cmp [device.PHYType], MysonPHY
jne .no_myson_phy jne .no_myson_phy
DEBUGF 1,"myson PHY\n" DEBUGF 1,"myson PHY\n"
set_io [ebx + device.io_addr], 0
set_io 0 set_io [ebx + device.io_addr], TCRRCR
set_io TCRRCR
in eax, dx in eax, dx
mov [device.duplexmode], 1 ; 1 = half duplex
test eax, FD test eax, FD
jne @f jz @f
DEBUGF 1,"full duplex\n" DEBUGF 1,"full duplex\n"
inc [device.duplexmode] ; 2 = full duplex or [ebx + device.state], ETH_LINK_FD
@@: @@:
mov [device.line_speed], 1 ; 1 = 10M
test eax, PS10 test eax, PS10
jne @f jnz @f
DEBUGF 1,"100mbit\n" DEBUGF 1,"100mbit\n"
inc [device.line_speed] ; 2 = 100M or [ebx + device.state], ETH_LINK_100M
ret
@@: @@:
DEBUGF 1,"10mbit\n"
or [ebx + device.state], ETH_LINK_10M
ret ret
.no_myson_phy: .no_myson_phy:
DEBUGF 1,"not a myson PHY\n"
DEBUGF 1,"no myson phy\n" mov [ebx + device.state], ETH_LINK_UNKNOWN
; if (mtdx.PHYType equ= SeeqPHY) { /* this PHY is SEEQ 80225 */ ; if (mtdx.PHYType equ= SeeqPHY) { /* this PHY is SEEQ 80225 */
; unsigned int data; ; unsigned int data;
@ -982,7 +909,6 @@ getlinktype:
; mtdx.crvalue |= PS1000; ; mtdx.crvalue |= PS1000;
; if (mtdx.duplexmode equ= 2) ; if (mtdx.duplexmode equ= 2)
; mtdx.crvalue |= FD; ; mtdx.crvalue |= FD;
;
ret ret
@ -999,76 +925,84 @@ getlinktype:
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 4 proc transmit stdcall bufferptr, buffersize
transmit:
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8] pushf
mov eax, [esp+4] 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",\ 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+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+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
[eax+13]:2,[eax+12]:2 [eax+13]:2,[eax+12]:2
cmp dword [esp+8], 1514 cmp [buffersize], 1514
ja .fail ja .fail
cmp [buffersize], 60
jb .fail
mov esi, [device.cur_tx] mov esi, [ebx + device.cur_tx]
test [esi + mtd_desc.status], TXOWN test [esi + descriptor.status], TXOWN
jnz .fail jnz .fail
push [esi + mtd_desc.next_desc_logical] push [esi + descriptor.next_desc_logical]
pop [device.cur_tx] pop [ebx + device.cur_tx]
mov eax, [esp + 4] mov eax, [bufferptr]
mov [esi + mtd_desc.skbuff], eax mov [esi + descriptor.skbuff], eax
GetRealAddr invoke GetPhysAddr
mov [esi + mtd_desc.buffer], eax mov [esi + descriptor.buffer], eax
mov eax, [esp + 8] mov eax, [buffersize]
mov ecx, eax mov ecx, eax
shl eax, PKTSShift ; packet size shl eax, PKTSShift ; packet size
shl ecx, TBSShift shl ecx, TBSShift
or eax, ecx or eax, ecx
or eax, TXIC + TXLD + TXFD + CRCEnable + PADEnable or eax, TXIC + TXLD + TXFD + CRCEnable + PADEnable
mov [esi + mtd_desc.control], eax mov [esi + descriptor.control], eax
mov [esi + mtd_desc.status], TXOWN mov [esi + descriptor.status], TXOWN
; Update stats ; Update stats
inc [device.packets_tx] inc [ebx + device.packets_tx]
mov eax, [esp+8] mov eax, [buffersize]
add dword [device.bytes_tx], eax add dword[ebx + device.bytes_tx], eax
adc dword [device.bytes_tx + 4], 0 adc dword[ebx + device.bytes_tx + 4], 0
; TX Poll ; TX Poll
set_io 0 set_io [ebx + device.io_addr], 0
set_io TXPDR set_io [ebx + device.io_addr], TXPDR
xor eax, eax xor eax, eax
out dx, eax out dx, eax
DEBUGF 1,"transmit ok\n" DEBUGF 1,"Transmit OK\n"
popf
xor eax, eax xor eax, eax
ret 8 ret
.fail: .fail:
DEBUGF 1,"transmit failed\n" DEBUGF 2,"Transmit failed\n"
stdcall KernelFree, [esp + 4] invoke KernelFree, [bufferptr]
popf
or eax, -1 or eax, -1
ret 8 ret
endp
align 4 align 4
read_mac: read_mac:
set_io 0 set_io [ebx + device.io_addr], 0
set_io PAR0 set_io [ebx + device.io_addr], PAR0
lea edi, [device.mac] lea edi, [ebx + device.mac]
insd insd
set_io PAR1 set_io [ebx + device.io_addr], PAR1
insw insw
DEBUGF 1,"MAC = %x-%x-%x-%x-%x-%x\n",\ 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 ret
@ -1101,8 +1035,8 @@ int_handler:
.nextdevice: .nextdevice:
mov ebx, [esi] mov ebx, [esi]
set_io 0 set_io [ebx + device.io_addr], 0
set_io ISR set_io [ebx + device.io_addr], ISR
in eax, dx in eax, dx
out dx, eax ; send it back to ACK out dx, eax ; send it back to ACK
test eax, eax test eax, eax
@ -1125,79 +1059,84 @@ int_handler:
jz .no_rx jz .no_rx
push ax push ax
.rx_loop: .rx_loop:
mov esi, [device.cur_rx] mov esi, [ebx + device.cur_rx]
test [esi + mtd_desc.status], RXOWN test [esi + descriptor.status], RXOWN
jnz .fail_rx jnz .rx_done
push ebx push ebx
push .rx_complete push .rx_complete
mov ecx, [esi + mtd_desc.status] mov ecx, [esi + descriptor.status]
shr ecx, FLNGShift shr ecx, FLNGShift
sub ecx, 4 ; we dont need CRC sub ecx, 4 ; we dont need CRC
push ecx push ecx
DEBUGF 1,"Received %u bytes\n", ecx DEBUGF 1,"Received %u bytes\n", ecx
; Update stats ; Update stats
add dword[device.bytes_rx], ecx add dword[ebx + device.bytes_rx], ecx
adc dword[device.bytes_rx + 4], 0 adc dword[ebx + device.bytes_rx + 4], 0
inc [device.packets_rx] inc [ebx + device.packets_rx]
push [esi + mtd_desc.skbuff] push [esi + descriptor.skbuff]
jmp Eth_input jmp [Eth_input]
.rx_complete: .rx_complete:
pop ebx pop ebx
mov esi, [device.cur_rx] mov esi, [ebx + device.cur_rx]
mov [esi + mtd_desc.control], 1536 shl RBSShift mov [esi + descriptor.control], 1536 shl RBSShift
push esi push esi
stdcall KernelAlloc, 1536 invoke KernelAlloc, 1536
pop esi pop esi
mov [esi + mtd_desc.skbuff], eax mov [esi + descriptor.skbuff], eax
call GetPgAddr invoke GetPgAddr
mov [esi + mtd_desc.buffer], eax mov [esi + descriptor.buffer], eax
mov [esi + mtd_desc.status], RXOWN mov [esi + descriptor.status], RXOWN
push [esi + mtd_desc.next_desc_logical] push [esi + descriptor.next_desc_logical]
pop [device.cur_rx] pop [ebx + device.cur_rx]
jmp .rx_loop jmp .rx_loop
;
; while( ( mtdx.cur_rx->status & RXOWN ) == 0 )
; {
; mtdx.cur_rx->status = RXOWN;
; mtdx.cur_rx = mtdx.cur_rx->next_desc_logical;
; }
;
; /* Restart Rx engine if stopped. */
; outl(0, mtdx.ioaddr + RXPDR);
.fail_rx: .rx_done:
DEBUGF 1,"RX done\n" DEBUGF 1,"RX done\n"
pop ax
; Restart Rx engine if stopped.
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], RXPDR
xor eax, eax
out dx, eax
pop ax
.no_rx: .no_rx:
test ax, TI ; transmit interrupt test ax, TI ; transmit interrupt
jz .no_tx jz .no_tx
DEBUGF 1,"TX\n" DEBUGF 1,"TX\n"
push ax push ax
lea esi, [device.tx_desc] lea esi, [ebx + device.tx_desc]
mov ecx, NUM_TX_DESC mov ecx, NUM_TX_DESC
.tx_loop: .tx_loop:
test [esi + mtd_desc.status], TXOWN test [esi + descriptor.status], TXOWN
jnz .skip_this_one jnz .skip_this_one
mov eax, [esi + mtd_desc.skbuff] mov eax, [esi + descriptor.skbuff]
test eax, eax test eax, eax
je .skip_this_one je .skip_this_one
mov [esi + mtd_desc.skbuff], 0 mov [esi + descriptor.skbuff], 0
DEBUGF 1,"freeing buffer: 0x%x\n", eax DEBUGF 1,"freeing buffer: 0x%x\n", eax
stdcall KernelFree, eax invoke KernelFree, eax
.skip_this_one: .skip_this_one:
mov esi, [esi + mtd_desc.next_desc_logical] mov esi, [esi + descriptor.next_desc_logical]
loop .tx_loop loop .tx_loop
pop ax pop ax
.no_tx: .no_tx:
test ax, LSCStatus
jz .no_link_change
push ax
call getlinkstatus
pop ax
.no_link_change:
; test ax, TBU ; test ax, TBU
; jz .no_tbu ; jz .no_tbu
; DEBUGF 2,"Transmit buffer unavailable!\n" ; DEBUGF 2,"Transmit buffer unavailable!\n"
@ -1213,22 +1152,23 @@ int_handler:
; End of code ; End of code
align 4 ; Place all initialised data here
devices dd 0 data fixups
version dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF) end data
my_service db 'mtd80x',0 ; max 16 chars include zero
include '../peimport.inc'
; 0x1516, 0x0800, "MTD800", "Myson MTD800" my_service db 'mtd80x',0 ; max 16 chars include zero
; 0x1516, 0x0803, "MTD803", "Surecom EP-320X"
; 0x1516, 0x0891, "MTD891", "Myson MTD891" sz_mtd800 db "Myson MTD800", 0
sz_mtd803 db "Surecom EP-320X", 0
sz_mtd891 db "Myson MTD891", 0
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 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

View File

@ -916,7 +916,7 @@ reset:
mov [ebx + device.mtu], 1514 mov [ebx + device.mtu], 1514
; get link status ; get link status
mov [ebx + device.state], ETH_LINK_UNKOWN mov [ebx + device.state], ETH_LINK_UNKNOWN
call check_media call check_media

View File

@ -34,11 +34,11 @@ include 'mii.inc'
; Link state ; Link state
ETH_LINK_DOWN = 0 ; Link is down ETH_LINK_DOWN = 0 ; Link is down
ETH_LINK_UNKOWN = 1b ; There could be an active link ETH_LINK_UNKNOWN= 1b ; There could be an active link
ETH_LINK_FD = 10b ; full duplex flag ETH_LINK_FD = 10b ; full duplex flag
ETH_LINK_10M = 100b ; 10 mbit ETH_LINK_10M = 100b ; 10 mbit
ETH_LINK_100M = 1000b ; 100 mbit ETH_LINK_100M = 1000b ; 100 mbit
ETH_LINK_1G = 10000b ; gigabit ETH_LINK_1G = 1100b ; gigabit
; Macro to easily set i/o addresses to access device. ; Macro to easily set i/o addresses to access device.
; In the beginning of a procedure (or ofter edx may have been destroyed), ; In the beginning of a procedure (or ofter edx may have been destroyed),