From b384868a4deecfe14449717fb25b6b6536aa4456 Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Fri, 28 Mar 2008 23:42:28 +0000 Subject: [PATCH] Fixed PCnet32 ethernet driver git-svn-id: svn://kolibrios.org@781 a494cfbc-eb01-0410-851d-a64ba20cac60 --- .../trunk/network/eth_drv/drivers/pcnet32.inc | 293 ++++++++++-------- 1 file changed, 160 insertions(+), 133 deletions(-) diff --git a/kernel/trunk/network/eth_drv/drivers/pcnet32.inc b/kernel/trunk/network/eth_drv/drivers/pcnet32.inc index eda682020f..f328e7105e 100644 --- a/kernel/trunk/network/eth_drv/drivers/pcnet32.inc +++ b/kernel/trunk/network/eth_drv/drivers/pcnet32.inc @@ -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