Files
ipxe/src/drivers/net/r8169.h
T
Michael Brown 8406115834 [build] Rename gPXE to iPXE
Access to the gpxe.org and etherboot.org domains and associated
resources has been revoked by the registrant of the domain.  Work
around this problem by renaming project from gPXE to iPXE, and
updating URLs to match.

Also update README, LOG and COPYRIGHTS to remove obsolete information.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2010-04-19 23:43:39 +01:00

488 lines
14 KiB
C

/*
* Copyright (c) 2008 Marty Connor <mdc@etherboot.org>
* 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 <shuchen@realtek.com.tw>
* Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
* 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 iPXE?
**/
#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:
*/