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 ;; ;; 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 ;; ;; This driver is based on the PCNet32 driver from ;;
;; the etherboot 5.0.6 project. The copyright statement is ;; ;; the etherboot 5.0.6 project. The copyright statement is ;;
@ -25,24 +31,6 @@
$Revision$ $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_AUI equ 0x00
PCNET32_PORT_10BT equ 0x01 PCNET32_PORT_10BT equ 0x01
PCNET32_PORT_GPSI equ 0x02 PCNET32_PORT_GPSI equ 0x02
@ -52,8 +40,10 @@ PCNET32_PORT_ASEL equ 0x04
PCNET32_PORT_100 equ 0x40 PCNET32_PORT_100 equ 0x40
PCNET32_PORT_FD equ 0x80 PCNET32_PORT_FD equ 0x80
PCNET32_DMA_MASK equ 0xffffffff PCNET32_DMA_MASK equ 0xffffffff
PCNET32_LOG_TX_BUFFERS equ 1 PCNET32_LOG_TX_BUFFERS equ 1
PCNET32_LOG_RX_BUFFERS equ 2 PCNET32_LOG_RX_BUFFERS equ 2
PCNET32_TX_RING_SIZE equ (1 shl PCNET32_LOG_TX_BUFFERS) 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_MOD_MASK equ (PCNET32_TX_RING_SIZE-1)
PCNET32_TX_RING_LEN_BITS equ 0 PCNET32_TX_RING_LEN_BITS equ 0
@ -62,10 +52,12 @@ PCNET32_RX_RING_MOD_MASK equ (PCNET32_RX_RING_SIZE-1)
PCNET32_RX_RING_LEN_BITS equ (PCNET32_LOG_RX_BUFFERS shl 4) PCNET32_RX_RING_LEN_BITS equ (PCNET32_LOG_RX_BUFFERS shl 4)
PCNET32_PKT_BUF_SZ equ 1544 PCNET32_PKT_BUF_SZ equ 1544
PCNET32_PKT_BUF_SZ_NEG equ 0xf9f8 PCNET32_PKT_BUF_SZ_NEG equ 0xf9f8
pcnet32_txb equ (eth_data_start) pcnet32_txb equ (eth_data_start)
pcnet32_rxb equ ((pcnet32_txb+(PCNET32_PKT_BUF_SZ*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0) 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_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) 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) virtual at ((pcnet32_rx_ring+(16*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0)
pcnet32_private: pcnet32_private:
.mode dw ? .mode dw ?
@ -89,6 +81,7 @@ pcnet32_private:
.fset db ? .fset db ?
.fdx db ? .fdx db ?
end virtual end virtual
virtual at 0 virtual at 0
pcnet32_rx_head: pcnet32_rx_head:
.base dd ? .base dd ?
@ -97,6 +90,7 @@ pcnet32_rx_head:
.msg_length dd ? .msg_length dd ?
.reserved dd ? .reserved dd ?
end virtual end virtual
virtual at 0 virtual at 0
pcnet32_tx_head: pcnet32_tx_head:
.base dd ? .base dd ?
@ -339,6 +333,8 @@ pcnet32_dwio:
dd pcnet32_dwio_reset dd pcnet32_dwio_reset
endg endg
pcnet32_init_ring: pcnet32_init_ring:
mov [pcnet32_private.tx_full],0 mov [pcnet32_private.tx_full],0
mov [pcnet32_private.cur_rx],0 mov [pcnet32_private.cur_rx],0
@ -348,6 +344,7 @@ pcnet32_init_ring:
mov edi,pcnet32_rx_ring mov edi,pcnet32_rx_ring
mov ecx,PCNET32_RX_RING_SIZE mov ecx,PCNET32_RX_RING_SIZE
mov ebx,pcnet32_rxb mov ebx,pcnet32_rxb
sub ebx,OS_BASE
.rx_init: .rx_init:
mov [edi+pcnet32_rx_head.base],ebx mov [edi+pcnet32_rx_head.base],ebx
mov [edi+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG mov [edi+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG
@ -369,9 +366,17 @@ pcnet32_init_ring:
cld cld
movsd movsd
movsw movsw
mov dword [pcnet32_private.rx_ring],pcnet32_rx_ring mov eax,pcnet32_rx_ring
mov dword [pcnet32_private.tx_ring],pcnet32_tx_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 ret
pcnet32_reset: pcnet32_reset:
; Reset PCNET32 ; Reset PCNET32
mov ebp,[io_addr] mov ebp,[io_addr]
@ -443,7 +448,7 @@ pcnet32_reset:
test [pcnet32_private.options],PCNET32_PORT_ASEL test [pcnet32_private.options],PCNET32_PORT_ASEL
jz .L9 jz .L9
mov ebx,32 mov ebx,32
; PutStr "ASEL, enable auto-negotiation" ; DEBUGF 1," K : ASEL, enable auto-negotiation\n"
call dword [pcnet32_access.read_bcr] call dword [pcnet32_access.read_bcr]
and eax,not 0x98 and eax,not 0x98
or eax,0x20 or eax,0x20
@ -465,9 +470,11 @@ pcnet32_reset:
call pcnet32_init_ring call pcnet32_init_ring
mov ebx,1 mov ebx,1
mov eax,pcnet32_private mov eax,pcnet32_private
sub eax,OS_BASE
and eax,0xffff and eax,0xffff
call dword [pcnet32_access.write_csr] call dword [pcnet32_access.write_csr]
mov eax,pcnet32_private mov eax,pcnet32_private
sub eax,OS_BASE
mov ebx,2 mov ebx,2
shr eax,16 shr eax,16
call dword [pcnet32_access.write_csr] call dword [pcnet32_access.write_csr]
@ -485,14 +492,17 @@ pcnet32_reset:
jnz .L12 jnz .L12
loop .L11 loop .L11
.L12: .L12:
; PutStr "hardware reset" ; DEBUGF 1," K : hardware reset\n"
xor ebx,ebx xor ebx,ebx
mov eax,0x0002 mov eax,0x0002
call dword [pcnet32_access.write_csr] call dword [pcnet32_access.write_csr]
xor ebx,ebx xor ebx,ebx
call dword [pcnet32_access.read_csr] call dword [pcnet32_access.read_csr]
; PutStr "PCNET reset complete" ; DEBUGF 1," K : PCNET reset complete\n"
ret ret
pcnet32_adjust_pci_device: pcnet32_adjust_pci_device:
;*******Get current setting************************ ;*******Get current setting************************
mov al, 2 ;read a word mov al, 2 ;read a word
@ -534,6 +544,10 @@ pcnet32_adjust_pci_device_Latency:
;******Check latency setting*********** ;******Check latency setting***********
pcnet32_adjust_pci_device_Done: pcnet32_adjust_pci_device_Done:
ret ret
pcnet32_probe: pcnet32_probe:
mov ebp,[io_addr] mov ebp,[io_addr]
call pcnet32_wio_reset call pcnet32_wio_reset
@ -544,7 +558,7 @@ pcnet32_probe:
call pcnet32_wio_check call pcnet32_wio_check
and al,al and al,al
jz .try_dwio jz .try_dwio
; PutStr "Using WIO" ; DEBUGF 1," K : Using WIO\n"
mov esi,pcnet32_wio mov esi,pcnet32_wio
jmp .L1 jmp .L1
.try_dwio: .try_dwio:
@ -556,11 +570,11 @@ pcnet32_probe:
call pcnet32_dwio_check call pcnet32_dwio_check
and al,al and al,al
jz .no_dev jz .no_dev
; PutStr "Using DWIO" ; DEBUGF 1," K : Using DWIO\n"
mov esi,pcnet32_dwio mov esi,pcnet32_dwio
jmp .L1 jmp .L1
.no_dev: .no_dev:
; PutStr "PCNET32 not found" DEBUGF 1," K : PCNET32 not found\n"
ret ret
.L1: .L1:
mov edi,pcnet32_access mov edi,pcnet32_access
@ -581,7 +595,7 @@ pcnet32_probe:
shr eax,12 shr eax,12
and eax,0xffff and eax,0xffff
mov [pcnet32_private.chip_version],eax 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.fdx],0
mov [pcnet32_private.mii],0 mov [pcnet32_private.mii],0
mov [pcnet32_private.fset],0 mov [pcnet32_private.fset],0
@ -604,45 +618,45 @@ pcnet32_probe:
je .L8 je .L8
cmp eax,0x2627 cmp eax,0x2627
je .L9 je .L9
; PutStr "Invalid chip rev" DEBUGF 1," K : Invalid chip rev\n"
jmp .no_dev jmp .no_dev
.L2: .L2:
; PutStr "PCnet/PCI 79C970" ; DEBUGF 1," K : PCnet/PCI 79C970\n"
jmp .L10 jmp .L10
.L3: .L3:
; PutStr "PCnet/PCI 79C970" ; DEBUGF 1," K : PCnet/PCI 79C970\n"
jmp .L10 jmp .L10
.L4: .L4:
; PutStr "PCnet/PCI II 79C970A" ; DEBUGF 1," K : PCnet/PCI II 79C970A\n"
mov [pcnet32_private.fdx],1 mov [pcnet32_private.fdx],1
jmp .L10 jmp .L10
.L5: .L5:
; PutStr "PCnet/FAST 79C971" ; DEBUGF 1," K : PCnet/FAST 79C971\n"
mov [pcnet32_private.fdx],1 mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1 mov [pcnet32_private.mii],1
mov [pcnet32_private.fset],1 mov [pcnet32_private.fset],1
mov [pcnet32_private.ltint],1 mov [pcnet32_private.ltint],1
jmp .L10 jmp .L10
.L6: .L6:
; PutStr "PCnet/FAST+ 79C972" ; DEBUGF 1," K : PCnet/FAST+ 79C972\n"
mov [pcnet32_private.fdx],1 mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1 mov [pcnet32_private.mii],1
mov [pcnet32_private.fset],1 mov [pcnet32_private.fset],1
jmp .L10 jmp .L10
.L7: .L7:
; PutStr "PCnet/FAST III 79C973" ; DEBUGF 1," K : PCnet/FAST III 79C973\n"
mov [pcnet32_private.fdx],1 mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1 mov [pcnet32_private.mii],1
jmp .L10 jmp .L10
.L8: .L8:
; PutStr "PCnet/Home 79C978" ; DEBUGF 1," K : PCnet/Home 79C978\n"
mov [pcnet32_private.fdx],1 mov [pcnet32_private.fdx],1
mov ebx,49 mov ebx,49
call dword [pcnet32_access.read_bcr] call dword [pcnet32_access.read_bcr]
call dword [pcnet32_access.write_bcr] call dword [pcnet32_access.write_bcr]
jmp .L10 jmp .L10
.L9: .L9:
; PutStr "PCnet/FAST III 79C975" ; DEBUGF 1," K : PCnet/FAST III 79C975\n"
mov [pcnet32_private.fdx],1 mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1 mov [pcnet32_private.mii],1
.L10: .L10:
@ -669,9 +683,9 @@ pcnet32_probe:
stosb stosb
inc edx inc edx
loop .Lmac loop .Lmac
; PutStr "MAC read" ; DEBUGF 1," K : MAC read\n"
call pcnet32_adjust_pci_device call pcnet32_adjust_pci_device
; PutStr "PCI done" ; DEBUGF 1," K : PCI done\n"
mov eax,PCNET32_PORT_ASEL mov eax,PCNET32_PORT_ASEL
mov [pcnet32_private.options],eax mov [pcnet32_private.options],eax
mov [pcnet32_private.mode],word 0x0003 mov [pcnet32_private.mode],word 0x0003
@ -683,9 +697,14 @@ pcnet32_probe:
movsw movsw
mov [pcnet32_private.filter],dword 0 mov [pcnet32_private.filter],dword 0
mov [pcnet32_private.filter+4],dword 0 mov [pcnet32_private.filter+4],dword 0
mov dword [pcnet32_private.rx_ring],pcnet32_rx_ring mov eax,pcnet32_rx_ring
mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring sub eax,OS_BASE
; PutStr "Switching to 32" 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 ebx,20
mov eax,2 mov eax,2
call dword [pcnet32_access.write_bcr] call dword [pcnet32_access.write_bcr]
@ -704,8 +723,11 @@ pcnet32_probe:
mov eax, [pci_data] mov eax, [pci_data]
mov [eth_status], eax mov [eth_status], eax
ret ret
pcnet32_poll: pcnet32_poll:
xor eax,eax xor ax,ax
mov [eth_rx_data_len],ax mov [eth_rx_data_len],ax
mov eax,[pcnet32_private.cur_rx] mov eax,[pcnet32_private.cur_rx]
and eax,PCNET32_RX_RING_MOD_MASK and eax,PCNET32_RX_RING_MOD_MASK
@ -719,11 +741,11 @@ pcnet32_poll:
jnz .L1 jnz .L1
cmp ch,3 cmp ch,3
jne .L1 jne .L1
; PutStr "PCNETRX"
mov ecx,[ebx+pcnet32_rx_head.msg_length] mov ecx,[ebx+pcnet32_rx_head.msg_length]
and ecx,0xfff and ecx,0xfff
sub ecx,4 sub ecx,4
mov [eth_rx_data_len],cx mov [eth_rx_data_len],cx
; DEBUGF 1," K : PCNETRX: %ub\n",cx
push ecx push ecx
shr ecx,2 shr ecx,2
mov edi,Ether_buffer mov edi,Ether_buffer
@ -737,6 +759,10 @@ pcnet32_poll:
inc [pcnet32_private.cur_rx] inc [pcnet32_private.cur_rx]
.L1: .L1:
ret ret
; Pointer to 48 bit destination address in edi ; Pointer to 48 bit destination address in edi
; Type of packet in bx ; Type of packet in bx
; size of packet in ecx ; size of packet in ecx
@ -746,7 +772,7 @@ pcnet32_xmit:
push esi push esi
push ebx push ebx
push ecx push ecx
; PutStr "PCNETTX" ; DEBUGF 1," K : PCNETTX\n"
mov esi,edi mov esi,edi
mov edi,[pcnet32_private.cur_tx] mov edi,[pcnet32_private.cur_tx]
imul edi,PCNET32_PKT_BUF_SZ imul edi,PCNET32_PKT_BUF_SZ
@ -790,6 +816,7 @@ pcnet32_xmit:
neg cx neg cx
mov [edi+pcnet32_tx_head.length],cx mov [edi+pcnet32_tx_head.length],cx
mov [edi+pcnet32_tx_head.misc],dword 0 mov [edi+pcnet32_tx_head.misc],dword 0
sub eax,OS_BASE
mov [edi+pcnet32_tx_head.base],eax mov [edi+pcnet32_tx_head.base],eax
mov [edi+pcnet32_tx_head.status],word 0x8300 mov [edi+pcnet32_tx_head.status],word 0x8300
; trigger an immediate send poll ; trigger an immediate send poll
@ -811,7 +838,7 @@ pcnet32_xmit:
call delay_ms call delay_ms
jnz .L2 jnz .L2
.L4: .L4:
; PutStr "PCNET: Send timeout" DEBUGF 1," K : PCNET: Send timeout\n"
.L3: .L3:
mov dword [edi+pcnet32_tx_head.base],0 mov dword [edi+pcnet32_tx_head.base],0
pop ecx pop ecx