7,8 → 7,14 |
;; ;; |
;; 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_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 |
dd pcnet32_dwio_reset |
endg |
|
|
|
pcnet32_init_ring: |
mov [pcnet32_private.tx_full],0 |
mov [pcnet32_private.cur_rx],0 |
348,6 → 344,7 |
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 |
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 |
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 |
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 |
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 |
;******Check latency setting*********** |
pcnet32_adjust_pci_device_Done: |
ret |
|
|
|
|
pcnet32_probe: |
mov ebp,[io_addr] |
call pcnet32_wio_reset |
544,7 → 558,7 |
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 |
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 |
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,20 → 618,20 |
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 |
624,18 → 638,18 |
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] |
642,7 → 656,7 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
; 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 |
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 |
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 |