/* * Copyright (c) 2008 Marty Connor * Copyright (c) 2008 Entity Cyber, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * This driver is based on rtl8169 data sheets and work by: * * Copyright (c) 2002 ShuChen * Copyright (c) 2003 - 2007 Francois Romieu * Copyright (c) a lot of people too. Please respect their work. * */ FILE_LICENCE ( GPL2_OR_LATER ); #ifndef _R8169_H_ #define _R8169_H_ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) /** FIXME: include/linux/pci_regs.h has these PCI regs, maybe we need such a file in gPXE? **/ #define PCI_EXP_DEVCTL 8 /* Device Control */ #define PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */ #define PCI_EXP_LNKCTL 16 /* Link Control */ #define PCI_EXP_LNKCTL_CLKREQ_EN 0x100 /* Enable clkreq */ #define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */ /** FIXME: update mii.h in src/include/mii.h from Linux sources so we don't have to include these definitiions. **/ /* The forced speed, 10Mb, 100Mb, gigabit, 2.5Gb, 10GbE. */ #define SPEED_10 10 #define SPEED_100 100 #define SPEED_1000 1000 #define SPEED_2500 2500 #define SPEED_10000 10000 /* Duplex, half or full. */ #define DUPLEX_HALF 0x00 #define DUPLEX_FULL 0x01 #define AUTONEG_DISABLE 0x00 #define AUTONEG_ENABLE 0x01 /* MAC address length */ #define MAC_ADDR_LEN 6 #define MAX_READ_REQUEST_SHIFT 12 #define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */ #define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ #define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ #define EarlyTxThld 0x3F /* 0x3F means NO early transmit */ #define RxPacketMaxSize 0x3FE8 /* 16K - 1 - ETH_HLEN - VLAN - CRC... */ #define SafeMtu 0x1c20 /* ... actually life sucks beyond ~7k */ #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ #define R8169_REGS_SIZE 256 #define R8169_NAPI_WEIGHT 64 #define NUM_TX_DESC 8 /* Number of Tx descriptor registers */ #define NUM_RX_DESC 8 /* Number of Rx descriptor registers */ #define RX_BUF_SIZE 1536 /* Rx Buffer size */ #define R8169_TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc)) #define R8169_RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc)) #define TX_RING_ALIGN 256 #define RX_RING_ALIGN 256 #define RTL8169_TX_TIMEOUT (6*HZ) #define RTL8169_PHY_TIMEOUT (10*HZ) #define RTL_EEPROM_SIG cpu_to_le32(0x8129) #define RTL_EEPROM_SIG_MASK cpu_to_le32(0xffff) #define RTL_EEPROM_SIG_ADDR 0x0000 /* write/read MMIO register */ #define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) #define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg)) #define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg)) #define RTL_R8(reg) readb (ioaddr + (reg)) #define RTL_R16(reg) readw (ioaddr + (reg)) #define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) enum mac_version { RTL_GIGA_MAC_VER_01 = 0x01, // 8169 RTL_GIGA_MAC_VER_02 = 0x02, // 8169S RTL_GIGA_MAC_VER_03 = 0x03, // 8110S RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe RTL_GIGA_MAC_VER_07 = 0x07, // 8102e RTL_GIGA_MAC_VER_08 = 0x08, // 8102e RTL_GIGA_MAC_VER_09 = 0x09, // 8102e RTL_GIGA_MAC_VER_10 = 0x0a, // 8101e RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb RTL_GIGA_MAC_VER_14 = 0x0e, // 8101 ? RTL_GIGA_MAC_VER_15 = 0x0f, // 8101 ? RTL_GIGA_MAC_VER_16 = 0x11, // 8101Ec RTL_GIGA_MAC_VER_17 = 0x10, // 8168Bf RTL_GIGA_MAC_VER_18 = 0x12, // 8168CP RTL_GIGA_MAC_VER_19 = 0x13, // 8168C RTL_GIGA_MAC_VER_20 = 0x14, // 8168C RTL_GIGA_MAC_VER_21 = 0x15, // 8168C RTL_GIGA_MAC_VER_22 = 0x16, // 8168C RTL_GIGA_MAC_VER_23 = 0x17, // 8168CP RTL_GIGA_MAC_VER_24 = 0x18, // 8168CP RTL_GIGA_MAC_VER_25 = 0x19, // 8168D }; #define _R(NAME,MAC,MASK) \ { .name = NAME, .mac_version = MAC, .RxConfigMask = MASK } static const struct { const char *name; u8 mac_version; u32 RxConfigMask; /* Clears the bits supported by this chip */ } rtl_chip_info[] = { _R("RTL8169", RTL_GIGA_MAC_VER_01, 0xff7e1880), // 8169 _R("RTL8169s", RTL_GIGA_MAC_VER_02, 0xff7e1880), // 8169S _R("RTL8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880), // 8110S _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe _R("RTL8102e", RTL_GIGA_MAC_VER_07, 0xff7e1880), // PCI-E _R("RTL8102e", RTL_GIGA_MAC_VER_08, 0xff7e1880), // PCI-E _R("RTL8102e", RTL_GIGA_MAC_VER_09, 0xff7e1880), // PCI-E _R("RTL8101e", RTL_GIGA_MAC_VER_10, 0xff7e1880), // PCI-E _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139 _R("RTL8100e", RTL_GIGA_MAC_VER_14, 0xff7e1880), // PCI-E 8139 _R("RTL8100e", RTL_GIGA_MAC_VER_15, 0xff7e1880), // PCI-E 8139 _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_17, 0xff7e1880), // PCI-E _R("RTL8101e", RTL_GIGA_MAC_VER_16, 0xff7e1880), // PCI-E _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_18, 0xff7e1880), // PCI-E _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_19, 0xff7e1880), // PCI-E _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_20, 0xff7e1880), // PCI-E _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_21, 0xff7e1880), // PCI-E _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_22, 0xff7e1880), // PCI-E _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_23, 0xff7e1880), // PCI-E _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_24, 0xff7e1880), // PCI-E _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_25, 0xff7e1880) // PCI-E }; #undef _R enum cfg_version { RTL_CFG_0 = 0x00, RTL_CFG_1, RTL_CFG_2 }; #if 0 /** Device Table from Linux Driver **/ static struct pci_device_id rtl8169_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8129), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8136), 0, 0, RTL_CFG_2 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_1 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_AT, 0xc107), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 }, { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 }, { 0x0001, 0x8168, PCI_ANY_ID, 0x2410, 0, 0, RTL_CFG_2 }, {0,}, }; #endif enum rtl_registers { MAC0 = 0, /* Ethernet hardware address. */ MAC4 = 4, MAR0 = 8, /* Multicast filter. */ CounterAddrLow = 0x10, CounterAddrHigh = 0x14, TxDescStartAddrLow = 0x20, TxDescStartAddrHigh = 0x24, TxHDescStartAddrLow = 0x28, TxHDescStartAddrHigh = 0x2c, FLASH = 0x30, ERSR = 0x36, ChipCmd = 0x37, TxPoll = 0x38, IntrMask = 0x3c, IntrStatus = 0x3e, TxConfig = 0x40, RxConfig = 0x44, RxMissed = 0x4c, Cfg9346 = 0x50, Config0 = 0x51, Config1 = 0x52, Config2 = 0x53, Config3 = 0x54, Config4 = 0x55, Config5 = 0x56, MultiIntr = 0x5c, PHYAR = 0x60, PHYstatus = 0x6c, RxMaxSize = 0xda, CPlusCmd = 0xe0, IntrMitigate = 0xe2, RxDescAddrLow = 0xe4, RxDescAddrHigh = 0xe8, EarlyTxThres = 0xec, FuncEvent = 0xf0, FuncEventMask = 0xf4, FuncPresetState = 0xf8, FuncForceEvent = 0xfc, }; enum rtl8110_registers { TBICSR = 0x64, TBI_ANAR = 0x68, TBI_LPAR = 0x6a, }; enum rtl8168_8101_registers { CSIDR = 0x64, CSIAR = 0x68, #define CSIAR_FLAG 0x80000000 #define CSIAR_WRITE_CMD 0x80000000 #define CSIAR_BYTE_ENABLE 0x0f #define CSIAR_BYTE_ENABLE_SHIFT 12 #define CSIAR_ADDR_MASK 0x0fff EPHYAR = 0x80, #define EPHYAR_FLAG 0x80000000 #define EPHYAR_WRITE_CMD 0x80000000 #define EPHYAR_REG_MASK 0x1f #define EPHYAR_REG_SHIFT 16 #define EPHYAR_DATA_MASK 0xffff DBG_REG = 0xd1, #define FIX_NAK_1 (1 << 4) #define FIX_NAK_2 (1 << 3) }; enum rtl_register_content { /* InterruptStatusBits */ SYSErr = 0x8000, PCSTimeout = 0x4000, SWInt = 0x0100, TxDescUnavail = 0x0080, RxFIFOOver = 0x0040, LinkChg = 0x0020, RxOverflow = 0x0010, TxErr = 0x0008, TxOK = 0x0004, RxErr = 0x0002, RxOK = 0x0001, /* RxStatusDesc */ RxFOVF = (1 << 23), RxRWT = (1 << 22), RxRES = (1 << 21), RxRUNT = (1 << 20), RxCRC = (1 << 19), /* ChipCmdBits */ CmdReset = 0x10, CmdRxEnb = 0x08, CmdTxEnb = 0x04, RxBufEmpty = 0x01, /* TXPoll register p.5 */ HPQ = 0x80, /* Poll cmd on the high prio queue */ NPQ = 0x40, /* Poll cmd on the low prio queue */ FSWInt = 0x01, /* Forced software interrupt */ /* Cfg9346Bits */ Cfg9346_Lock = 0x00, Cfg9346_Unlock = 0xc0, /* rx_mode_bits */ AcceptErr = 0x20, AcceptRunt = 0x10, AcceptBroadcast = 0x08, AcceptMulticast = 0x04, AcceptMyPhys = 0x02, AcceptAllPhys = 0x01, /* RxConfigBits */ RxCfgFIFOShift = 13, RxCfgDMAShift = 8, /* TxConfigBits */ TxInterFrameGapShift = 24, TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ /* Config1 register p.24 */ LEDS1 = (1 << 7), LEDS0 = (1 << 6), MSIEnable = (1 << 5), /* Enable Message Signaled Interrupt */ Speed_down = (1 << 4), MEMMAP = (1 << 3), IOMAP = (1 << 2), VPD = (1 << 1), PMEnable = (1 << 0), /* Power Management Enable */ /* Config2 register p. 25 */ PCI_Clock_66MHz = 0x01, PCI_Clock_33MHz = 0x00, /* Config3 register p.25 */ MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */ LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */ Beacon_en = (1 << 0), /* 8168 only. Reserved in the 8168b */ /* Config5 register p.27 */ BWF = (1 << 6), /* Accept Broadcast wakeup frame */ MWF = (1 << 5), /* Accept Multicast wakeup frame */ UWF = (1 << 4), /* Accept Unicast wakeup frame */ LanWake = (1 << 1), /* LanWake enable/disable */ PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */ /* TBICSR p.28 */ TBIReset = 0x80000000, TBILoopback = 0x40000000, TBINwEnable = 0x20000000, TBINwRestart = 0x10000000, TBILinkOk = 0x02000000, TBINwComplete = 0x01000000, /* CPlusCmd p.31 */ EnableBist = (1 << 15), // 8168 8101 Mac_dbgo_oe = (1 << 14), // 8168 8101 Normal_mode = (1 << 13), // unused Force_half_dup = (1 << 12), // 8168 8101 Force_rxflow_en = (1 << 11), // 8168 8101 Force_txflow_en = (1 << 10), // 8168 8101 Cxpl_dbg_sel = (1 << 9), // 8168 8101 ASF = (1 << 8), // 8168 8101 PktCntrDisable = (1 << 7), // 8168 8101 Mac_dbgo_sel = 0x001c, // 8168 RxVlan = (1 << 6), RxChkSum = (1 << 5), PCIDAC = (1 << 4), PCIMulRW = (1 << 3), INTT_0 = 0x0000, // 8168 INTT_1 = 0x0001, // 8168 INTT_2 = 0x0002, // 8168 INTT_3 = 0x0003, // 8168 /* rtl8169_PHYstatus */ TBI_Enable = 0x80, TxFlowCtrl = 0x40, RxFlowCtrl = 0x20, _1000bpsF = 0x10, _100bps = 0x08, _10bps = 0x04, LinkStatus = 0x02, FullDup = 0x01, /* _TBICSRBit */ TBILinkOK = 0x02000000, /* DumpCounterCommand */ CounterDump = 0x8, }; enum desc_status_bit { DescOwn = (1 << 31), /* Descriptor is owned by NIC */ RingEnd = (1 << 30), /* End of descriptor ring */ FirstFrag = (1 << 29), /* First segment of a packet */ LastFrag = (1 << 28), /* Final segment of a packet */ /* Tx private */ LargeSend = (1 << 27), /* TCP Large Send Offload (TSO) */ MSSShift = 16, /* MSS value position */ MSSMask = 0xfff, /* MSS value + LargeSend bit: 12 bits */ IPCS = (1 << 18), /* Calculate IP checksum */ UDPCS = (1 << 17), /* Calculate UDP/IP checksum */ TCPCS = (1 << 16), /* Calculate TCP/IP checksum */ TxVlanTag = (1 << 17), /* Add VLAN tag */ /* Rx private */ PID1 = (1 << 18), /* Protocol ID bit 1/2 */ PID0 = (1 << 17), /* Protocol ID bit 2/2 */ #define RxProtoUDP (PID1) #define RxProtoTCP (PID0) #define RxProtoIP (PID1 | PID0) #define RxProtoMask RxProtoIP IPFail = (1 << 16), /* IP checksum failed */ UDPFail = (1 << 15), /* UDP/IP checksum failed */ TCPFail = (1 << 14), /* TCP/IP checksum failed */ RxVlanTag = (1 << 16), /* VLAN tag available */ }; #define RsvdMask 0x3fffc000 struct TxDesc { volatile uint32_t opts1; volatile uint32_t opts2; volatile uint32_t addr_lo; volatile uint32_t addr_hi; }; struct RxDesc { volatile uint32_t opts1; volatile uint32_t opts2; volatile uint32_t addr_lo; volatile uint32_t addr_hi; }; enum features { RTL_FEATURE_WOL = (1 << 0), RTL_FEATURE_MSI = (1 << 1), RTL_FEATURE_GMII = (1 << 2), }; static void rtl_hw_start_8169(struct net_device *); static void rtl_hw_start_8168(struct net_device *); static void rtl_hw_start_8101(struct net_device *); struct rtl8169_private { struct pci_device *pci_dev; struct net_device *netdev; uint8_t *hw_addr; void *mmio_addr; uint32_t irqno; int chipset; int mac_version; int cfg_index; u16 intr_event; struct io_buffer *tx_iobuf[NUM_TX_DESC]; struct io_buffer *rx_iobuf[NUM_RX_DESC]; struct TxDesc *tx_base; struct RxDesc *rx_base; uint32_t tx_curr; uint32_t rx_curr; uint32_t tx_tail; uint32_t tx_fill_ctr; u16 cp_cmd; int phy_auto_nego_reg; int phy_1000_ctrl_reg; int ( *set_speed ) (struct net_device *, u8 autoneg, u16 speed, u8 duplex ); void ( *phy_reset_enable ) ( void *ioaddr ); void ( *hw_start ) ( struct net_device * ); unsigned int ( *phy_reset_pending ) ( void *ioaddr ); unsigned int ( *link_ok ) ( void *ioaddr ); int pcie_cap; unsigned features; }; static const unsigned int rtl8169_rx_config = (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); #endif /* _R8169_H_ */ /* * Local variables: * c-basic-offset: 8 * c-indent-level: 8 * tab-width: 8 * End: */