From 77f1a07bff84b9d25a5985c7a8a077994ef507c7 Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Thu, 24 Feb 2011 17:25:38 +0000 Subject: [PATCH] R6040 driver for trunk kernel git-svn-id: svn://kolibrios.org@1887 a494cfbc-eb01-0410-851d-a64ba20cac60 --- .../trunk/network/eth_drv/drivers/R6040.INC | 813 ++++++++++++++++++ kernel/trunk/network/eth_drv/ethernet.inc | 130 ++- 2 files changed, 876 insertions(+), 67 deletions(-) create mode 100644 kernel/trunk/network/eth_drv/drivers/R6040.INC diff --git a/kernel/trunk/network/eth_drv/drivers/R6040.INC b/kernel/trunk/network/eth_drv/drivers/R6040.INC new file mode 100644 index 0000000000..cf0e2d6f1a --- /dev/null +++ b/kernel/trunk/network/eth_drv/drivers/R6040.INC @@ -0,0 +1,813 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;; R6040 driver for KolibriOS ;; +;; ;; +;; based on R6040.c from linux ;; +;; ;; +;; Written by Asper (asper.85@mail.ru) ;; +;; and hidnplayr (hidnplayr@gmail.com) ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +;******************************************************************** +; Interface +; r6040_reset +; r6040_probe +; r6040_poll +; r6040_transmit +; +; These functions are referenced in ethernet.inc +; +;******************************************************************** + +;; A few user-configurable values. + +TX_RING_SIZE equ 4 +RX_RING_SIZE equ 4 + +; ethernet address length +ETH_ALEN equ 6 +ETH_HLEN equ (2 * ETH_ALEN + 2) +ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for + ; mininmum 64bytes frame length +; system timer frequency +HZ equ 1000 + +; max time out delay time +W_MAX_TIMEOUT equ 0x0FFF + +;; Size of the in-memory receive ring. +RX_BUF_LEN_IDX equ 3 ;; 0==8K, 1==16K, 2==32K, 3==64K +RX_BUF_LEN equ (8192 << RX_BUF_LEN_IDX) + +;-; Size of the Tx bounce buffers -- must be at least (dev->mtu+14+4). +;-TX_BUF_SIZE equ 1536 +;-RX_BUF_SIZE equ 1536 + +;; PCI Tuning Parameters +; Threshold is bytes transferred to chip before transmission starts. +TX_FIFO_THRESH equ 256 ;; In bytes, rounded down to 32 byte units. + +;; The following settings are log_2(bytes)-4: 0 == 16 bytes .. 6==1024. +RX_FIFO_THRESH equ 4 ;; Rx buffer level before first PCI xfer. +RX_DMA_BURST equ 4 ;; Maximum PCI burst, '4' is 256 bytes +TX_DMA_BURST equ 4 + +;; Operational parameters that usually are not changed. +PHY1_ADDR equ 1 ;For MAC1 +PHY2_ADDR equ 3 ;For MAC2 +PHY_MODE equ 0x3100 ;PHY CHIP Register 0 +PHY_CAP equ 0x01E1 ;PHY CHIP Register 4 + +;; Time in jiffies before concluding the transmitter is hung. +TX_TIMEOUT equ ((6000*HZ)/1000) + +R6040_IO_SIZE equ 256 ; RDC MAC I/O Size +MAX_MAC equ 2 ; MAX RDC MAC + +;************************************************************************** +; RDC R6040 Register Definitions +;************************************************************************** +MCR0 equ 0x00 ;Control register 0 +MCR1 equ 0x01 ;Control register 1 +MAC_RST equ 0x0001 ;Reset the MAC +MBCR equ 0x08 ;Bus control +MT_ICR equ 0x0C ;TX interrupt control +MR_ICR equ 0x10 ;RX interrupt control +MTPR equ 0x14 ;TX poll command register +MR_BSR equ 0x18 ;RX buffer size +MR_DCR equ 0x1A ;RX descriptor control +MLSR equ 0x1C ;Last status +MMDIO equ 0x20 ;MDIO control register +MDIO_WRITE equ 0x4000 ;MDIO write +MDIO_READ equ 0x2000 ;MDIO read +MMRD equ 0x24 ;MDIO read data register +MMWD equ 0x28 ;MDIO write data register +MTD_SA0 equ 0x2C ;TX descriptor start address 0 +MTD_SA1 equ 0x30 ;TX descriptor start address 1 +MRD_SA0 equ 0x34 ;RX descriptor start address 0 +MRD_SA1 equ 0x38 ;RX descriptor start address 1 +MISR equ 0x3C ;Status register +MIER equ 0x40 ;INT enable register +MSK_INT equ 0x0000 ;Mask off interrupts +RX_FINISH equ 0x0001 ;RX finished +RX_NO_DESC equ 0x0002 ;No RX descriptor available +RX_FIFO_FULL equ 0x0004 ;RX FIFO full +RX_EARLY equ 0x0008 ;RX early +TX_FINISH equ 0x0010 ;TX finished +TX_EARLY equ 0x0080 ;TX early +EVENT_OVRFL equ 0x0100 ;Event counter overflow +LINK_CHANGED equ 0x0200 ;PHY link changed +ME_CISR equ 0x44 ;Event counter INT status +ME_CIER equ 0x48 ;Event counter INT enable +MR_CNT equ 0x50 ;Successfully received packet counter +ME_CNT0 equ 0x52 ;Event counter 0 +ME_CNT1 equ 0x54 ;Event counter 1 +ME_CNT2 equ 0x56 ;Event counter 2 +ME_CNT3 equ 0x58 ;Event counter 3 +MT_CNT equ 0x5A ;Successfully transmit packet counter +ME_CNT4 equ 0x5C ;Event counter 4 +MP_CNT equ 0x5E ;Pause frame counter register +MAR0 equ 0x60 ;Hash table 0 +MAR1 equ 0x62 ;Hash table 1 +MAR2 equ 0x64 ;Hash table 2 +MAR3 equ 0x66 ;Hash table 3 +MID_0L equ 0x68 ;Multicast address MID0 Low +MID_0M equ 0x6A ;Multicast address MID0 Medium +MID_0H equ 0x6C ;Multicast address MID0 High +MID_1L equ 0x70 ;MID1 Low +MID_1M equ 0x72 ;MID1 Medium +MID_1H equ 0x74 ;MID1 High +MID_2L equ 0x78 ;MID2 Low +MID_2M equ 0x7A ;MID2 Medium +MID_2H equ 0x7C ;MID2 High +MID_3L equ 0x80 ;MID3 Low +MID_3M equ 0x82 ;MID3 Medium +MID_3H equ 0x84 ;MID3 High +PHY_CC equ 0x88 ;PHY status change configuration register +PHY_ST equ 0x8A ;PHY status register +MAC_SM equ 0xAC ;MAC status machine +MAC_ID equ 0xBE ;Identifier register + +MAX_BUF_SIZE equ 0x600 ;1536 + +MBCR_DEFAULT equ 0x012A ;MAC Bus Control Register +MCAST_MAX equ 3 ;Max number multicast addresses to filter + +;Descriptor status +DSC_OWNER_MAC equ 0x8000 ;MAC is the owner of this descriptor +DSC_RX_OK equ 0x4000 ;RX was successfull +DSC_RX_ERR equ 0x0800 ;RX PHY error +DSC_RX_ERR_DRI equ 0x0400 ;RX dribble packet +DSC_RX_ERR_BUF equ 0x0200 ;RX length exceeds buffer size +DSC_RX_ERR_LONG equ 0x0100 ;RX length > maximum packet length +DSC_RX_ERR_RUNT equ 0x0080 ;RX packet length < 64 byte +DSC_RX_ERR_CRC equ 0x0040 ;RX CRC error +DSC_RX_BCAST equ 0x0020 ;RX broadcast (no error) +DSC_RX_MCAST equ 0x0010 ;RX multicast (no error) +DSC_RX_MCH_HIT equ 0x0008 ;RX multicast hit in hash table (no error) +DSC_RX_MIDH_HIT equ 0x0004 ;RX MID table hit (no error) +DSC_RX_IDX_MID_MASK equ 3 ;RX mask for the index of matched MIDx + +;PHY settings +ICPLUS_PHY_ID equ 0x0243 + +RX_INTS equ RX_FIFO_FULL or RX_NO_DESC or RX_FINISH +TX_INTS equ TX_FINISH +INT_MASK equ RX_INTS or TX_INTS + + +r6040_txb equ (eth_data_start) +r6040_rxb equ ((r6040_txb+(MAX_BUF_SIZE*TX_RING_SIZE)+32) and 0xfffffff0) +r6040_tx_ring equ ((r6040_rxb+(MAX_BUF_SIZE*RX_RING_SIZE)+32) and 0xfffffff0) +r6040_rx_ring equ ((r6040_tx_ring+(r6040_x_head.sizeof*TX_RING_SIZE)+32) and 0xfffffff0) + +virtual at ((r6040_rx_ring+(r6040_x_head.sizeof*RX_RING_SIZE)+32) and 0xfffffff0) +r6040_private: + .rx_ring dd ? + .tx_ring dd ? + .cur_rx dw ? + .cur_tx dw ? + .phy_addr dw ? + .phy_mode dw ? + .mcr0 dw ? + .mcr1 dw ? + .switch_sig dw ? +end virtual + +virtual at 0 +r6040_x_head: + .status dw ? ;0-1 + .len dw ? ;2-3 + .buf dd ? ;4-7 + .ndesc dd ? ;8-B + .rev1 dd ? ;C-F + .vbufp dd ? ;10-13 + .vndescp dd ? ;14-17 + .skb_ptr dd ? ;18-1B + .rev2 dd ? ;1C-1F + .sizeof: +end virtual + + + +; Read a word data from PHY Chip +proc r6040_phy_read stdcall, phy_addr:dword, reg:dword + push ecx edx + mov eax, [phy_addr] + shl eax, 8 + add eax, [reg] + add eax, MDIO_READ + mov edx, [io_addr] + add edx, MMDIO + out dx, ax + ;Wait for the read bit to be cleared. + mov ecx, 2048 ;limit + xor eax, eax + .read: + in ax, dx + test ax, MDIO_READ + jz @f + dec ecx + test ecx, ecx + jnz .read + @@: + mov edx, [io_addr] + add edx, MMRD + in ax, dx + and eax, 0xFFFF + pop edx ecx + ret +endp + +; Write a word data to PHY Chip +proc r6040_phy_write stdcall, phy_addr:dword, reg:dword, val:dword + push eax ecx edx + mov eax, [val] + mov edx, [io_addr] + add edx, MMWD + out dx, ax + ;Write the command to the MDIO bus + mov eax, [phy_addr] + shl eax, 8 + add eax, [reg] + add eax, MDIO_WRITE + mov edx, [io_addr] + add edx, MMDIO + out dx, ax + ;Wait for the write bit to be cleared. + mov ecx, 2048 ;limit + xor eax, eax + .write: + in ax, dx + test ax, MDIO_WRITE + jz @f + dec ecx + test ecx, ecx + jnz .write + @@: + pop edx ecx eax + ret +endp + +macro r6040_mdio_write reg, val { + stdcall r6040_phy_read, [io_addr], [r6040_private.phy_addr], reg +} + +macro r6040_mdio_write reg, val { + stdcall r6040_phy_write, [io_addr], [r6040_private.phy_addr], reg, val +} + + +proc r6040_init_ring_desc stdcall, desc_ring:dword, size:dword + push eax ecx esi + mov ecx, [size] + test ecx, ecx + jz .out + + mov esi, [desc_ring] + mov eax, esi + .next_desc: + add eax, r6040_x_head.sizeof - OS_BASE + mov [esi+r6040_x_head.ndesc], eax + add eax, OS_BASE + mov [esi+r6040_x_head.vndescp], eax + mov esi, eax + dec ecx + jnz .next_desc + + sub esi, r6040_x_head.sizeof + mov eax, [desc_ring] + mov [esi+r6040_x_head.vndescp], eax + sub eax, OS_BASE + mov [esi+r6040_x_head.ndesc], eax + .out: + pop esi ecx eax + ret +endp + + + + +r6040_init_rxbufs: + + stdcall r6040_init_ring_desc, r6040_rx_ring, RX_RING_SIZE + + ; Allocate skbs for the rx descriptors + mov esi, r6040_rx_ring + mov ebx, r6040_rxb + mov ecx, RX_RING_SIZE + mov eax, r6040_rx_ring + .next_desc: + mov [esi+r6040_x_head.skb_ptr], ebx + mov [esi+r6040_x_head.buf], ebx + sub [esi+r6040_x_head.buf], OS_BASE + mov [esi+r6040_x_head.status], DSC_OWNER_MAC + + mov eax, [esi+r6040_x_head.vndescp] + mov esi, eax + + add ebx, MAX_BUF_SIZE + dec ecx + jnz .next_desc + + xor eax, eax + .out: + + ret + + +r6040_probe: + + DEBUGF 1, "Probing r6040\n" + + call adjust_pci_device + + + ; If PHY status change register is still set to zero + ; it means the bootloader didn't initialize it + mov edx, [io_addr] + add edx, PHY_CC + in ax, dx + test ax, ax + jnz @f + mov eax, 0x9F07 + out dx, ax + @@: + ; Set MAC address + mov ecx, 3 + mov edi, node_addr + mov edx, [io_addr] + add edx, MID_0L + .mac: + in ax, dx + stosw + add edx, 2 + dec ecx + jnz .mac + ; Some bootloaders/BIOSes do not initialize + ; MAC address, warn about that + and eax, 0xFF + or eax, [node_addr] + test eax, eax + jnz @f + DEBUGF 1, "K : MAC address not initialized\n" ;, generating random" + ;Asper: Add here generate function call! + ; Temporary workaround: init by constant adress + mov dword [node_addr], 0x00006000 + mov word [node_addr+4], 0x0001 + @@: + ; Init RDC private data + mov [r6040_private.mcr0], 0x1002 + ;mov [r6040_private.phy_addr], 1 ; Asper: Only one network card is supported now. + mov [r6040_private.switch_sig], 0 + + ; Check the vendor ID on the PHY, if 0xFFFF assume none attached + stdcall r6040_phy_read, 1, 2 + cmp ax, 0xFFFF + jne @f + DEBUGF 1, "K : Failed to detect an attached PHY\n" ;, generating random" + mov eax, -1 + ret + @@: + + ; Set MAC address + call r6040_mac_address + + + ; Initialize and alloc RX/TX buffers + stdcall r6040_init_ring_desc, r6040_tx_ring, TX_RING_SIZE + call r6040_init_rxbufs ;r6040_alloc_rxbufs + test eax, eax + jnz .out + + ; Read the PHY ID + mov [r6040_private.phy_mode], 0x8000 + stdcall r6040_phy_read, 0, 2 + mov [r6040_private.switch_sig], ax + cmp ax, ICPLUS_PHY_ID + jne @f + stdcall r6040_phy_write, 29, 31, 0x175C ; Enable registers + jmp .phy_readen + @@: + + ; PHY Mode Check + movzx eax, [r6040_private.phy_addr] + stdcall r6040_phy_write, eax, 4, PHY_CAP + stdcall r6040_phy_write, eax, 0, PHY_MODE +; if PHY_MODE = 0x3100 + call r6040_phy_mode_chk + mov [r6040_private.phy_mode], ax + jmp .phy_readen +; end if +; if not (PHY_MODE and 0x0100) + mov [r6040_private.phy_mode], 0 +; end if + .phy_readen: + + ; Set duplex mode + mov ax, [r6040_private.phy_mode] + or [r6040_private.mcr0], ax + + ; improve performance (by RDC guys) + stdcall r6040_phy_read, 30, 17 + or ax, 0x4000 + stdcall r6040_phy_write, 30, 17, eax + + stdcall r6040_phy_read, 30, 17 + xor ax, -1 + or ax, 0x2000 + xor ax, -1 + stdcall r6040_phy_write, 30, 17, eax + + stdcall r6040_phy_write, 0, 19, 0x0000 + stdcall r6040_phy_write, 0, 30, 0x01F0 + + ; Initialize all Mac registers + call r6040_reset + + xor eax, eax + .out: + ret + + + + + + +align 4 +r6040_reset: + + DEBUGF 1, "Resetting r6040\n" + + push eax ecx edx + ; Mask off Interrupt + mov eax, MSK_INT + mov edx, [io_addr] + add edx, MIER + out dx, ax + + ;Reset RDC MAC + mov eax, MAC_RST + mov edx, [io_addr] + add edx, MCR1 + out dx, ax + + mov ecx, 2048 ;limit + .read: + in ax, dx + test ax, 0x1 + jnz @f + dec ecx + test ecx, ecx + jnz .read + @@: + ;Reset internal state machine + mov ax, 2 + mov edx, [io_addr] + add edx, MAC_SM + out dx, ax + xor ax, ax + out dx, ax + mov esi, 5 + call delay_ms + + ;MAC Bus Control Register + mov ax, MBCR_DEFAULT + mov edx, [io_addr] + add edx, MBCR + out dx, ax + + ;Buffer Size Register + mov ax, MAX_BUF_SIZE + mov edx, [io_addr] + add edx, MR_BSR + out dx, ax + + ;Write TX ring start address + mov eax, r6040_tx_ring - OS_BASE ;Asper: Maybe we can just write dword? Hidnplayr: better use word, as described in datasheet. + mov edx, [io_addr] + add edx, MTD_SA0 + out dx, ax + shr eax, 16 + add edx, MTD_SA1 - MTD_SA0 + out dx, ax + + ;Write RX ring start address + mov eax, r6040_rx_ring - OS_BASE ;Asper: Maybe we can just write dword? + mov edx, [io_addr] + add edx, MRD_SA0 + out dx, ax + shr eax, 16 + add edx, MRD_SA1 - MRD_SA0 + out dx, ax + + ;Set interrupt waiting time and packet numbers + xor ax, ax + mov edx, [io_addr] + add edx, MT_ICR + out dx, ax + + ;Asper: ~ Disable ints ;Enable interrupts + ;mov ax, MSK_INT ;INT_MASK ;Asper ~ + ;mov edx, [io_addr] + ;add edx, MIER + ;out dx, ax + + ;Enable TX and RX + mov ax, [r6040_private.mcr0] + or ax, 0x0002 + mov edx, [io_addr] + out dx, ax + + ;Let TX poll the descriptors + ;we may got called by r6040_tx_timeout which has left + ;some unset tx buffers + xor ax, ax + inc ax + mov edx, [io_addr] + add edx, MTPR + out dx, ax + + pop edx ecx eax + + DEBUGF 1, "reset ok!\n" + + ; Indicate that we have successfully reset the card + mov eax, [pci_data] + mov [eth_status], eax + ret + + + +proc r6040_tx_timeout + push eax edx + ;... + inc [stats.tx_errors] + ;Reset MAC and re-init all registers + call r6040_init_mac_regs + pop edx eax + ret +endp + +proc r6040_get_stats + push eax edx + mov edx, [io_addr] + add edx, ME_CNT1 + in al, dx + add [stats.rx_crc_errors], al + mov edx, [io_addr] + add edx, ME_CNT0 + in al, dx + add [stats.multicast], al + pop edx eax + ret +endp + +;... + +proc r6040_phy_mode_chk + push ebx + ;PHY Link Status Check + movzx eax, [r6040_private.phy_addr] + stdcall r6040_phy_read, eax, 1 + test eax, 0x4 + jnz @f + mov eax, 0x8000 ;Link Failed, full duplex + @@: + ;PHY Chip Auto-Negotiation Status + movzx eax, [r6040_private.phy_addr] + stdcall r6040_phy_read, eax, 1 + test eax, 0x0020 + jz .force_mode + ;Auto Negotuiation Mode + movzx eax, [r6040_private.phy_addr] + stdcall r6040_phy_read, eax, 5 + mov ebx, eax + movzx eax, [r6040_private.phy_addr] + stdcall r6040_phy_read, eax, 4 + and eax, ebx + test eax, 0x140 + jz .ret_0 + jmp .ret_0x8000 + .force_mode: + ;Force Mode + movzx eax, [r6040_private.phy_addr] + stdcall r6040_phy_read, eax, 0 + test eax, 0x100 + jz .ret_0 + .ret_0x8000: + mov eax, 0x8000 + pop ebx + ret + .ret_0: + xor eax, eax + pop ebx + ret +endp + + + +;*************************************************************************** +; Function +; r6040_rx +; Description +; polls card to see if there is a packet waiting +; +; Currently only supports one descriptor per packet, if packet is fragmented +; between multiple descriptors you will lose part of the packet +;*************************************************************************** +r6040_poll: + push ebx ecx esi edi + + xor eax, eax + mov [eth_rx_data_len], ax + + movzx eax, [r6040_private.cur_rx] + mov ebx, eax + shl ebx, 5 + + mov cx, [ebx+r6040_rx_ring+r6040_x_head.status] ; Read the descriptor status + test cx, DSC_OWNER_MAC + jnz .out + + test cx, DSC_RX_ERR ; Global error status set + jz .no_dsc_rx_err + ;... + jmp .out + + .no_dsc_rx_err: + ; Packet successfully received + movzx ecx, [ebx+r6040_rx_ring+r6040_x_head.len] + and ecx, 0xFFF + sub ecx, 4 ; Do not count the CRC + mov [eth_rx_data_len], cx + mov esi, [ebx+r6040_rx_ring+r6040_x_head.skb_ptr] + + push ecx + shr ecx, 2 + mov edi, Ether_buffer + cld + rep movsd + pop ecx + and ecx, 3 + rep movsb + + or [ebx+r6040_rx_ring+r6040_x_head.status], DSC_OWNER_MAC + + inc [r6040_private.cur_rx] + and [r6040_private.cur_rx], RX_RING_SIZE-1 + + xor eax, eax + .out: + pop edi esi ecx ebx + ret + + + +;*************************************************************************** +; Function +; r6040_transmit +; Description +; Transmits a packet of data via the ethernet card +; Pointer to 48 bit destination address in edi +; Type of packet in bx +; size of packet in ecx +; pointer to packet data in esi +; +;*************************************************************************** +r6040_transmit: + cmp ecx, MAX_BUF_SIZE + jg .out ; packet is too long + + push edi esi ebx ecx + + movzx eax, [r6040_private.cur_tx] + shl eax, 5 + +; DEBUGF 1,"R6040: TX buffer status: 0x%x, eax=%u\n", [eax + r6040_tx_ring + r6040_x_head.status]:4, eax + + test [r6040_tx_ring + eax + r6040_x_head.status], 0x8000 ; check if buffer is available + jz .l3 + + push ecx esi + mov ecx, [timer_ticks] + add ecx, 100 + .l2: + test [r6040_tx_ring + eax + r6040_x_head.status], 0x8000 + jz .l5 + cmp ecx, [timer_ticks] + jb .l4 + mov esi, 10 + call delay_ms + jmp .l2 + + .l4: + pop esi ecx + DEBUGF 1,"R6040: Send timeout\n" + jmp .out + + .l5: + pop esi ecx + .l3: + push eax + + mov esi, edi + +; point to the current tx buffer + movzx edi, [r6040_private.cur_tx] + imul edi, MAX_BUF_SIZE + add edi, r6040_txb + lea eax, [edi - OS_BASE] ; real buffer address in eax + +; copy destination address + movsd + movsw +; copy source address + mov esi, node_addr + movsd + movsw +; copy packet type + mov [edi], bx + add edi, 2 + + mov esi, [esp+8+4] + mov ecx, [esp+4] +; copy the packet data + push ecx + shr ecx,2 + rep movsd + pop ecx + and ecx,3 + rep movsb + + pop edi + + mov ecx, [esp] + add ecx, ETH_HLEN + cmp cx, ETH_ZLEN + jae @f + mov cx, ETH_ZLEN + @@: + + mov [r6040_tx_ring + edi + r6040_x_head.len], cx + mov [r6040_tx_ring + edi + r6040_x_head.buf], eax + mov [r6040_tx_ring + edi + r6040_x_head.status], 0x8000 + + ; Trigger the MAC to check the TX descriptor + mov ax, 0x01 + mov edx, [io_addr] + add edx, MTPR + out dx, ax + + inc [r6040_private.cur_tx] + and [r6040_private.cur_tx], TX_RING_SIZE-1 + xor eax, eax + + pop ecx ebx esi edi + .out: + ret + + + +r6040_mac_address: + push eax ecx edx esi edi + ; MAC operation register + mov ax, 1 + mov edx, [io_addr] + add edx, MCR1 + out dx, ax + ; Reset MAC + mov ax, 2 + mov edx, [io_addr] + add edx, MAC_SM + out dx, ax + ; Reset internal state machine + xor ax, ax + out dx, ax + mov esi, 5 + call delay_ms + + ; Restore MAC Address + mov ecx, 3 + mov edi, node_addr + mov edx, [io_addr] + add edx, MID_0L + .mac: + in ax, dx + stosw + add edx, 2 + dec ecx + jnz .mac + + pop edi esi edx ecx eax + ret + diff --git a/kernel/trunk/network/eth_drv/ethernet.inc b/kernel/trunk/network/eth_drv/ethernet.inc index 6393ba728a..5a8e4772d0 100644 --- a/kernel/trunk/network/eth_drv/ethernet.inc +++ b/kernel/trunk/network/eth_drv/ethernet.inc @@ -49,7 +49,7 @@ struc ETH_FRAME .SrcMAC dp ? ;source MAC-address [6 bytes] .Type dw ? ;type of the upper-layer protocol [2 bytes] .Data db ? ;data [46-1500 bytes] -} + } virtual at Ether_buffer ETH_FRAME ETH_FRAME @@ -103,6 +103,7 @@ include "drivers/sis900.inc" include "drivers/pcnet32.inc" include "drivers/rtl8169.inc" include "drivers/forcedeth.inc" +include "drivers/r6040.inc" ; PCICards ; ======== @@ -125,29 +126,28 @@ dd 0x10298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 dd 0x12298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 dd 0x10308086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 dd 0x24498086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 -dd 0x10688086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 dd 0x802910ec, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit, 0 -dd 0x813910ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable ; tested by hidnplayr: works ok -dd 0x813810ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable -dd 0x12111113, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable ; tested by hidnplayr: works ok -dd 0x13601500, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable -dd 0x13604033, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable -dd 0x13001186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable -dd 0x13401186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable -dd 0xab0613d1, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable -dd 0xa1171259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable -dd 0xa11e1259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable -dd 0xab0614ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable -dd 0xab0714ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable -dd 0x123411db, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable -dd 0x91301432, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable -dd 0x101202ac, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable -dd 0x0106018a, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable -dd 0x1211126c, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable -dd 0x81391743, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable -dd 0x8139021b, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +;dd 0x813910ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +;dd 0x813810ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +;dd 0x12111113, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +;dd 0x13601500, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +;dd 0x13604033, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +;dd 0x13001186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +;dd 0x13401186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +;dd 0xab0613d1, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +;dd 0xa1171259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +;dd 0xa11e1259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +;dd 0xab0614ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +;dd 0xab0714ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +;dd 0x123411db, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +;dd 0x91301432, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +;dd 0x101202ac, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +;dd 0x0106018a, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +;dd 0x1211126c, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +;dd 0x81391743, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable +;dd 0x8139021b, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable dd 0x816810ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 dd 0x816910ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 @@ -189,58 +189,54 @@ dd 0x656410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 dd 0x450010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 dd 0x09001039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit, 0 +dd 0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit, 0 dd 0x20001022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0 dd 0x26251022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0 dd 0x20011022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0 -;dd 0x08031516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable +dd 0x006610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; nVidia Corporation nForce2 Ethernet Controller +dd 0x01c310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x00D610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x008610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x008c10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x00e610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x00df10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x005610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x005710de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x003710de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x003810de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x026810de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x026910de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x037210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x037310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x03e510de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x03e610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x03ee10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x03ef10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x045010de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x045110de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x045210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x045310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x054c10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x054d10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x054e10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x054f10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x07dc10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x07dd10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x07de10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x07df10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x076010de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; MCP77 Ethernet Controller +dd 0x076110de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x076210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x076310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x0ab010de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x0ab110de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x0ab210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x0ab310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x0d7d10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -; following cards are untested -dd 0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit, 0 -;dd 0x08001516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable -;dd 0x08911516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable - -dd 0x006610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; nVidia Corporation nForce2 Ethernet Controller -dd 0x01c310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x00D610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x008610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x008c10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x00e610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x00df10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x005610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x005710de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x003710de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x003810de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x026810de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x026910de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x037210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x037310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x03e510de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x03e610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x03ee10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x03ef10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x045010de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x045110de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x045210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x045310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x054c10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x054d10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x054e10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x054f10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x07dc10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x07dd10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x07de10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x07df10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x076010de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; MCP77 Ethernet Controller -dd 0x076110de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x076210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x076310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x0ab010de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x0ab110de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x0ab210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x0ab310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested -dd 0x0d7d10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested +dd 0x604017F3, r6040_probe, r6040_reset, r6040_poll, r6040_transmit, 0 rb PCICARDS_ENTRY_SIZE ; end of list marker, do not remove endg