176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Copyright (c) 2008 Marty Connor <mdc@etherboot.org> 376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Copyright (c) 2008 Entity Cyber, Inc. 476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * This program is free software; you can redistribute it and/or 676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * modify it under the terms of the GNU General Public License as 776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * published by the Free Software Foundation; either version 2 of the 876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * License, or any later version. 976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * This program is distributed in the hope that it will be useful, but 1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * WITHOUT ANY WARRANTY; without even the implied warranty of 1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * General Public License for more details. 1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * You should have received a copy of the GNU General Public License 1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * along with this program; if not, write to the Free Software 1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * This driver is based on rtl8169 data sheets and work by: 2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw> 2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com> 2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Copyright (c) a lot of people too. Please respect their work. 2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2676d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanFILE_LICENCE ( GPL2_OR_LATER ); 2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdint.h> 2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdio.h> 3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdlib.h> 3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <string.h> 3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <unistd.h> 3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <assert.h> 3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <byteswap.h> 3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <errno.h> 3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/ethernet.h> 3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/if_ether.h> 3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/io.h> 3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/iobuf.h> 4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/malloc.h> 4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/netdevice.h> 4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/pci.h> 4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/timer.h> 4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <mii.h> 4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "r8169.h" 4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*** Low level hardware routines ***/ 4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void mdio_write(void *ioaddr, int reg_addr, int value) 5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int i; 5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "mdio_write\n" ); 5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0x1f) << 16 | (value & 0xffff)); 5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = 20; i > 0; i--) { 5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Check if the RTL8169 has completed writing to the specified 6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * MII register. 6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!(RTL_R32(PHYAR) & 0x80000000)) 6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman udelay(25); 6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int mdio_read(void *ioaddr, int reg_addr) 7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int i, value = -1; 7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "mdio_read\n" ); 7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32(PHYAR, 0x0 | (reg_addr & 0x1f) << 16); 7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = 20; i > 0; i--) { 7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Check if the RTL8169 has completed retrieving data from 8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * the specified MII register. 8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (RTL_R32(PHYAR) & 0x80000000) { 8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman value = RTL_R32(PHYAR) & 0xffff; 8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman udelay(25); 8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return value; 8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void mdio_patch(void *ioaddr, int reg_addr, int value) 9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "mdio_patch\n" ); 9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, reg_addr, mdio_read(ioaddr, reg_addr) | value); 9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_ephy_write(void *ioaddr, int reg_addr, int value) 9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int i; 10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_ephy_write\n" ); 10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32(EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) | 10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT); 10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = 0; i < 100; i++) { 10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!(RTL_R32(EPHYAR) & EPHYAR_FLAG)) 10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman udelay(10); 11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic u16 rtl_ephy_read(void *ioaddr, int reg_addr) 11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u16 value = 0xffff; 11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int i; 11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_ephy_read\n" ); 12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32(EPHYAR, (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT); 12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = 0; i < 100; i++) { 12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (RTL_R32(EPHYAR) & EPHYAR_FLAG) { 12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman value = RTL_R32(EPHYAR) & EPHYAR_DATA_MASK; 12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman udelay(10); 12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return value; 13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_csi_write(void *ioaddr, int addr, int value) 13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int i; 13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_csi_write\n" ); 13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32(CSIDR, value); 14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32(CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) | 14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT); 14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = 0; i < 100; i++) { 14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!(RTL_R32(CSIAR) & CSIAR_FLAG)) 14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman udelay(10); 14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic u32 rtl_csi_read(void *ioaddr, int addr) 15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 value = ~0x00; 15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int i; 15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_csi_read\n" ); 15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32(CSIAR, (addr & CSIAR_ADDR_MASK) | 15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT); 16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = 0; i < 100; i++) { 16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (RTL_R32(CSIAR) & CSIAR_FLAG) { 16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman value = RTL_R32(CSIDR); 16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman udelay(10); 16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return value; 17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8169_irq_mask_and_ack(void *ioaddr) 17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_irq_mask_and_ack\n" ); 17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16(IntrMask, 0x0000); 17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16(IntrStatus, 0xffff); 17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic unsigned int rtl8169_tbi_reset_pending(void *ioaddr) 18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_tbi_reset_pending\n" ); 18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return RTL_R32(TBICSR) & TBIReset; 18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic unsigned int rtl8169_xmii_reset_pending(void *ioaddr) 18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_xmii_reset_pending\n" ); 19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return mdio_read(ioaddr, MII_BMCR) & BMCR_RESET; 19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic unsigned int rtl8169_tbi_link_ok(void *ioaddr) 19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_tbi_link_ok\n" ); 19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return RTL_R32(TBICSR) & TBILinkOk; 20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic unsigned int rtl8169_xmii_link_ok(void *ioaddr) 20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_xmii_link_ok\n" ); 20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return RTL_R8(PHYstatus) & LinkStatus; 20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8169_tbi_reset_enable(void *ioaddr) 21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_tbi_reset_enable\n" ); 21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32(TBICSR, RTL_R32(TBICSR) | TBIReset); 21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8169_xmii_reset_enable(void *ioaddr) 21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int val; 21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_xmii_reset_enable\n" ); 22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 22276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman val = mdio_read(ioaddr, MII_BMCR) | BMCR_RESET; 22376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, MII_BMCR, val & 0xffff); 22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int rtl8169_set_speed_tbi(struct net_device *dev, 22776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u8 autoneg, u16 speed, u8 duplex) 22876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 22976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp = netdev_priv(dev); 23076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ioaddr = tp->mmio_addr; 23176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int ret = 0; 23276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 reg; 23376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 23476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_set_speed_tbi\n" ); 23576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 23676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman reg = RTL_R32(TBICSR); 23776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((autoneg == AUTONEG_DISABLE) && (speed == SPEED_1000) && 23876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (duplex == DUPLEX_FULL)) { 23976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32(TBICSR, reg & ~(TBINwEnable | TBINwRestart)); 24076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else if (autoneg == AUTONEG_ENABLE) 24176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32(TBICSR, reg | TBINwEnable | TBINwRestart); 24276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else { 24376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "incorrect speed setting refused in TBI mode\n" ); 24476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ret = -EOPNOTSUPP; 24576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 24676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ret; 24776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 24876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 24976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int rtl8169_set_speed_xmii(struct net_device *dev, 25076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u8 autoneg, u16 speed, u8 duplex) 25176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 25276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp = netdev_priv(dev); 25376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ioaddr = tp->mmio_addr; 25476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int auto_nego, giga_ctrl; 25576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 25676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_set_speed_xmii\n" ); 25776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 25876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman auto_nego = mdio_read(ioaddr, MII_ADVERTISE); 25976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL | 26076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ADVERTISE_100HALF | ADVERTISE_100FULL); 26176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman giga_ctrl = mdio_read(ioaddr, MII_CTRL1000); 26276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); 26376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 26476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (autoneg == AUTONEG_ENABLE) { 26576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman auto_nego |= (ADVERTISE_10HALF | ADVERTISE_10FULL | 26676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ADVERTISE_100HALF | ADVERTISE_100FULL); 26776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF; 26876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 26976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (speed == SPEED_10) 27076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman auto_nego |= ADVERTISE_10HALF | ADVERTISE_10FULL; 27176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else if (speed == SPEED_100) 27276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman auto_nego |= ADVERTISE_100HALF | ADVERTISE_100FULL; 27376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else if (speed == SPEED_1000) 27476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF; 27576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 27676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (duplex == DUPLEX_HALF) 27776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman auto_nego &= ~(ADVERTISE_10FULL | ADVERTISE_100FULL); 27876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 27976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (duplex == DUPLEX_FULL) 28076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_100HALF); 28176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 28276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* This tweak comes straight from Realtek's driver. */ 28376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((speed == SPEED_100) && (duplex == DUPLEX_HALF) && 28476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ((tp->mac_version == RTL_GIGA_MAC_VER_13) || 28576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (tp->mac_version == RTL_GIGA_MAC_VER_16))) { 28676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman auto_nego = ADVERTISE_100HALF | ADVERTISE_CSMA; 28776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 28876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 28976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 29076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* The 8100e/8101e/8102e do Fast Ethernet only. */ 29176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((tp->mac_version == RTL_GIGA_MAC_VER_07) || 29276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (tp->mac_version == RTL_GIGA_MAC_VER_08) || 29376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (tp->mac_version == RTL_GIGA_MAC_VER_09) || 29476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (tp->mac_version == RTL_GIGA_MAC_VER_10) || 29576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (tp->mac_version == RTL_GIGA_MAC_VER_13) || 29676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (tp->mac_version == RTL_GIGA_MAC_VER_14) || 29776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (tp->mac_version == RTL_GIGA_MAC_VER_15) || 29876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (tp->mac_version == RTL_GIGA_MAC_VER_16)) { 29976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((giga_ctrl & (ADVERTISE_1000FULL | ADVERTISE_1000HALF))) { 30076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "PHY does not support 1000Mbps.\n" ); 30176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 30276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); 30376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 30476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 30576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; 30676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 30776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((tp->mac_version == RTL_GIGA_MAC_VER_11) || 30876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (tp->mac_version == RTL_GIGA_MAC_VER_12) || 30976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (tp->mac_version >= RTL_GIGA_MAC_VER_17)) { 31076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 31176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Wake up the PHY. 31276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Vendor specific (0x1f) and reserved (0x0e) MII registers. 31376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 31476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, 0x1f, 0x0000); 31576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, 0x0e, 0x0000); 31676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 31776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 31876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->phy_auto_nego_reg = auto_nego; 31976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->phy_1000_ctrl_reg = giga_ctrl; 32076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 32176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, MII_ADVERTISE, auto_nego); 32276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, MII_CTRL1000, giga_ctrl); 32376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); 32476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 32576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 32676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 32776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int rtl8169_set_speed(struct net_device *dev, 32876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u8 autoneg, u16 speed, u8 duplex) 32976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 33076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp = netdev_priv(dev); 33176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int ret; 33276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 33376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_set_speed\n" ); 33476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 33576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ret = tp->set_speed(dev, autoneg, speed, duplex); 33676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 33776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ret; 33876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 33976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 34076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8169_write_gmii_reg_bit(void *ioaddr, int reg, 34176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int bitnum, int bitval) 34276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 34376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int val; 34476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 34576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_write_gmii_reg_bit\n" ); 34676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 34776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman val = mdio_read(ioaddr, reg); 34876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman val = (bitval == 1) ? 34976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman val | (bitval << bitnum) : val & ~(0x0001 << bitnum); 35076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, reg, val & 0xffff); 35176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 35276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 35376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8169_get_mac_version(struct rtl8169_private *tp, 35476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ioaddr) 35576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 35676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 35776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * The driver currently handles the 8168Bf and the 8168Be identically 35876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * but they can be identified more specifically through the test below 35976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * if needed: 36076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 36176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * (RTL_R32(TxConfig) & 0x700000) == 0x500000 ? 8168Bf : 8168Be 36276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 36376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Same thing for the 8101Eb and the 8101Ec: 36476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 36576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * (RTL_R32(TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec 36676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 36776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const struct { 36876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 mask; 36976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 val; 37076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int mac_version; 37176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } mac_info[] = { 37276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 8168D family. */ 37376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7c800000, 0x28000000, RTL_GIGA_MAC_VER_25 }, 37476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 37576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 8168C family. */ 37676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7cf00000, 0x3ca00000, RTL_GIGA_MAC_VER_24 }, 37776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7cf00000, 0x3c900000, RTL_GIGA_MAC_VER_23 }, 37876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7cf00000, 0x3c800000, RTL_GIGA_MAC_VER_18 }, 37976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7c800000, 0x3c800000, RTL_GIGA_MAC_VER_24 }, 38076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7cf00000, 0x3c000000, RTL_GIGA_MAC_VER_19 }, 38176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7cf00000, 0x3c200000, RTL_GIGA_MAC_VER_20 }, 38276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7cf00000, 0x3c300000, RTL_GIGA_MAC_VER_21 }, 38376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7cf00000, 0x3c400000, RTL_GIGA_MAC_VER_22 }, 38476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7c800000, 0x3c000000, RTL_GIGA_MAC_VER_22 }, 38576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 38676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 8168B family. */ 38776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7cf00000, 0x38000000, RTL_GIGA_MAC_VER_12 }, 38876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7cf00000, 0x38500000, RTL_GIGA_MAC_VER_17 }, 38976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7c800000, 0x38000000, RTL_GIGA_MAC_VER_17 }, 39076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 }, 39176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 39276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 8101 family. */ 39376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7cf00000, 0x34a00000, RTL_GIGA_MAC_VER_09 }, 39476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7cf00000, 0x24a00000, RTL_GIGA_MAC_VER_09 }, 39576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7cf00000, 0x34900000, RTL_GIGA_MAC_VER_08 }, 39676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7cf00000, 0x24900000, RTL_GIGA_MAC_VER_08 }, 39776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7cf00000, 0x34800000, RTL_GIGA_MAC_VER_07 }, 39876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7cf00000, 0x24800000, RTL_GIGA_MAC_VER_07 }, 39976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7cf00000, 0x34000000, RTL_GIGA_MAC_VER_13 }, 40076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7cf00000, 0x34300000, RTL_GIGA_MAC_VER_10 }, 40176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7cf00000, 0x34200000, RTL_GIGA_MAC_VER_16 }, 40276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7c800000, 0x34800000, RTL_GIGA_MAC_VER_09 }, 40376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7c800000, 0x24800000, RTL_GIGA_MAC_VER_09 }, 40476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7c800000, 0x34000000, RTL_GIGA_MAC_VER_16 }, 40576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* FIXME: where did these entries come from ? -- FR */ 40676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0xfc800000, 0x38800000, RTL_GIGA_MAC_VER_15 }, 40776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0xfc800000, 0x30800000, RTL_GIGA_MAC_VER_14 }, 40876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 40976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 8110 family. */ 41076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0xfc800000, 0x98000000, RTL_GIGA_MAC_VER_06 }, 41176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0xfc800000, 0x18000000, RTL_GIGA_MAC_VER_05 }, 41276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0xfc800000, 0x10000000, RTL_GIGA_MAC_VER_04 }, 41376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0xfc800000, 0x04000000, RTL_GIGA_MAC_VER_03 }, 41476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0xfc800000, 0x00800000, RTL_GIGA_MAC_VER_02 }, 41576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0xfc800000, 0x00000000, RTL_GIGA_MAC_VER_01 }, 41676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 41776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x00000000, 0x00000000, RTL_GIGA_MAC_VER_01 } /* Catch-all */ 41876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }, *p = mac_info; 41976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 reg; 42076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 42176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_get_mac_version\n" ); 42276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 42376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman reg = RTL_R32(TxConfig); 42476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman while ((reg & p->mask) != p->val) 42576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman p++; 42676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->mac_version = p->mac_version; 42776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 42876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "tp->mac_version = %d\n", tp->mac_version ); 42976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 43076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (p->mask == 0x00000000) { 43176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "unknown MAC (%08x)\n", reg ); 43276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 43376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 43476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 43576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct phy_reg { 43676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u16 reg; 43776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u16 val; 43876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 43976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 44076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_phy_write(void *ioaddr, struct phy_reg *regs, int len) 44176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 44276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_phy_write\n" ); 44376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 44476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman while (len-- > 0) { 44576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, regs->reg, regs->val); 44676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman regs++; 44776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 44876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 44976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 45076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8169s_hw_phy_config(void *ioaddr) 45176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 45276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct { 45376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u16 regs[5]; /* Beware of bit-sign propagation */ 45476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } phy_magic[5] = { { 45576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x0000, //w 4 15 12 0 45676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0x00a1, //w 3 15 0 00a1 45776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0x0008, //w 2 15 0 0008 45876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0x1020, //w 1 15 0 1020 45976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0x1000 } },{ //w 0 15 0 1000 46076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x7000, //w 4 15 12 7 46176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0xff41, //w 3 15 0 ff41 46276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0xde60, //w 2 15 0 de60 46376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0x0140, //w 1 15 0 0140 46476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0x0077 } },{ //w 0 15 0 0077 46576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0xa000, //w 4 15 12 a 46676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0xdf01, //w 3 15 0 df01 46776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0xdf20, //w 2 15 0 df20 46876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0xff95, //w 1 15 0 ff95 46976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0xfa00 } },{ //w 0 15 0 fa00 47076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0xb000, //w 4 15 12 b 47176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0xff41, //w 3 15 0 ff41 47276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0xde20, //w 2 15 0 de20 47376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0x0140, //w 1 15 0 0140 47476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0x00bb } },{ //w 0 15 0 00bb 47576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0xf000, //w 4 15 12 f 47676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0xdf01, //w 3 15 0 df01 47776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0xdf20, //w 2 15 0 df20 47876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0xff95, //w 1 15 0 ff95 47976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 0xbf00 } //w 0 15 0 bf00 48076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 48176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }, *p = phy_magic; 48276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int i; 48376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 48476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169s_hw_phy_config\n" ); 48576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 48676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, 0x1f, 0x0001); //w 31 2 0 1 48776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, 0x15, 0x1000); //w 21 15 0 1000 48876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, 0x18, 0x65c7); //w 24 15 0 65c7 48976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0); //w 4 11 11 0 49076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 49176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = 0; i < ARRAY_SIZE(phy_magic); i++, p++) { 49276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int val, pos = 4; 49376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 49476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman val = (mdio_read(ioaddr, pos) & 0x0fff) | (p->regs[0] & 0xffff); 49576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, pos, val); 49676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman while (--pos >= 0) 49776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, pos, p->regs[4 - pos] & 0xffff); 49876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 1); //w 4 11 11 1 49976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0); //w 4 11 11 0 50076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 50176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, 0x1f, 0x0000); //w 31 2 0 0 50276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 50376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 50476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8169sb_hw_phy_config(void *ioaddr) 50576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 50676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct phy_reg phy_reg_init[] = { 50776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0002 }, 50876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x01, 0x90d0 }, 50976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0000 } 51076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }; 51176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 51276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169sb_hw_phy_config\n" ); 51376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 51476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); 51576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 51676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 51776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8168bb_hw_phy_config(void *ioaddr) 51876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 51976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct phy_reg phy_reg_init[] = { 52076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x10, 0xf41b }, 52176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0000 } 52276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }; 52376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 52476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, 0x1f, 0x0001); 52576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_patch(ioaddr, 0x16, 1 << 0); 52676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 52776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8168bb_hw_phy_config\n" ); 52876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 52976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); 53076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 53176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 53276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8168bef_hw_phy_config(void *ioaddr) 53376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 53476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct phy_reg phy_reg_init[] = { 53576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0001 }, 53676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x10, 0xf41b }, 53776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0000 } 53876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }; 53976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 54076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8168bef_hw_phy_config\n" ); 54176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 54276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); 54376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 54476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 54576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8168cp_1_hw_phy_config(void *ioaddr) 54676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 54776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct phy_reg phy_reg_init[] = { 54876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0000 }, 54976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1d, 0x0f00 }, 55076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0002 }, 55176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x0c, 0x1ec8 }, 55276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0000 } 55376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }; 55476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 55576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8168cp_1_hw_phy_config\n" ); 55676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 55776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); 55876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 55976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 56076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8168cp_2_hw_phy_config(void *ioaddr) 56176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 56276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct phy_reg phy_reg_init[] = { 56376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0001 }, 56476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1d, 0x3d98 }, 56576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0000 } 56676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }; 56776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 56876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8168cp_2_hw_phy_config\n" ); 56976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 57076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, 0x1f, 0x0000); 57176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_patch(ioaddr, 0x14, 1 << 5); 57276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_patch(ioaddr, 0x0d, 1 << 5); 57376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 57476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); 57576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 57676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 57776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8168c_1_hw_phy_config(void *ioaddr) 57876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 57976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct phy_reg phy_reg_init[] = { 58076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0001 }, 58176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x12, 0x2300 }, 58276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0002 }, 58376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x00, 0x88d4 }, 58476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x01, 0x82b1 }, 58576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x03, 0x7002 }, 58676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x08, 0x9e30 }, 58776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x09, 0x01f0 }, 58876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x0a, 0x5500 }, 58976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x0c, 0x00c8 }, 59076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0003 }, 59176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x12, 0xc096 }, 59276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x16, 0x000a }, 59376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0000 }, 59476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0000 }, 59576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x09, 0x2000 }, 59676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x09, 0x0000 } 59776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }; 59876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 59976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8168c_1_hw_phy_config\n" ); 60076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 60176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); 60276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 60376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_patch(ioaddr, 0x14, 1 << 5); 60476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_patch(ioaddr, 0x0d, 1 << 5); 60576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, 0x1f, 0x0000); 60676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 60776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 60876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8168c_2_hw_phy_config(void *ioaddr) 60976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 61076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct phy_reg phy_reg_init[] = { 61176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0001 }, 61276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x12, 0x2300 }, 61376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x03, 0x802f }, 61476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x02, 0x4f02 }, 61576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x01, 0x0409 }, 61676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x00, 0xf099 }, 61776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x04, 0x9800 }, 61876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x04, 0x9000 }, 61976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1d, 0x3d98 }, 62076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0002 }, 62176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x0c, 0x7eb8 }, 62276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0x0761 }, 62376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0003 }, 62476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x16, 0x0f0a }, 62576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0000 } 62676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }; 62776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 62876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8168c_2_hw_phy_config\n" ); 62976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 63076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); 63176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 63276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_patch(ioaddr, 0x16, 1 << 0); 63376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_patch(ioaddr, 0x14, 1 << 5); 63476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_patch(ioaddr, 0x0d, 1 << 5); 63576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, 0x1f, 0x0000); 63676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 63776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 63876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8168c_3_hw_phy_config(void *ioaddr) 63976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 64076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct phy_reg phy_reg_init[] = { 64176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0001 }, 64276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x12, 0x2300 }, 64376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1d, 0x3d98 }, 64476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0002 }, 64576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x0c, 0x7eb8 }, 64676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0x5461 }, 64776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0003 }, 64876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x16, 0x0f0a }, 64976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0000 } 65076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }; 65176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 65276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8168c_3_hw_phy_config\n" ); 65376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 65476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); 65576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 65676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_patch(ioaddr, 0x16, 1 << 0); 65776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_patch(ioaddr, 0x14, 1 << 5); 65876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_patch(ioaddr, 0x0d, 1 << 5); 65976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, 0x1f, 0x0000); 66076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 66176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 66276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8168c_4_hw_phy_config(void *ioaddr) 66376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 66476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8168c_4_hw_phy_config\n" ); 66576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 66676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8168c_3_hw_phy_config(ioaddr); 66776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 66876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 66976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8168d_hw_phy_config(void *ioaddr) 67076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 67176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct phy_reg phy_reg_init_0[] = { 67276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0001 }, 67376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x09, 0x2770 }, 67476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x08, 0x04d0 }, 67576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x0b, 0xad15 }, 67676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x0c, 0x5bf0 }, 67776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1c, 0xf101 }, 67876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0003 }, 67976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x14, 0x94d7 }, 68076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x12, 0xf4d6 }, 68176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x09, 0xca0f }, 68276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0002 }, 68376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x0b, 0x0b10 }, 68476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x0c, 0xd1f7 }, 68576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0002 }, 68676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0x5461 }, 68776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0002 }, 68876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x05, 0x6662 }, 68976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0000 }, 69076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x14, 0x0060 }, 69176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0000 }, 69276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x0d, 0xf8a0 }, 69376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0005 }, 69476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x05, 0xffc2 } 69576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }; 69676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 69776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8168d_hw_phy_config\n" ); 69876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 69976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0)); 70076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 70176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (mdio_read(ioaddr, 0x06) == 0xc400) { 70276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct phy_reg phy_reg_init_1[] = { 70376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0005 }, 70476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x01, 0x0300 }, 70576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0000 }, 70676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x11, 0x401c }, 70776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x16, 0x4100 }, 70876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0005 }, 70976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x07, 0x0010 }, 71076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x05, 0x83dc }, 71176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0x087d }, 71276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x05, 0x8300 }, 71376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0x0101 }, 71476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0x05f8 }, 71576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0xf9fa }, 71676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0xfbef }, 71776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0x79e2 }, 71876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0x835f }, 71976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0xe0f8 }, 72076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0x9ae1 }, 72176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0xf89b }, 72276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0xef31 }, 72376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0x3b65 }, 72476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0xaa07 }, 72576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0x81e4 }, 72676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0xf89a }, 72776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0xe5f8 }, 72876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0x9baf }, 72976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0x06ae }, 73076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x05, 0x83dc }, 73176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0x8300 }, 73276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }; 73376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 73476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_phy_write(ioaddr, phy_reg_init_1, 73576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ARRAY_SIZE(phy_reg_init_1)); 73676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 73776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 73876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, 0x1f, 0x0000); 73976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 74076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 74176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8102e_hw_phy_config(void *ioaddr) 74276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 74376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct phy_reg phy_reg_init[] = { 74476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0003 }, 74576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x08, 0x441d }, 74676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x01, 0x9100 }, 74776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x1f, 0x0000 } 74876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }; 74976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 75076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8102e_hw_phy_config\n" ); 75176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 75276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, 0x1f, 0x0000); 75376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_patch(ioaddr, 0x11, 1 << 12); 75476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_patch(ioaddr, 0x19, 1 << 13); 75576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 75676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); 75776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 75876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 75976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_hw_phy_config(struct net_device *dev) 76076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 76176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp = netdev_priv(dev); 76276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ioaddr = tp->mmio_addr; 76376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 76476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_hw_phy_config\n" ); 76576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 76676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "mac_version = 0x%02x\n", tp->mac_version ); 76776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 76876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman switch (tp->mac_version) { 76976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_01: 77076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 77176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_02: 77276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_03: 77376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169s_hw_phy_config(ioaddr); 77476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 77576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_04: 77676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169sb_hw_phy_config(ioaddr); 77776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 77876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_07: 77976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_08: 78076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_09: 78176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8102e_hw_phy_config(ioaddr); 78276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 78376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_11: 78476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8168bb_hw_phy_config(ioaddr); 78576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 78676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_12: 78776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8168bef_hw_phy_config(ioaddr); 78876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 78976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_17: 79076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8168bef_hw_phy_config(ioaddr); 79176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 79276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_18: 79376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8168cp_1_hw_phy_config(ioaddr); 79476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 79576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_19: 79676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8168c_1_hw_phy_config(ioaddr); 79776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 79876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_20: 79976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8168c_2_hw_phy_config(ioaddr); 80076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 80176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_21: 80276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8168c_3_hw_phy_config(ioaddr); 80376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 80476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_22: 80576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8168c_4_hw_phy_config(ioaddr); 80676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 80776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_23: 80876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_24: 80976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8168cp_2_hw_phy_config(ioaddr); 81076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 81176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_25: 81276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8168d_hw_phy_config(ioaddr); 81376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 81476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 81576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman default: 81676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 81776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 81876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 81976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 82076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8169_phy_reset(struct net_device *dev __unused, 82176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp) 82276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 82376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ioaddr = tp->mmio_addr; 82476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int i; 82576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 82676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_phy_reset\n" ); 82776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 82876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->phy_reset_enable(ioaddr); 82976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = 0; i < 100; i++) { 83076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!tp->phy_reset_pending(ioaddr)) 83176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return; 83276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdelay ( 1 ); 83376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 83476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "PHY reset failed.\n" ); 83576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 83676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 83776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp) 83876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 83976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ioaddr = tp->mmio_addr; 84076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 84176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_init_phy\n" ); 84276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 84376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_hw_phy_config(dev); 84476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 84576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (tp->mac_version <= RTL_GIGA_MAC_VER_06) { 84676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "Set MAC Reg C+CR Offset 0x82h = 0x01h\n" ); 84776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(0x82, 0x01); 84876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 84976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 85076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40); 85176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 85276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (tp->mac_version <= RTL_GIGA_MAC_VER_06) 85376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pci_write_config_byte(tp->pci_dev, PCI_CACHE_LINE_SIZE, 0x08); 85476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 85576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (tp->mac_version == RTL_GIGA_MAC_VER_02) { 85676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "Set MAC Reg C+CR Offset 0x82h = 0x01h\n" ); 85776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(0x82, 0x01); 85876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "Set PHY Reg 0x0bh = 0x00h\n" ); 85976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0 86076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 86176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 86276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_phy_reset(dev, tp); 86376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 86476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 86576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * rtl8169_set_speed_xmii takes good care of the Fast Ethernet 86676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * only 8101. Don't panic. 86776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 86876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_set_speed(dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL); 86976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 87076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((RTL_R8(PHYstatus) & TBI_Enable)) 87176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "TBI auto-negotiating\n" ); 87276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 87376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 87476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic const struct rtl_cfg_info { 87576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void (*hw_start)(struct net_device *); 87676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int region; 87776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int align; 87876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u16 intr_event; 87976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u16 napi_event; 88076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned features; 88176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} rtl_cfg_infos [] = { 88276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman [RTL_CFG_0] = { 88376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .hw_start = rtl_hw_start_8169, 88476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .region = 1, 88576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .align = 0, 88676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .intr_event = SYSErr | LinkChg | RxOverflow | 88776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RxFIFOOver | TxErr | TxOK | RxOK | RxErr, 88876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow, 88976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .features = RTL_FEATURE_GMII 89076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }, 89176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman [RTL_CFG_1] = { 89276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .hw_start = rtl_hw_start_8168, 89376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .region = 2, 89476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .align = 8, 89576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .intr_event = SYSErr | LinkChg | RxOverflow | 89676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman TxErr | TxOK | RxOK | RxErr, 89776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .napi_event = TxErr | TxOK | RxOK | RxOverflow, 89876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .features = RTL_FEATURE_GMII 89976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }, 90076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman [RTL_CFG_2] = { 90176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .hw_start = rtl_hw_start_8101, 90276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .region = 2, 90376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .align = 8, 90476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout | 90576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RxFIFOOver | TxErr | TxOK | RxOK | RxErr, 90676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow, 90776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 90876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 90976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 91076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8169_hw_reset(void *ioaddr) 91176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 91276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_hw_reset\n" ); 91376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 91476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Disable interrupts */ 91576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_irq_mask_and_ack(ioaddr); 91676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 91776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Reset the chipset */ 91876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(ChipCmd, CmdReset); 91976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 92076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* PCI commit */ 92176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_R8(ChipCmd); 92276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 92376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 92476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp) 92576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 92676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ioaddr = tp->mmio_addr; 92776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 cfg = rtl8169_rx_config; 92876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 92976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_set_rx_tx_config_registers\n" ); 93076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 93176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cfg |= (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask); 93276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32(RxConfig, cfg); 93376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 93476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Set DMA burst size and Interframe Gap Time */ 93576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) | 93676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (InterFrameGap << TxInterFrameGapShift)); 93776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 93876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 93976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_soft_reset ( struct net_device *dev ) 94076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 94176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp = netdev_priv(dev); 94276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ioaddr = tp->mmio_addr; 94376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int i; 94476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 94576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_hw_soft_reset\n" ); 94676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 94776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Soft reset the chip. */ 94876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(ChipCmd, CmdReset); 94976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 95076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Check that the chip has finished the reset. */ 95176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = 0; i < 100; i++) { 95276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((RTL_R8(ChipCmd) & CmdReset) == 0) 95376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 95476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mdelay ( 1 ); 95576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 95676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 95776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( i == 100 ) { 95876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "Reset Failed! (> 100 iterations)\n" ); 95976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 96076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 96176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 96276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_hw_start ( struct net_device *dev ) 96376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 96476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp = netdev_priv ( dev ); 96576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 96676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_hw_start\n" ); 96776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 96876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Soft reset NIC */ 96976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_soft_reset ( dev ); 97076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 97176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->hw_start ( dev ); 97276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 97376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 97476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp, 97576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ioaddr) 97676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 97776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_set_rx_tx_desc_registers\n" ); 97876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 97976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 98076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh 98176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * register to be written before TxDescAddrLow to work. 98276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Switching from MMIO to I/O access fixes the issue as well. 98376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 98476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32 ( TxDescStartAddrHigh, 0 ); 98576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32 ( TxDescStartAddrLow, virt_to_bus ( tp->tx_base ) ); 98676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32 ( RxDescAddrHigh, 0 ); 98776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32 ( RxDescAddrLow, virt_to_bus ( tp->rx_base ) ); 98876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 98976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 99076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic u16 rtl_rw_cpluscmd(void *ioaddr) 99176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 99276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u16 cmd; 99376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 99476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_rw_cpluscmd\n" ); 99576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 99676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cmd = RTL_R16(CPlusCmd); 99776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16(CPlusCmd, cmd); 99876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return cmd; 99976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 100076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 100176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_set_rx_max_size(void *ioaddr) 100276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 100376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_set_rx_max_size\n" ); 100476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 100576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16 ( RxMaxSize, RX_BUF_SIZE ); 100676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 100776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 100876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8169_set_magic_reg(void *ioaddr, unsigned mac_version) 100976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 101076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct { 101176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 mac_version; 101276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 clk; 101376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 val; 101476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } cfg2_info [] = { 101576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { RTL_GIGA_MAC_VER_05, PCI_Clock_33MHz, 0x000fff00 }, // 8110SCd 101676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { RTL_GIGA_MAC_VER_05, PCI_Clock_66MHz, 0x000fffff }, 101776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { RTL_GIGA_MAC_VER_06, PCI_Clock_33MHz, 0x00ffff00 }, // 8110SCe 101876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { RTL_GIGA_MAC_VER_06, PCI_Clock_66MHz, 0x00ffffff } 101976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }, *p = cfg2_info; 102076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int i; 102176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 clk; 102276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 102376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_set_magic_reg\n" ); 102476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 102576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman clk = RTL_R8(Config2) & PCI_Clock_66MHz; 102676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = 0; i < ARRAY_SIZE(cfg2_info); i++, p++) { 102776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((p->mac_version == mac_version) && (p->clk == clk)) { 102876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32(0x7c, p->val); 102976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 103076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 103176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 103276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 103376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 103476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_set_rx_mode ( struct net_device *netdev ) 103576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 103676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp = netdev_priv ( netdev ); 103776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ioaddr = tp->mmio_addr; 103876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 tmp; 103976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 104076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_set_rx_mode\n" ); 104176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 104276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Accept all Multicast Packets */ 104376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 104476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32 ( MAR0 + 0, 0xffffffff ); 104576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32 ( MAR0 + 4, 0xffffffff ); 104676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 104776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tmp = rtl8169_rx_config | AcceptBroadcast | AcceptMulticast | AcceptMyPhys | 104876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ( RTL_R32 ( RxConfig ) & rtl_chip_info[tp->chipset].RxConfigMask ); 104976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 105076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32 ( RxConfig, tmp ); 105176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 105276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 105376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_hw_start_8169(struct net_device *dev) 105476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 105576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp = netdev_priv(dev); 105676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ioaddr = tp->mmio_addr; 105776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct pci_device *pdev = tp->pci_dev; 105876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 105976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_hw_start_8169\n" ); 106076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 106176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (tp->mac_version == RTL_GIGA_MAC_VER_05) { 106276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | PCIMulRW); 106376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08); 106476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 106576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 106676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(Cfg9346, Cfg9346_Unlock); 106776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 106876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((tp->mac_version == RTL_GIGA_MAC_VER_01) || 106976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (tp->mac_version == RTL_GIGA_MAC_VER_02) || 107076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (tp->mac_version == RTL_GIGA_MAC_VER_03) || 107176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (tp->mac_version == RTL_GIGA_MAC_VER_04)) 107276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); 107376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 107476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(EarlyTxThres, EarlyTxThld); 107576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 107676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_set_rx_max_size(ioaddr); 107776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 107876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((tp->mac_version == RTL_GIGA_MAC_VER_01) || 107976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (tp->mac_version == RTL_GIGA_MAC_VER_02) || 108076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (tp->mac_version == RTL_GIGA_MAC_VER_03) || 108176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (tp->mac_version == RTL_GIGA_MAC_VER_04)) 108276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_set_rx_tx_config_registers(tp); 108376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 108476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW; 108576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 108676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((tp->mac_version == RTL_GIGA_MAC_VER_02) || 108776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (tp->mac_version == RTL_GIGA_MAC_VER_03)) { 108876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "Set MAC Reg C+CR Offset 0xE0. " 108976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "Bit-3 and bit-14 MUST be 1\n" ); 109076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->cp_cmd |= (1 << 14); 109176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 109276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 109376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16(CPlusCmd, tp->cp_cmd); 109476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 109576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_set_magic_reg(ioaddr, tp->mac_version); 109676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 109776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 109876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Undocumented corner. Supposedly: 109976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets 110076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 110176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16(IntrMitigate, 0x0000); 110276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 110376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_set_rx_tx_desc_registers(tp, ioaddr); 110476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 110576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((tp->mac_version != RTL_GIGA_MAC_VER_01) && 110676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (tp->mac_version != RTL_GIGA_MAC_VER_02) && 110776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (tp->mac_version != RTL_GIGA_MAC_VER_03) && 110876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (tp->mac_version != RTL_GIGA_MAC_VER_04)) { 110976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); 111076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_set_rx_tx_config_registers(tp); 111176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 111276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 111376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(Cfg9346, Cfg9346_Lock); 111476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 111576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Initially a 10 us delay. Turned it into a PCI commit. - FR */ 111676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_R8(IntrMask); 111776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 111876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32(RxMissed, 0); 111976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 112076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_set_rx_mode(dev); 112176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 112276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* no early-rx interrupts */ 112376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); 112476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 112576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman // RTL_W16(IntrMask, tp->intr_event); 112676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 112776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 112876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_tx_performance_tweak(struct pci_device *pdev, u16 force) 112976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 113076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct net_device *dev = pci_get_drvdata(pdev); 113176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp = netdev_priv(dev); 113276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int cap = tp->pcie_cap; 113376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 113476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_tx_performance_tweak\n" ); 113576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 113676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (cap) { 113776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u16 ctl; 113876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 113976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl); 114076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force; 114176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl); 114276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 114376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 114476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 114576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_csi_access_enable(void *ioaddr) 114676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 114776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 csi; 114876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 114976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_csi_access_enable\n" ); 115076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 115176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman csi = rtl_csi_read(ioaddr, 0x070c) & 0x00ffffff; 115276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_csi_write(ioaddr, 0x070c, csi | 0x27000000); 115376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 115476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 115576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct ephy_info { 115676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int offset; 115776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u16 mask; 115876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u16 bits; 115976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 116076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 116176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_ephy_init(void *ioaddr, struct ephy_info *e, int len) 116276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 116376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u16 w; 116476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 116576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_ephy_init\n" ); 116676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 116776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman while (len-- > 0) { 116876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman w = (rtl_ephy_read(ioaddr, e->offset) & ~e->mask) | e->bits; 116976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_ephy_write(ioaddr, e->offset, w); 117076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman e++; 117176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 117276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 117376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 117476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_disable_clock_request(struct pci_device *pdev) 117576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 117676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct net_device *dev = pci_get_drvdata(pdev); 117776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp = netdev_priv(dev); 117876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int cap = tp->pcie_cap; 117976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 118076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_disable_clock_request\n" ); 118176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 118276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (cap) { 118376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u16 ctl; 118476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 118576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pci_read_config_word(pdev, cap + PCI_EXP_LNKCTL, &ctl); 118676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ctl &= ~PCI_EXP_LNKCTL_CLKREQ_EN; 118776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pci_write_config_word(pdev, cap + PCI_EXP_LNKCTL, ctl); 118876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 118976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 119076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 119176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define R8168_CPCMD_QUIRK_MASK (\ 119276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman EnableBist | \ 119376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Mac_dbgo_oe | \ 119476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Force_half_dup | \ 119576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Force_rxflow_en | \ 119676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Force_txflow_en | \ 119776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Cxpl_dbg_sel | \ 119876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ASF | \ 119976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PktCntrDisable | \ 120076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Mac_dbgo_sel) 120176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 120276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_hw_start_8168bb(void *ioaddr, struct pci_device *pdev) 120376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 120476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_hw_start_8168bb\n" ); 120576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 120676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); 120776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 120876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); 120976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 121076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_tx_performance_tweak(pdev, 121176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (0x5 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN); 121276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 121376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 121476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_hw_start_8168bef(void *ioaddr, struct pci_device *pdev) 121576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 121676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_hw_start_8168bef\n" ); 121776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 121876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_hw_start_8168bb(ioaddr, pdev); 121976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 122076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(EarlyTxThres, EarlyTxThld); 122176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 122276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(Config4, RTL_R8(Config4) & ~(1 << 0)); 122376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 122476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 122576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void __rtl_hw_start_8168cp(void *ioaddr, struct pci_device *pdev) 122676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 122776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "__rtl_hw_start_8168cp\n" ); 122876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 122976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(Config1, RTL_R8(Config1) | Speed_down); 123076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 123176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); 123276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 123376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); 123476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 123576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_disable_clock_request(pdev); 123676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 123776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); 123876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 123976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 124076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_hw_start_8168cp_1(void *ioaddr, struct pci_device *pdev) 124176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 124276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman static struct ephy_info e_info_8168cp[] = { 124376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x01, 0, 0x0001 }, 124476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x02, 0x0800, 0x1000 }, 124576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x03, 0, 0x0042 }, 124676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0x0080, 0x0000 }, 124776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x07, 0, 0x2000 } 124876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }; 124976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 125076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_hw_start_8168cp_1\n" ); 125176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 125276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_csi_access_enable(ioaddr); 125376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 125476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_ephy_init(ioaddr, e_info_8168cp, ARRAY_SIZE(e_info_8168cp)); 125576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 125676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __rtl_hw_start_8168cp(ioaddr, pdev); 125776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 125876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 125976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_hw_start_8168cp_2(void *ioaddr, struct pci_device *pdev) 126076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 126176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_hw_start_8168cp_2\n" ); 126276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 126376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_csi_access_enable(ioaddr); 126476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 126576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); 126676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 126776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); 126876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 126976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); 127076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 127176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 127276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_hw_start_8168cp_3(void *ioaddr, struct pci_device *pdev) 127376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 127476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_hw_start_8168cp_3\n" ); 127576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 127676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_csi_access_enable(ioaddr); 127776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 127876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); 127976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 128076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Magic. */ 128176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(DBG_REG, 0x20); 128276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 128376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(EarlyTxThres, EarlyTxThld); 128476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 128576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); 128676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 128776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); 128876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 128976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 129076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_hw_start_8168c_1(void *ioaddr, struct pci_device *pdev) 129176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 129276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman static struct ephy_info e_info_8168c_1[] = { 129376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x02, 0x0800, 0x1000 }, 129476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x03, 0, 0x0002 }, 129576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0x0080, 0x0000 } 129676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }; 129776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 129876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_hw_start_8168c_1\n" ); 129976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 130076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_csi_access_enable(ioaddr); 130176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 130276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(DBG_REG, 0x06 | FIX_NAK_1 | FIX_NAK_2); 130376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 130476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_ephy_init(ioaddr, e_info_8168c_1, ARRAY_SIZE(e_info_8168c_1)); 130576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 130676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __rtl_hw_start_8168cp(ioaddr, pdev); 130776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 130876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 130976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_hw_start_8168c_2(void *ioaddr, struct pci_device *pdev) 131076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 131176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman static struct ephy_info e_info_8168c_2[] = { 131276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x01, 0, 0x0001 }, 131376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x03, 0x0400, 0x0220 } 131476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }; 131576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 131676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_hw_start_8168c_2\n" ); 131776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 131876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_csi_access_enable(ioaddr); 131976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 132076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_ephy_init(ioaddr, e_info_8168c_2, ARRAY_SIZE(e_info_8168c_2)); 132176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 132276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __rtl_hw_start_8168cp(ioaddr, pdev); 132376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 132476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 132576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_hw_start_8168c_3(void *ioaddr, struct pci_device *pdev) 132676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 132776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_hw_start_8168c_3\n" ); 132876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 132976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_hw_start_8168c_2(ioaddr, pdev); 133076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 133176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 133276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_hw_start_8168c_4(void *ioaddr, struct pci_device *pdev) 133376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 133476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_hw_start_8168c_4\n" ); 133576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 133676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_csi_access_enable(ioaddr); 133776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 133876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __rtl_hw_start_8168cp(ioaddr, pdev); 133976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 134076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 134176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_hw_start_8168d(void *ioaddr, struct pci_device *pdev) 134276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 134376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_hw_start_8168d\n" ); 134476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 134576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_csi_access_enable(ioaddr); 134676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 134776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_disable_clock_request(pdev); 134876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 134976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(EarlyTxThres, EarlyTxThld); 135076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 135176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); 135276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 135376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); 135476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 135576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 135676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_hw_start_8168(struct net_device *dev) 135776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 135876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp = netdev_priv(dev); 135976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ioaddr = tp->mmio_addr; 136076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct pci_device *pdev = tp->pci_dev; 136176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 136276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_hw_start_8168\n" ); 136376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 136476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(Cfg9346, Cfg9346_Unlock); 136576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 136676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(EarlyTxThres, EarlyTxThld); 136776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 136876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_set_rx_max_size(ioaddr); 136976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 137076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->cp_cmd |= RTL_R16(CPlusCmd) | PktCntrDisable | INTT_1; 137176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 137276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16(CPlusCmd, tp->cp_cmd); 137376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 137476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16(IntrMitigate, 0x5151); 137576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 137676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Work around for RxFIFO overflow. */ 137776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (tp->mac_version == RTL_GIGA_MAC_VER_11) { 137876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->intr_event |= RxFIFOOver | PCSTimeout; 137976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->intr_event &= ~RxOverflow; 138076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 138176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 138276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_set_rx_tx_desc_registers(tp, ioaddr); 138376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 138476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_set_rx_mode(dev); 138576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 138676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) | 138776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (InterFrameGap << TxInterFrameGapShift)); 138876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 138976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_R8(IntrMask); 139076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 139176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman switch (tp->mac_version) { 139276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_11: 139376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_hw_start_8168bb(ioaddr, pdev); 139476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 139576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 139676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_12: 139776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_17: 139876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_hw_start_8168bef(ioaddr, pdev); 139976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 140076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 140176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_18: 140276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_hw_start_8168cp_1(ioaddr, pdev); 140376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 140476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 140576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_19: 140676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_hw_start_8168c_1(ioaddr, pdev); 140776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 140876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 140976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_20: 141076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_hw_start_8168c_2(ioaddr, pdev); 141176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 141276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 141376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_21: 141476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_hw_start_8168c_3(ioaddr, pdev); 141576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 141676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 141776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_22: 141876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_hw_start_8168c_4(ioaddr, pdev); 141976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 142076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 142176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_23: 142276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_hw_start_8168cp_2(ioaddr, pdev); 142376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 142476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 142576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_24: 142676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_hw_start_8168cp_3(ioaddr, pdev); 142776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 142876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 142976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_25: 143076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_hw_start_8168d(ioaddr, pdev); 143176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 143276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 143376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman default: 143476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "Unknown chipset (mac_version = %d).\n", 143576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->mac_version ); 143676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 143776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 143876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 143976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); 144076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 144176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(Cfg9346, Cfg9346_Lock); 144276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 144376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); 144476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 144576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman // RTL_W16(IntrMask, tp->intr_event); 144676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 144776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 144876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define R810X_CPCMD_QUIRK_MASK (\ 144976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman EnableBist | \ 145076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Mac_dbgo_oe | \ 145176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Force_half_dup | \ 145276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Force_half_dup | \ 145376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Force_txflow_en | \ 145476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Cxpl_dbg_sel | \ 145576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ASF | \ 145676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PktCntrDisable | \ 145776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PCIDAC | \ 145876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PCIMulRW) 145976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 146076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_hw_start_8102e_1(void *ioaddr, struct pci_device *pdev) 146176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 146276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman static struct ephy_info e_info_8102e_1[] = { 146376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x01, 0, 0x6e65 }, 146476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x02, 0, 0x091f }, 146576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x03, 0, 0xc2f9 }, 146676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x06, 0, 0xafb5 }, 146776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x07, 0, 0x0e00 }, 146876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x19, 0, 0xec80 }, 146976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x01, 0, 0x2e65 }, 147076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 0x01, 0, 0x6e65 } 147176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }; 147276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u8 cfg1; 147376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 147476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_hw_start_8102e_1\n" ); 147576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 147676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_csi_access_enable(ioaddr); 147776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 147876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(DBG_REG, FIX_NAK_1); 147976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 148076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); 148176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 148276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(Config1, 148376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman LEDS1 | LEDS0 | Speed_down | MEMMAP | IOMAP | VPD | PMEnable); 148476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); 148576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 148676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cfg1 = RTL_R8(Config1); 148776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((cfg1 & LEDS0) && (cfg1 & LEDS1)) 148876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(Config1, cfg1 & ~LEDS0); 148976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 149076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK); 149176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 149276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_ephy_init(ioaddr, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1)); 149376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 149476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 149576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_hw_start_8102e_2(void *ioaddr, struct pci_device *pdev) 149676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 149776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_hw_start_8102e_2\n" ); 149876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 149976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_csi_access_enable(ioaddr); 150076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 150176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); 150276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 150376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(Config1, MEMMAP | IOMAP | VPD | PMEnable); 150476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); 150576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 150676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK); 150776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 150876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 150976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_hw_start_8102e_3(void *ioaddr, struct pci_device *pdev) 151076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 151176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_hw_start_8102e_3\n" ); 151276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 151376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_hw_start_8102e_2(ioaddr, pdev); 151476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 151576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_ephy_write(ioaddr, 0x03, 0xc2f9); 151676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 151776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 151876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl_hw_start_8101(struct net_device *dev) 151976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 152076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp = netdev_priv(dev); 152176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ioaddr = tp->mmio_addr; 152276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct pci_device *pdev = tp->pci_dev; 152376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 152476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl_hw_start_8101\n" ); 152576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 152676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((tp->mac_version == RTL_GIGA_MAC_VER_13) || 152776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (tp->mac_version == RTL_GIGA_MAC_VER_16)) { 152876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int cap = tp->pcie_cap; 152976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 153076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (cap) { 153176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, 153276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PCI_EXP_DEVCTL_NOSNOOP_EN); 153376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 153476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 153576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 153676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman switch (tp->mac_version) { 153776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_07: 153876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_hw_start_8102e_1(ioaddr, pdev); 153976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 154076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 154176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_08: 154276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_hw_start_8102e_3(ioaddr, pdev); 154376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 154476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 154576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case RTL_GIGA_MAC_VER_09: 154676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_hw_start_8102e_2(ioaddr, pdev); 154776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 154876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 154976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 155076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(Cfg9346, Cfg9346_Unlock); 155176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 155276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(EarlyTxThres, EarlyTxThld); 155376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 155476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_set_rx_max_size(ioaddr); 155576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 155676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW; 155776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 155876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16(CPlusCmd, tp->cp_cmd); 155976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 156076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16(IntrMitigate, 0x0000); 156176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 156276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_set_rx_tx_desc_registers(tp, ioaddr); 156376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 156476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); 156576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_set_rx_tx_config_registers(tp); 156676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 156776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(Cfg9346, Cfg9346_Lock); 156876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 156976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_R8(IntrMask); 157076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 157176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_set_rx_mode(dev); 157276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 157376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); 157476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 157576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000); 157676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 157776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman // RTL_W16(IntrMask, tp->intr_event); 157876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 157976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 158076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*** gPXE API Support Routines ***/ 158176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 158276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 158376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * setup_tx_resources - allocate tx resources (descriptors) 158476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 158576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v tp Driver private storage 158676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 158776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc Returns 0 on success, negative on failure 158876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman **/ 158976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int 159076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanrtl8169_setup_tx_resources ( struct rtl8169_private *tp ) 159176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 159276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_setup_tx_resources\n" ); 159376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 159476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->tx_base = malloc_dma ( R8169_TX_RING_BYTES, TX_RING_ALIGN ); 159576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 159676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ! tp->tx_base ) { 159776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return -ENOMEM; 159876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 159976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 160076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memset ( tp->tx_base, 0, R8169_TX_RING_BYTES ); 160176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 160276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "tp->tx_base = %#08lx\n", virt_to_bus ( tp->tx_base ) ); 160376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 160476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->tx_fill_ctr = 0; 160576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->tx_curr = 0; 160676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->tx_tail = 0; 160776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 160876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 160976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 161076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 161176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 161276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanrtl8169_process_tx_packets ( struct net_device *netdev ) 161376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 161476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp = netdev_priv ( netdev ); 161576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 161676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint32_t tx_status; 161776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct TxDesc *tx_curr_desc; 161876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 161976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_process_tx_packets\n" ); 162076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 162176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman while ( tp->tx_tail != tp->tx_curr ) { 162276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 162376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tx_curr_desc = tp->tx_base + tp->tx_tail; 162476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 162576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tx_status = tx_curr_desc->opts1; 162676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 162776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG2 ( "Before DescOwn check tx_status: %#08x\n", tx_status ); 162876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 162976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* if the packet at tx_tail is not owned by hardware it is for us */ 163076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( tx_status & DescOwn ) 163176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 163276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 163376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "Transmitted packet.\n" ); 163476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "tp->tx_fill_ctr = %d\n", tp->tx_fill_ctr ); 163576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "tp->tx_tail = %d\n", tp->tx_tail ); 163676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "tp->tx_curr = %d\n", tp->tx_curr ); 163776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "tx_status = %d\n", tx_status ); 163876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "tx_curr_desc = %#08lx\n", virt_to_bus ( tx_curr_desc ) ); 163976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 164076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Pass packet to core for processing */ 164176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman netdev_tx_complete ( netdev, tp->tx_iobuf[tp->tx_tail] ); 164276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 164376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memset ( tx_curr_desc, 0, sizeof ( *tx_curr_desc ) ); 164476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 164576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Decrement count of used descriptors */ 164676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->tx_fill_ctr--; 164776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 164876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Increment sent packets index */ 164976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->tx_tail = ( tp->tx_tail + 1 ) % NUM_TX_DESC; 165076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 165176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 165276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 165376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 165476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanrtl8169_free_tx_resources ( struct rtl8169_private *tp ) 165576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 165676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_free_tx_resources\n" ); 165776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 165876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman free_dma ( tp->tx_base, R8169_TX_RING_BYTES ); 165976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 166076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 166176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 166276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanrtl8169_populate_rx_descriptor ( struct rtl8169_private *tp, struct RxDesc *rx_desc, uint32_t index ) 166376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 166476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_populate_rx_descriptor\n" ); 166576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 166676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "Populating rx descriptor %d\n", index ); 166776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 166876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memset ( rx_desc, 0, sizeof ( *rx_desc ) ); 166976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 167076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rx_desc->addr_hi = 0; 167176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rx_desc->addr_lo = virt_to_bus ( tp->rx_iobuf[index]->data ); 167276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rx_desc->opts2 = 0; 167376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rx_desc->opts1 = ( index == ( NUM_RX_DESC - 1 ) ? RingEnd : 0 ) | 167476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RX_BUF_SIZE; 167576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rx_desc->opts1 |= DescOwn; 167676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 167776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 167876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 167976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Refill descriptor ring 168076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 168176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v netdev Net device 168276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 168376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8169_refill_rx_ring ( struct rtl8169_private *tp ) 168476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 168576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct RxDesc *rx_curr_desc; 168676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int i; 168776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 168876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_refill_rx_ring\n" ); 168976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 169076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for ( i = 0; i < NUM_RX_DESC; i++ ) { 169176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 169276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rx_curr_desc = ( tp->rx_base ) + i; 169376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 169476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Don't touch descriptors owned by the NIC */ 169576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( rx_curr_desc->opts1 & DescOwn ) 169676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman continue; 169776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 169876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Don't touch descriptors with iobufs, they still need to be 169976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman processed by the poll routine */ 170076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( tp->rx_iobuf[tp->rx_curr] != NULL ) 170176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman continue; 170276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 170376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /** If we can't get an iobuf for this descriptor 170476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman try again later (next poll). 170576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 170676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ! ( tp->rx_iobuf[i] = alloc_iob ( RX_BUF_SIZE ) ) ) { 170776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "Refill rx ring failed!!\n" ); 170876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 170976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 171076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 171176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_populate_rx_descriptor ( tp, rx_curr_desc, i ); 171276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 171376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 171476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 171576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 171676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * setup_rx_resources - allocate Rx resources (Descriptors) 171776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 171876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v tp: Driver private structure 171976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 172076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc Returns 0 on success, negative on failure 172176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 172276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman **/ 172376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int 172476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanrtl8169_setup_rx_resources ( struct rtl8169_private *tp ) 172576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 172676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_setup_rx_resources\n" ); 172776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 172876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->rx_base = malloc_dma ( R8169_RX_RING_BYTES, RX_RING_ALIGN ); 172976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 173076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "tp->rx_base = %#08lx\n", virt_to_bus ( tp->rx_base ) ); 173176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 173276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ! tp->rx_base ) { 173376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return -ENOMEM; 173476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 173576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memset ( tp->rx_base, 0, R8169_RX_RING_BYTES ); 173676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 173776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_refill_rx_ring ( tp ); 173876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 173976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->rx_curr = 0; 174076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 174176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 174276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 174376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 174476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 174576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanrtl8169_process_rx_packets ( struct net_device *netdev ) 174676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 174776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp = netdev_priv ( netdev ); 174876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint32_t rx_status; 174976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint16_t rx_len; 175076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct RxDesc *rx_curr_desc; 175176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int i; 175276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 175376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_process_rx_packets\n" ); 175476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 175576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for ( i = 0; i < NUM_RX_DESC; i++ ) { 175676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 175776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rx_curr_desc = tp->rx_base + tp->rx_curr; 175876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 175976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rx_status = rx_curr_desc->opts1; 176076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 176176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG2 ( "Before DescOwn check rx_status: %#08x\n", rx_status ); 176276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 176376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Hardware still owns the descriptor */ 176476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( rx_status & DescOwn ) 176576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 176676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 176776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* We own the descriptor, but it has not been refilled yet */ 176876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( tp->rx_iobuf[tp->rx_curr] == NULL ) 176976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 177076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 177176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rx_len = rx_status & 0x3fff; 177276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 177376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "Received packet.\n" ); 177476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "tp->rx_curr = %d\n", tp->rx_curr ); 177576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "rx_len = %d\n", rx_len ); 177676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "rx_status = %#08x\n", rx_status ); 177776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "rx_curr_desc = %#08lx\n", virt_to_bus ( rx_curr_desc ) ); 177876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 177976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( rx_status & RxRES ) { 178076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 178176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman netdev_rx_err ( netdev, tp->rx_iobuf[tp->rx_curr], -EINVAL ); 178276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 178376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "rtl8169_poll: Corrupted packet received!\n" 178476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman " rx_status: %#08x\n", rx_status ); 178576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 178676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 178776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 178876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Adjust size of the iobuf to reflect received data */ 178976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman iob_put ( tp->rx_iobuf[tp->rx_curr], rx_len ); 179076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 179176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Add this packet to the receive queue. */ 179276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman netdev_rx ( netdev, tp->rx_iobuf[tp->rx_curr] ); 179376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 179476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 179576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Invalidate this iobuf and descriptor */ 179676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->rx_iobuf[tp->rx_curr] = NULL; 179776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memset ( rx_curr_desc, 0, sizeof ( *rx_curr_desc ) ); 179876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 179976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Update pointer to next available rx descriptor */ 180076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->rx_curr = ( tp->rx_curr + 1 ) % NUM_RX_DESC; 180176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 180276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_refill_rx_ring ( tp ); 180376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 180476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 180576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 180676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanrtl8169_free_rx_resources ( struct rtl8169_private *tp ) 180776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 180876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int i; 180976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 181076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_free_rx_resources\n" ); 181176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 181276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman free_dma ( tp->rx_base, R8169_RX_RING_BYTES ); 181376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 181476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for ( i = 0; i < NUM_RX_DESC; i++ ) { 181576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman free_iob ( tp->rx_iobuf[i] ); 181676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->rx_iobuf[i] = NULL; 181776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 181876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 181976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 182076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 182176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman FIXME: Because gPXE's pci_device_id structure does not contain a 182276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman field to contain arbitrary data, we need the following table to 182376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman associate PCI IDs with nic variants, because a lot of driver 182476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman routines depend on knowing which kind of variant they are dealing 182576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman with. --mdc 182676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman **/ 182776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 182876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define _R(VENDOR,DEVICE,INDEX) \ 182976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { .vendor = VENDOR, .device = DEVICE, .index = INDEX } 183076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 183176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic const struct { 183276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint16_t vendor; 183376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint16_t device; 183476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int index; 183576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} nic_variant_table[] = { 183676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman _R(0x10ec, 0x8129, RTL_CFG_0), 183776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman _R(0x10ec, 0x8136, RTL_CFG_2), 183876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman _R(0x10ec, 0x8167, RTL_CFG_0), 183976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman _R(0x10ec, 0x8168, RTL_CFG_1), 184076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman _R(0x10ec, 0x8169, RTL_CFG_0), 184176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman _R(0x1186, 0x4300, RTL_CFG_0), 184276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman _R(0x1259, 0xc107, RTL_CFG_0), 184376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman _R(0x16ec, 0x0116, RTL_CFG_0), 184476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman _R(0x1737, 0x1032, RTL_CFG_0), 184576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman _R(0x0001, 0x8168, RTL_CFG_2), 184676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 184776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#undef _R 184876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 184976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int 185076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanrtl8169_get_nic_variant ( uint16_t vendor, uint16_t device ) 185176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 185276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 i; 185376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 185476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_get_nic_variant\n" ); 185576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 185676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = 0; i < ARRAY_SIZE(nic_variant_table); i++) { 185776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ( nic_variant_table[i].vendor == vendor ) && 185876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ( nic_variant_table[i].device == device ) ) { 185976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ( nic_variant_table[i].index ); 186076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 186176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 186276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "No matching NIC variant found!\n" ); 186376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ( RTL_CFG_0 ); 186476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 186576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 186676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8169_irq_enable ( struct rtl8169_private *tp ) 186776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 186876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ioaddr = tp->mmio_addr; 186976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 187076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_irq_enable\n" ); 187176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 187276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16 ( IntrMask, tp->intr_event ); 187376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 187476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 187576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void rtl8169_irq_disable ( struct rtl8169_private *tp ) 187676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 187776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ioaddr = tp->mmio_addr; 187876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 187976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_irq_disable\n" ); 188076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 188176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_irq_mask_and_ack ( ioaddr ); 188276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 188376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 188476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*** gPXE Core API Routines ***/ 188576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 188676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 188776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * open - Called when a network interface is made active 188876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 188976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v netdev network interface device structure 189076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc Return status code, 0 on success, negative value on failure 189176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 189276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman **/ 189376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int 189476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanrtl8169_open ( struct net_device *netdev ) 189576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 189676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp = netdev_priv ( netdev ); 189776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ioaddr = tp->mmio_addr; 189876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int rc; 189976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 190076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_open\n" ); 190176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 190276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* allocate transmit descriptors */ 190376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rc = rtl8169_setup_tx_resources ( tp ); 190476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( rc ) { 190576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "Error setting up TX resources!\n" ); 190676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto err_setup_tx; 190776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 190876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 190976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* allocate receive descriptors */ 191076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rc = rtl8169_setup_rx_resources ( tp ); 191176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( rc ) { 191276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "Error setting up RX resources!\n" ); 191376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto err_setup_rx; 191476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 191576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 191676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_hw_start ( netdev ); 191776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 191876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "TxDescStartAddrHigh = %#08lx\n", RTL_R32 ( TxDescStartAddrHigh ) ); 191976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "TxDescStartAddrLow = %#08lx\n", RTL_R32 ( TxDescStartAddrLow ) ); 192076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "RxDescAddrHigh = %#08lx\n", RTL_R32 ( RxDescAddrHigh ) ); 192176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "RxDescAddrLow = %#08lx\n", RTL_R32 ( RxDescAddrLow ) ); 192276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 192376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 192476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 192576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanerr_setup_rx: 192676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_free_tx_resources ( tp ); 192776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanerr_setup_tx: 192876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_hw_reset ( ioaddr ); 192976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 193076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return rc; 193176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 193276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 193376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 193476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * transmit - Transmit a packet 193576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 193676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v netdev Network device 193776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v iobuf I/O buffer 193876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 193976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc Returns 0 on success, negative on failure 194076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 194176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int 194276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanrtl8169_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) 194376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 194476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp = netdev_priv ( netdev ); 194576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ioaddr = tp->mmio_addr; 194676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint32_t tx_len = iob_len ( iobuf ); 194776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 194876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct TxDesc *tx_curr_desc; 194976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 195076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ("rtl8169_transmit\n"); 195176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 195276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( tp->tx_fill_ctr == NUM_TX_DESC ) { 195376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ("TX overflow\n"); 195476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return -ENOBUFS; 195576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 195676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 195776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /** 195876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * The rtl8169 family automatically pads short packets to a 195976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * minimum size, but if it did not, like some older cards, 196076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * we could do: 196176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * iob_pad ( iobuf, ETH_ZLEN ); 196276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 196376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 196476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Save pointer to this iobuf we have been given to transmit so 196576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman we can pass it to netdev_tx_complete() later */ 196676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->tx_iobuf[tp->tx_curr] = iobuf; 196776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 196876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tx_curr_desc = tp->tx_base + tp->tx_curr; 196976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 197076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "tp->tx_fill_ctr = %d\n", tp->tx_fill_ctr ); 197176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "tp->tx_curr = %d\n", tp->tx_curr ); 197276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "tx_curr_desc = %#08lx\n", virt_to_bus ( tx_curr_desc ) ); 197376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "iobuf->data = %#08lx\n", virt_to_bus ( iobuf->data ) ); 197476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "tx_len = %d\n", tx_len ); 197576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 197676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Configure current descriptor to transmit supplied packet */ 197776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tx_curr_desc->addr_hi = 0; 197876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tx_curr_desc->addr_lo = virt_to_bus ( iobuf->data ); 197976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tx_curr_desc->opts2 = 0; 198076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tx_curr_desc->opts1 = FirstFrag | LastFrag | 198176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ( tp->tx_curr == ( NUM_TX_DESC - 1 ) ? RingEnd : 0 ) | 198276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tx_len; 198376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 198476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Mark descriptor as owned by NIC */ 198576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tx_curr_desc->opts1 |= DescOwn; 198676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 198776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "tx_curr_desc->opts1 = %#08x\n", tx_curr_desc->opts1 ); 198876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "tx_curr_desc->opts2 = %#08x\n", tx_curr_desc->opts2 ); 198976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "tx_curr_desc->addr_hi = %#08x\n", tx_curr_desc->addr_hi ); 199076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "tx_curr_desc->addr_lo = %#08x\n", tx_curr_desc->addr_lo ); 199176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 199276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W8 ( TxPoll, NPQ ); /* set polling bit */ 199376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 199476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Point to next free descriptor */ 199576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->tx_curr = ( tp->tx_curr + 1 ) % NUM_TX_DESC; 199676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 199776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Increment number of tx descriptors in use */ 199876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->tx_fill_ctr++; 199976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 200076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 200176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 200276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 200376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 200476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * poll - Poll for received packets 200576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 200676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v netdev Network device 200776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 200876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 200976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanrtl8169_poll ( struct net_device *netdev ) 201076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 201176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp = netdev_priv ( netdev ); 201276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ioaddr = tp->mmio_addr; 201376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 201476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint16_t intr_status; 201576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint16_t intr_mask; 201676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 201776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_poll\n" ); 201876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 201976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman intr_status = RTL_R16 ( IntrStatus ); 202076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman intr_mask = RTL_R16 ( IntrMask ); 202176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 202276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG2 ( "rtl8169_poll (before): intr_mask = %#04x intr_status = %#04x\n", 202376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman intr_mask, intr_status ); 202476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 202576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RTL_W16 ( IntrStatus, 0xffff ); 202676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 202776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* hotplug / major error / no more work / shared irq */ 202876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( intr_status == 0xffff ) 202976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return; 203076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 203176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Process transmitted packets */ 203276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_process_tx_packets ( netdev ); 203376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 203476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Process received packets */ 203576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_process_rx_packets ( netdev ); 203676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 203776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 203876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 203976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * close - Disable network interface 204076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 204176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v netdev network interface device structure 204276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 204376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman **/ 204476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 204576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanrtl8169_close ( struct net_device *netdev ) 204676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 204776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp = netdev_priv ( netdev ); 204876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ioaddr = tp->mmio_addr; 204976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 205076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "r8169_close\n" ); 205176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 205276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_hw_reset ( ioaddr ); 205376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 205476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_free_tx_resources ( tp ); 205576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_free_rx_resources ( tp ); 205676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 205776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 205876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 205976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * irq - enable or Disable interrupts 206076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 206176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v netdev network adapter 206276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v action requested interrupt action 206376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 206476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman **/ 206576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 206676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanrtl8169_irq ( struct net_device *netdev, int action ) 206776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 206876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp = netdev_priv ( netdev ); 206976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 207076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_irq\n" ); 207176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 207276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman switch ( action ) { 207376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman case 0 : 207476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_irq_disable ( tp ); 207576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 207676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman default : 207776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_irq_enable ( tp ); 207876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 207976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 208076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 208176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 208276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct net_device_operations rtl8169_operations = { 208376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .open = rtl8169_open, 208476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .transmit = rtl8169_transmit, 208576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .poll = rtl8169_poll, 208676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .close = rtl8169_close, 208776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .irq = rtl8169_irq, 208876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 208976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 209076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 209176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * probe - Initial configuration of NIC 209276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 209376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v pci PCI device 209476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v id PCI IDs 209576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 209676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc Return status code 209776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman **/ 209876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int 209976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanrtl8169_probe ( struct pci_device *pdev, const struct pci_device_id *ent ) 210076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 210176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int i, rc; 210276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct net_device *netdev; 210376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp; 210476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ioaddr; 210576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 210676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /** FIXME: This lookup is necessary because gPXE does not have a "data" 210776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman element in the structure pci_device_id which can pass an arbitrary 210876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman piece of data to the driver. It might be useful to add it. Then we 210976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman could just use ent->data instead of having to look up cfg_index. 211076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman **/ 211176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int cfg_index = rtl8169_get_nic_variant ( ent->vendor, ent->device ); 211276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const struct rtl_cfg_info *cfg = rtl_cfg_infos + cfg_index; 211376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 211476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_probe\n" ); 211576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 211676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "ent->vendor = %#04x, ent->device = %#04x\n", ent->vendor, ent->device ); 211776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 211876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "cfg_index = %d\n", cfg_index ); 211976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "cfg->intr_event = %#04x\n", cfg->intr_event ); 212076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 212176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rc = -ENOMEM; 212276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 212376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Allocate net device ( also allocates memory for netdev->priv 212476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman and makes netdev-priv point to it ) 212576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 212676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman netdev = alloc_etherdev ( sizeof ( *tp ) ); 212776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 212876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ! netdev ) 212976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto err_alloc_etherdev; 213076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 213176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Associate driver-specific network operations with 213276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman generic network device layer 213376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 213476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman netdev_init ( netdev, &rtl8169_operations ); 213576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 213676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Associate this network device with the given PCI device */ 213776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman pci_set_drvdata ( pdev, netdev ); 213876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman netdev->dev = &pdev->dev; 213976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 214076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Initialize driver private storage */ 214176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp = netdev_priv ( netdev ); 214276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memset ( tp, 0, ( sizeof ( *tp ) ) ); 214376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 214476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->pci_dev = pdev; 214576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->irqno = pdev->irq; 214676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->netdev = netdev; 214776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->cfg_index = cfg_index; 214876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->intr_event = cfg->intr_event; 214976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->cp_cmd = PCIMulRW; 215076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 215176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->hw_start = cfg->hw_start; 215276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 215376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rc = -EIO; 215476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 215576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman adjust_pci_device ( pdev ); 215676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 215776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* ioremap MMIO region */ 215876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ioaddr = ioremap ( pdev->membase, R8169_REGS_SIZE ); 215976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 216076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ! ioaddr ) { 216176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "cannot remap MMIO\n" ); 216276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rc = -EIO; 216376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto err_ioremap; 216476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 216576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 216676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->mmio_addr = ioaddr; 216776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 216876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->pcie_cap = pci_find_capability ( pdev, PCI_CAP_ID_EXP ); 216976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( tp->pcie_cap ) { 217076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "PCI Express capability\n" ); 217176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 217276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "No PCI Express capability\n" ); 217376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 217476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 217576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Mask interrupts just in case */ 217676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_irq_mask_and_ack ( ioaddr ); 217776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 217876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Soft reset NIC */ 217976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl_soft_reset ( netdev ); 218076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 218176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Identify chip attached to board */ 218276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_get_mac_version ( tp, ioaddr ); 218376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 218476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for ( i = 0; (u32) i < ARRAY_SIZE ( rtl_chip_info ); i++ ) { 218576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( tp->mac_version == rtl_chip_info[i].mac_version ) 218676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 218776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 218876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( i == ARRAY_SIZE(rtl_chip_info ) ) { 218976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Unknown chip: assume array element #0, original RTL-8169 */ 219076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "Unknown chip version, assuming %s\n", rtl_chip_info[0].name ); 219176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman i = 0; 219276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 219376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->chipset = i; 219476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 219576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((tp->mac_version <= RTL_GIGA_MAC_VER_06) && 219676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (RTL_R8(PHYstatus) & TBI_Enable)) { 219776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->set_speed = rtl8169_set_speed_tbi; 219876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->phy_reset_enable = rtl8169_tbi_reset_enable; 219976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->phy_reset_pending = rtl8169_tbi_reset_pending; 220076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->link_ok = rtl8169_tbi_link_ok; 220176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 220276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->phy_1000_ctrl_reg = ADVERTISE_1000FULL; /* Implied by TBI */ 220376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 220476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->set_speed = rtl8169_set_speed_xmii; 220576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->phy_reset_enable = rtl8169_xmii_reset_enable; 220676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->phy_reset_pending = rtl8169_xmii_reset_pending; 220776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tp->link_ok = rtl8169_xmii_link_ok; 220876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 220976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 221076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Get MAC address */ 221176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for ( i = 0; i < MAC_ADDR_LEN; i++ ) 221276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman netdev->hw_addr[i] = RTL_R8 ( MAC0 + i ); 221376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 221476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "%s\n", eth_ntoa ( netdev->hw_addr ) ); 221576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 221676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_init_phy ( netdev, tp ); 221776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 221876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ( rc = register_netdev ( netdev ) ) != 0 ) 221976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto err_register; 222076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 222176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Mark as link up; we don't yet handle link state */ 222276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman netdev_link_up ( netdev ); 222376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 222476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "rtl8169_probe succeeded!\n" ); 222576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 222676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* No errors, return success */ 222776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 222876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 222976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Error return paths */ 223076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanerr_register: 223176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanerr_ioremap: 223276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman netdev_put ( netdev ); 223376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanerr_alloc_etherdev: 223476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return rc; 223576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 223676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 223776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 223876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * remove - Device Removal Routine 223976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 224076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v pdev PCI device information struct 224176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 224276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman **/ 224376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void 224476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanrtl8169_remove ( struct pci_device *pdev ) 224576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 224676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct net_device *netdev = pci_get_drvdata ( pdev ); 224776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct rtl8169_private *tp = netdev_priv ( netdev ); 224876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *ioaddr = tp->mmio_addr; 224976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 225076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBGP ( "rtl8169_remove\n" ); 225176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 225276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rtl8169_hw_reset ( ioaddr ); 225376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 225476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unregister_netdev ( netdev ); 225576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman netdev_nullify ( netdev ); 225676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman netdev_put ( netdev ); 225776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 225876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 225976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct pci_device_id rtl8169_nics[] = { 226076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PCI_ROM(0x10ec, 0x8129, "rtl8169-0x8129", "rtl8169-0x8129", 0), 226176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PCI_ROM(0x10ec, 0x8136, "rtl8169-0x8136", "rtl8169-0x8136", 0), 226276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PCI_ROM(0x10ec, 0x8167, "rtl8169-0x8167", "rtl8169-0x8167", 0), 226376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PCI_ROM(0x10ec, 0x8168, "rtl8169-0x8168", "rtl8169-0x8168", 0), 226476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PCI_ROM(0x10ec, 0x8169, "rtl8169-0x8169", "rtl8169-0x8169", 0), 226576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PCI_ROM(0x1186, 0x4300, "rtl8169-0x4300", "rtl8169-0x4300", 0), 226676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PCI_ROM(0x1259, 0xc107, "rtl8169-0xc107", "rtl8169-0xc107", 0), 226776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PCI_ROM(0x16ec, 0x0116, "rtl8169-0x0116", "rtl8169-0x0116", 0), 226876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PCI_ROM(0x1737, 0x1032, "rtl8169-0x1032", "rtl8169-0x1032", 0), 226976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PCI_ROM(0x0001, 0x8168, "rtl8169-0x8168", "rtl8169-0x8168", 0), 227076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 227176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 227276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct pci_driver rtl8169_driver __pci_driver = { 227376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .ids = rtl8169_nics, 227476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .id_count = ( sizeof ( rtl8169_nics ) / sizeof ( rtl8169_nics[0] ) ), 227576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .probe = rtl8169_probe, 227676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .remove = rtl8169_remove, 227776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 227876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 227976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 228076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Local variables: 228176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * c-basic-offset: 8 228276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * c-indent-level: 8 228376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * tab-width: 8 228476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * End: 228576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 2286