Fixed PCnet32 ethernet driver

git-svn-id: svn://kolibrios.org@781 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2008-03-28 23:42:28 +00:00
parent c521e1fc73
commit b384868a4d

View File

@ -7,7 +7,13 @@
;; ;;
;; Ethernet driver for Menuet OS ;;
;; ;;
;; Version 1.0 31 July 2004 ;;
;; - Version 1.0 31 July 2004: ;;
;; Initial release ;;
;; ;;
;; - Version 1.01 29 March 2008: ;;
;; Adapted to work with kolibrios flat kernel ;;
;; Debug info is updated, and now uses DEBUGF macro ;;
;; by hidnplayr@kolibrios.org ;;
;; ;;
;; This driver is based on the PCNet32 driver from ;;
;; the etherboot 5.0.6 project. The copyright statement is ;;
@ -25,24 +31,6 @@
$Revision$
;macro PutStr X
;{
; local .__xyz1
; local .__xyz2
; push esi
; mov esi,.__xyz1
; call sys_msg_board_str
; push ebx
; mov ebx,1
; call delay_hs
; pop ebx
; jmp .__xyz2
;.__xyz1:
; db X
; db 13,10,0
;.__xyz2:
; pop esi
;}
PCNET32_PORT_AUI equ 0x00
PCNET32_PORT_10BT equ 0x01
PCNET32_PORT_GPSI equ 0x02
@ -52,100 +40,106 @@ PCNET32_PORT_ASEL equ 0x04
PCNET32_PORT_100 equ 0x40
PCNET32_PORT_FD equ 0x80
PCNET32_DMA_MASK equ 0xffffffff
PCNET32_LOG_TX_BUFFERS equ 1
PCNET32_LOG_RX_BUFFERS equ 2
PCNET32_TX_RING_SIZE equ (1 shl PCNET32_LOG_TX_BUFFERS)
PCNET32_TX_RING_MOD_MASK equ (PCNET32_TX_RING_SIZE-1)
PCNET32_TX_RING_LEN_BITS equ 0
PCNET32_RX_RING_SIZE equ (1 shl PCNET32_LOG_RX_BUFFERS)
PCNET32_RX_RING_MOD_MASK equ (PCNET32_RX_RING_SIZE-1)
PCNET32_RX_RING_LEN_BITS equ (PCNET32_LOG_RX_BUFFERS shl 4)
PCNET32_PKT_BUF_SZ equ 1544
PCNET32_PKT_BUF_SZ_NEG equ 0xf9f8
PCNET32_LOG_TX_BUFFERS equ 1
PCNET32_LOG_RX_BUFFERS equ 2
PCNET32_TX_RING_SIZE equ (1 shl PCNET32_LOG_TX_BUFFERS)
PCNET32_TX_RING_MOD_MASK equ (PCNET32_TX_RING_SIZE-1)
PCNET32_TX_RING_LEN_BITS equ 0
PCNET32_RX_RING_SIZE equ (1 shl PCNET32_LOG_RX_BUFFERS)
PCNET32_RX_RING_MOD_MASK equ (PCNET32_RX_RING_SIZE-1)
PCNET32_RX_RING_LEN_BITS equ (PCNET32_LOG_RX_BUFFERS shl 4)
PCNET32_PKT_BUF_SZ equ 1544
PCNET32_PKT_BUF_SZ_NEG equ 0xf9f8
pcnet32_txb equ (eth_data_start)
pcnet32_rxb equ ((pcnet32_txb+(PCNET32_PKT_BUF_SZ*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0)
pcnet32_tx_ring equ ((pcnet32_rxb+(PCNET32_PKT_BUF_SZ*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0)
pcnet32_rx_ring equ ((pcnet32_tx_ring+(16*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0)
virtual at ((pcnet32_rx_ring+(16*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0)
pcnet32_private:
.mode dw ?
.tlen_rlen dw ?
.phys_addr db ?,?,?,?,?,?
.reserved dw ?
.filter dd ?,?
.rx_ring dd ?
.tx_ring dd ?
.cur_rx dd ?
.cur_tx dd ?
.dirty_rx dd ?
.dirty_tx dd ?
.tx_full db ?
.options dd ?
.full_duplex db ?
.chip_version dd ?
.mii db ?
.ltint db ?
.dxsuflo db ?
.fset db ?
.fdx db ?
.mode dw ?
.tlen_rlen dw ?
.phys_addr db ?,?,?,?,?,?
.reserved dw ?
.filter dd ?,?
.rx_ring dd ?
.tx_ring dd ?
.cur_rx dd ?
.cur_tx dd ?
.dirty_rx dd ?
.dirty_tx dd ?
.tx_full db ?
.options dd ?
.full_duplex db ?
.chip_version dd ?
.mii db ?
.ltint db ?
.dxsuflo db ?
.fset db ?
.fdx db ?
end virtual
virtual at 0
pcnet32_rx_head:
.base dd ?
.buf_length dw ?
.status dw ?
.msg_length dd ?
.reserved dd ?
.base dd ?
.buf_length dw ?
.status dw ?
.msg_length dd ?
.reserved dd ?
end virtual
virtual at 0
pcnet32_tx_head:
.base dd ?
.length dw ?
.status dw ?
.misc dd ?
.reserved dd ?
.base dd ?
.length dw ?
.status dw ?
.misc dd ?
.reserved dd ?
end virtual
uglobal
pcnet32_access:
.read_csr dd ?
.write_csr dd ?
.read_bcr dd ?
.write_bcr dd ?
.read_rap dd ?
.write_rap dd ?
.reset dd ?
.read_csr dd ?
.write_csr dd ?
.read_bcr dd ?
.write_bcr dd ?
.read_rap dd ?
.write_rap dd ?
.reset dd ?
endg
iglobal
pcnet32_options_mapping:
dd PCNET32_PORT_ASEL ; 0 Auto-select
dd PCNET32_PORT_AUI ; 1 BNC/AUI
dd PCNET32_PORT_AUI ; 2 AUI/BNC
dd PCNET32_PORT_ASEL ; 3 not supported
dd PCNET32_PORT_ASEL ; 0 Auto-select
dd PCNET32_PORT_AUI ; 1 BNC/AUI
dd PCNET32_PORT_AUI ; 2 AUI/BNC
dd PCNET32_PORT_ASEL ; 3 not supported
dd PCNET32_PORT_10BT or PCNET32_PORT_FD ; 4 10baseT-FD
dd PCNET32_PORT_ASEL ; 5 not supported
dd PCNET32_PORT_ASEL ; 6 not supported
dd PCNET32_PORT_ASEL ; 7 not supported
dd PCNET32_PORT_ASEL ; 8 not supported
dd PCNET32_PORT_MII ; 9 MII 10baseT
dd PCNET32_PORT_MII or PCNET32_PORT_FD ; 10 MII 10baseT-FD
dd PCNET32_PORT_MII ; 11 MII (autosel)
dd PCNET32_PORT_10BT ; 12 10BaseT
dd PCNET32_PORT_ASEL ; 5 not supported
dd PCNET32_PORT_ASEL ; 6 not supported
dd PCNET32_PORT_ASEL ; 7 not supported
dd PCNET32_PORT_ASEL ; 8 not supported
dd PCNET32_PORT_MII ; 9 MII 10baseT
dd PCNET32_PORT_MII or PCNET32_PORT_FD ; 10 MII 10baseT-FD
dd PCNET32_PORT_MII ; 11 MII (autosel)
dd PCNET32_PORT_10BT ; 12 10BaseT
dd PCNET32_PORT_MII or PCNET32_PORT_100 ; 13 MII 100BaseTx
dd PCNET32_PORT_MII or PCNET32_PORT_100 or PCNET32_PORT_FD ; 14 MII 100BaseTx-FD
dd PCNET32_PORT_ASEL ; 15 not supported
dd PCNET32_PORT_MII or PCNET32_PORT_100 or PCNET32_PORT_FD ; 14 MII 100BaseTx-FD
dd PCNET32_PORT_ASEL ; 15 not supported
endg
PCNET32_WIO_RDP equ 0x10
PCNET32_WIO_RAP equ 0x12
PCNET32_WIO_RESET equ 0x14
PCNET32_WIO_BDP equ 0x16
PCNET32_DWIO_RDP equ 0x10
PCNET32_DWIO_RAP equ 0x14
PCNET32_DWIO_RESET equ 0x18
PCNET32_DWIO_BDP equ 0x1C
PCNET32_TOTAL_SIZE equ 0x20
PCNET32_WIO_RDP equ 0x10
PCNET32_WIO_RAP equ 0x12
PCNET32_WIO_RESET equ 0x14
PCNET32_WIO_BDP equ 0x16
PCNET32_DWIO_RDP equ 0x10
PCNET32_DWIO_RAP equ 0x14
PCNET32_DWIO_RESET equ 0x18
PCNET32_DWIO_BDP equ 0x1C
PCNET32_TOTAL_SIZE equ 0x20
; ebx - index
; return:
; eax - data
@ -339,6 +333,8 @@ pcnet32_dwio:
dd pcnet32_dwio_reset
endg
pcnet32_init_ring:
mov [pcnet32_private.tx_full],0
mov [pcnet32_private.cur_rx],0
@ -348,6 +344,7 @@ pcnet32_init_ring:
mov edi,pcnet32_rx_ring
mov ecx,PCNET32_RX_RING_SIZE
mov ebx,pcnet32_rxb
sub ebx,OS_BASE
.rx_init:
mov [edi+pcnet32_rx_head.base],ebx
mov [edi+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG
@ -369,9 +366,17 @@ pcnet32_init_ring:
cld
movsd
movsw
mov dword [pcnet32_private.rx_ring],pcnet32_rx_ring
mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring
mov eax,pcnet32_rx_ring
sub eax,OS_BASE
mov dword [pcnet32_private.rx_ring],eax
mov eax,pcnet32_tx_ring
sub eax,OS_BASE
mov dword [pcnet32_private.tx_ring],eax
ret
pcnet32_reset:
; Reset PCNET32
mov ebp,[io_addr]
@ -443,7 +448,7 @@ pcnet32_reset:
test [pcnet32_private.options],PCNET32_PORT_ASEL
jz .L9
mov ebx,32
; PutStr "ASEL, enable auto-negotiation"
; DEBUGF 1," K : ASEL, enable auto-negotiation\n"
call dword [pcnet32_access.read_bcr]
and eax,not 0x98
or eax,0x20
@ -465,9 +470,11 @@ pcnet32_reset:
call pcnet32_init_ring
mov ebx,1
mov eax,pcnet32_private
sub eax,OS_BASE
and eax,0xffff
call dword [pcnet32_access.write_csr]
mov eax,pcnet32_private
sub eax,OS_BASE
mov ebx,2
shr eax,16
call dword [pcnet32_access.write_csr]
@ -485,33 +492,36 @@ pcnet32_reset:
jnz .L12
loop .L11
.L12:
; PutStr "hardware reset"
; DEBUGF 1," K : hardware reset\n"
xor ebx,ebx
mov eax,0x0002
call dword [pcnet32_access.write_csr]
xor ebx,ebx
call dword [pcnet32_access.read_csr]
; PutStr "PCNET reset complete"
; DEBUGF 1," K : PCNET reset complete\n"
ret
pcnet32_adjust_pci_device:
;*******Get current setting************************
mov al, 2 ;read a word
mov bh, [pci_dev]
mov ah, [pci_bus]
mov bl, 0x04 ;from command Register
mov al, 2 ;read a word
mov bh, [pci_dev]
mov ah, [pci_bus]
mov bl, 0x04 ;from command Register
call pci_read_reg
;******see if its already set as bus master********
mov bx, ax
and bx,5
cmp bx,5
je pcnet32_adjust_pci_device_Latency
mov bx, ax
and bx,5
cmp bx,5
je pcnet32_adjust_pci_device_Latency
;******Make card a bus master*******
mov cx, ax ;value to write
mov bh, [pci_dev]
mov al, 2 ;write a word
or cx,5
mov ah, [pci_bus]
mov bl, 0x04 ;to command register
mov cx, ax ;value to write
mov bh, [pci_dev]
mov al, 2 ;write a word
or cx,5
mov ah, [pci_bus]
mov bl, 0x04 ;to command register
call pci_write_reg
;******Check latency setting***********
pcnet32_adjust_pci_device_Latency:
@ -534,6 +544,10 @@ pcnet32_adjust_pci_device_Latency:
;******Check latency setting***********
pcnet32_adjust_pci_device_Done:
ret
pcnet32_probe:
mov ebp,[io_addr]
call pcnet32_wio_reset
@ -544,7 +558,7 @@ pcnet32_probe:
call pcnet32_wio_check
and al,al
jz .try_dwio
; PutStr "Using WIO"
; DEBUGF 1," K : Using WIO\n"
mov esi,pcnet32_wio
jmp .L1
.try_dwio:
@ -556,11 +570,11 @@ pcnet32_probe:
call pcnet32_dwio_check
and al,al
jz .no_dev
; PutStr "Using DWIO"
; DEBUGF 1," K : Using DWIO\n"
mov esi,pcnet32_dwio
jmp .L1
.no_dev:
; PutStr "PCNET32 not found"
DEBUGF 1," K : PCNET32 not found\n"
ret
.L1:
mov edi,pcnet32_access
@ -581,7 +595,7 @@ pcnet32_probe:
shr eax,12
and eax,0xffff
mov [pcnet32_private.chip_version],eax
; PutStr "PCNET32 chip version OK"
; DEBUGF 1," K : PCNET32 chip version OK\n"
mov [pcnet32_private.fdx],0
mov [pcnet32_private.mii],0
mov [pcnet32_private.fset],0
@ -604,45 +618,45 @@ pcnet32_probe:
je .L8
cmp eax,0x2627
je .L9
; PutStr "Invalid chip rev"
DEBUGF 1," K : Invalid chip rev\n"
jmp .no_dev
.L2:
; PutStr "PCnet/PCI 79C970"
; DEBUGF 1," K : PCnet/PCI 79C970\n"
jmp .L10
.L3:
; PutStr "PCnet/PCI 79C970"
; DEBUGF 1," K : PCnet/PCI 79C970\n"
jmp .L10
.L4:
; PutStr "PCnet/PCI II 79C970A"
; DEBUGF 1," K : PCnet/PCI II 79C970A\n"
mov [pcnet32_private.fdx],1
jmp .L10
.L5:
; PutStr "PCnet/FAST 79C971"
; DEBUGF 1," K : PCnet/FAST 79C971\n"
mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1
mov [pcnet32_private.fset],1
mov [pcnet32_private.ltint],1
jmp .L10
.L6:
; PutStr "PCnet/FAST+ 79C972"
; DEBUGF 1," K : PCnet/FAST+ 79C972\n"
mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1
mov [pcnet32_private.fset],1
jmp .L10
.L7:
; PutStr "PCnet/FAST III 79C973"
; DEBUGF 1," K : PCnet/FAST III 79C973\n"
mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1
jmp .L10
.L8:
; PutStr "PCnet/Home 79C978"
; DEBUGF 1," K : PCnet/Home 79C978\n"
mov [pcnet32_private.fdx],1
mov ebx,49
call dword [pcnet32_access.read_bcr]
call dword [pcnet32_access.write_bcr]
jmp .L10
.L9:
; PutStr "PCnet/FAST III 79C975"
; DEBUGF 1," K : PCnet/FAST III 79C975\n"
mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1
.L10:
@ -669,9 +683,9 @@ pcnet32_probe:
stosb
inc edx
loop .Lmac
; PutStr "MAC read"
; DEBUGF 1," K : MAC read\n"
call pcnet32_adjust_pci_device
; PutStr "PCI done"
; DEBUGF 1," K : PCI done\n"
mov eax,PCNET32_PORT_ASEL
mov [pcnet32_private.options],eax
mov [pcnet32_private.mode],word 0x0003
@ -683,9 +697,14 @@ pcnet32_probe:
movsw
mov [pcnet32_private.filter],dword 0
mov [pcnet32_private.filter+4],dword 0
mov dword [pcnet32_private.rx_ring],pcnet32_rx_ring
mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring
; PutStr "Switching to 32"
mov eax,pcnet32_rx_ring
sub eax,OS_BASE
mov dword [pcnet32_private.rx_ring],eax
mov eax,pcnet32_tx_ring
sub eax,OS_BASE
mov dword [pcnet32_private.tx_ring],eax
; DEBUGF 1," K : Switching to 32\n"
mov ebx,20
mov eax,2
call dword [pcnet32_access.write_bcr]
@ -704,8 +723,11 @@ pcnet32_probe:
mov eax, [pci_data]
mov [eth_status], eax
ret
pcnet32_poll:
xor eax,eax
xor ax,ax
mov [eth_rx_data_len],ax
mov eax,[pcnet32_private.cur_rx]
and eax,PCNET32_RX_RING_MOD_MASK
@ -719,11 +741,11 @@ pcnet32_poll:
jnz .L1
cmp ch,3
jne .L1
; PutStr "PCNETRX"
mov ecx,[ebx+pcnet32_rx_head.msg_length]
and ecx,0xfff
sub ecx,4
mov [eth_rx_data_len],cx
; DEBUGF 1," K : PCNETRX: %ub\n",cx
push ecx
shr ecx,2
mov edi,Ether_buffer
@ -737,6 +759,10 @@ pcnet32_poll:
inc [pcnet32_private.cur_rx]
.L1:
ret
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; size of packet in ecx
@ -746,13 +772,13 @@ pcnet32_xmit:
push esi
push ebx
push ecx
; PutStr "PCNETTX"
; DEBUGF 1," K : PCNETTX\n"
mov esi,edi
mov edi,[pcnet32_private.cur_tx]
imul edi,PCNET32_PKT_BUF_SZ
add edi,pcnet32_txb ; edi=ptxb
mov eax,edi
cld ; copy MAC
cld ; copy MAC
movsd
movsw
mov esi,node_addr
@ -780,7 +806,7 @@ pcnet32_xmit:
; cld
; rep stosb
;.L1:
mov edi,pcnet32_tx_ring+0 ; entry=0
mov edi,pcnet32_tx_ring+0 ; entry=0
mov ecx,[esp]
add ecx,14
cmp cx,60
@ -790,11 +816,12 @@ pcnet32_xmit:
neg cx
mov [edi+pcnet32_tx_head.length],cx
mov [edi+pcnet32_tx_head.misc],dword 0
sub eax,OS_BASE
mov [edi+pcnet32_tx_head.base],eax
mov [edi+pcnet32_tx_head.status],word 0x8300
; trigger an immediate send poll
mov ebx,0
mov eax,0x0008 ; 0x0048
mov eax,0x0008 ; 0x0048
mov ebp,[io_addr]
call dword [pcnet32_access.write_csr]
mov dword [pcnet32_private.cur_tx],0
@ -811,7 +838,7 @@ pcnet32_xmit:
call delay_ms
jnz .L2
.L4:
; PutStr "PCNET: Send timeout"
DEBUGF 1," K : PCNET: Send timeout\n"
.L3:
mov dword [edi+pcnet32_tx_head.base],0
pop ecx