Home | History | Annotate | Download | only in net
      1 #ifndef __SIS190_H__
      2 #define __SIS190_H__
      3 
      4 FILE_LICENCE ( GPL_ANY );
      5 
      6 #include <stdint.h>
      7 #include <stdio.h>
      8 #include <stdlib.h>
      9 #include <stddef.h>
     10 #include <string.h>
     11 #include <unistd.h>
     12 #include <assert.h>
     13 #include <byteswap.h>
     14 #include <errno.h>
     15 #include <mii.h>
     16 #include <gpxe/ethernet.h>
     17 #include <gpxe/if_ether.h>
     18 #include <gpxe/io.h>
     19 #include <gpxe/iobuf.h>
     20 #include <gpxe/malloc.h>
     21 #include <gpxe/netdevice.h>
     22 #include <gpxe/pci.h>
     23 #include <gpxe/timer.h>
     24 
     25 #define PCI_VENDOR_ID_SI	0x1039
     26 
     27 #define PHY_MAX_ADDR		32
     28 #define PHY_ID_ANY		0x1f
     29 #define MII_REG_ANY		0x1f
     30 
     31 #define DRV_VERSION		"1.3"
     32 #define DRV_NAME		"sis190"
     33 #define SIS190_DRIVER_NAME	DRV_NAME " Gigabit Ethernet driver " DRV_VERSION
     34 #define PFX DRV_NAME ": "
     35 
     36 #define sis190_rx_quota(count, quota)	count
     37 
     38 #define NUM_TX_DESC		8	/* [8..1024] */
     39 #define NUM_RX_DESC		8	/* [8..8192] */
     40 #define TX_RING_BYTES		(NUM_TX_DESC * sizeof(struct TxDesc))
     41 #define RX_RING_BYTES		(NUM_RX_DESC * sizeof(struct RxDesc))
     42 #define RX_BUF_SIZE		1536
     43 #define RX_BUF_MASK		0xfff8
     44 
     45 #define RING_ALIGNMENT		256
     46 
     47 #define SIS190_REGS_SIZE	0x80
     48 
     49 /* Enhanced PHY access register bit definitions */
     50 #define EhnMIIread		0x0000
     51 #define EhnMIIwrite		0x0020
     52 #define EhnMIIdataShift		16
     53 #define EhnMIIpmdShift		6	/* 7016 only */
     54 #define EhnMIIregShift		11
     55 #define EhnMIIreq		0x0010
     56 #define EhnMIInotDone		0x0010
     57 
     58 /* Write/read MMIO register */
     59 #define SIS_W8(reg, val)	writeb ((val), ioaddr + (reg))
     60 #define SIS_W16(reg, val)	writew ((val), ioaddr + (reg))
     61 #define SIS_W32(reg, val)	writel ((val), ioaddr + (reg))
     62 #define SIS_R8(reg)		readb (ioaddr + (reg))
     63 #define SIS_R16(reg)		readw (ioaddr + (reg))
     64 #define SIS_R32(reg)		readl (ioaddr + (reg))
     65 
     66 #define SIS_PCI_COMMIT()	SIS_R32(IntrControl)
     67 
     68 enum sis190_registers {
     69 	TxControl		= 0x00,
     70 	TxDescStartAddr		= 0x04,
     71 	rsv0			= 0x08,	// reserved
     72 	TxSts			= 0x0c,	// unused (Control/Status)
     73 	RxControl		= 0x10,
     74 	RxDescStartAddr		= 0x14,
     75 	rsv1			= 0x18,	// reserved
     76 	RxSts			= 0x1c,	// unused
     77 	IntrStatus		= 0x20,
     78 	IntrMask		= 0x24,
     79 	IntrControl		= 0x28,
     80 	IntrTimer		= 0x2c,	// unused (Interupt Timer)
     81 	PMControl		= 0x30,	// unused (Power Mgmt Control/Status)
     82 	rsv2			= 0x34,	// reserved
     83 	ROMControl		= 0x38,
     84 	ROMInterface		= 0x3c,
     85 	StationControl		= 0x40,
     86 	GMIIControl		= 0x44,
     87 	GIoCR			= 0x48, // unused (GMAC IO Compensation)
     88 	GIoCtrl			= 0x4c, // unused (GMAC IO Control)
     89 	TxMacControl		= 0x50,
     90 	TxLimit			= 0x54, // unused (Tx MAC Timer/TryLimit)
     91 	RGDelay			= 0x58, // unused (RGMII Tx Internal Delay)
     92 	rsv3			= 0x5c, // reserved
     93 	RxMacControl		= 0x60,
     94 	RxMacAddr		= 0x62,
     95 	RxHashTable		= 0x68,
     96 	// Undocumented		= 0x6c,
     97 	RxWolCtrl		= 0x70,
     98 	RxWolData		= 0x74, // unused (Rx WOL Data Access)
     99 	RxMPSControl		= 0x78,	// unused (Rx MPS Control)
    100 	rsv4			= 0x7c, // reserved
    101 };
    102 
    103 enum sis190_register_content {
    104 	/* IntrStatus */
    105 	SoftInt			= 0x40000000,	// unused
    106 	Timeup			= 0x20000000,	// unused
    107 	PauseFrame		= 0x00080000,	// unused
    108 	MagicPacket		= 0x00040000,	// unused
    109 	WakeupFrame		= 0x00020000,	// unused
    110 	LinkChange		= 0x00010000,
    111 	RxQEmpty		= 0x00000080,
    112 	RxQInt			= 0x00000040,
    113 	TxQ1Empty		= 0x00000020,	// unused
    114 	TxQ1Int			= 0x00000010,
    115 	TxQ0Empty		= 0x00000008,	// unused
    116 	TxQ0Int			= 0x00000004,
    117 	RxHalt			= 0x00000002,
    118 	TxHalt			= 0x00000001,
    119 
    120 	/* {Rx/Tx}CmdBits */
    121 	CmdReset		= 0x10,
    122 	CmdRxEnb		= 0x08,		// unused
    123 	CmdTxEnb		= 0x01,
    124 	RxBufEmpty		= 0x01,		// unused
    125 
    126 	/* Cfg9346Bits */
    127 	Cfg9346_Lock		= 0x00,		// unused
    128 	Cfg9346_Unlock		= 0xc0,		// unused
    129 
    130 	/* RxMacControl */
    131 	AcceptErr		= 0x20,		// unused
    132 	AcceptRunt		= 0x10,		// unused
    133 	AcceptBroadcast		= 0x0800,
    134 	AcceptMulticast		= 0x0400,
    135 	AcceptMyPhys		= 0x0200,
    136 	AcceptAllPhys		= 0x0100,
    137 
    138 	/* RxConfigBits */
    139 	RxCfgFIFOShift		= 13,
    140 	RxCfgDMAShift		= 8,		// 0x1a in RxControl ?
    141 
    142 	/* TxConfigBits */
    143 	TxInterFrameGapShift	= 24,
    144 	TxDMAShift		= 8, /* DMA burst value (0-7) is shift this many bits */
    145 
    146 	LinkStatus		= 0x02,		// unused
    147 	FullDup			= 0x01,		// unused
    148 
    149 	/* TBICSRBit */
    150 	TBILinkOK		= 0x02000000,	// unused
    151 };
    152 
    153 struct TxDesc {
    154 	volatile u32 PSize;
    155 	volatile u32 status;
    156 	volatile u32 addr;
    157 	volatile u32 size;
    158 };
    159 
    160 struct RxDesc {
    161 	volatile u32 PSize;
    162 	volatile u32 status;
    163 	volatile u32 addr;
    164 	volatile u32 size;
    165 };
    166 
    167 enum _DescStatusBit {
    168 	/* _Desc.status */
    169 	OWNbit		= 0x80000000, // RXOWN/TXOWN
    170 	INTbit		= 0x40000000, // RXINT/TXINT
    171 	CRCbit		= 0x00020000, // CRCOFF/CRCEN
    172 	PADbit		= 0x00010000, // PREADD/PADEN
    173 	/* _Desc.size */
    174 	RingEnd		= 0x80000000,
    175 	/* TxDesc.status */
    176 	LSEN		= 0x08000000, // TSO ? -- FR
    177 	IPCS		= 0x04000000,
    178 	TCPCS		= 0x02000000,
    179 	UDPCS		= 0x01000000,
    180 	BSTEN		= 0x00800000,
    181 	EXTEN		= 0x00400000,
    182 	DEFEN		= 0x00200000,
    183 	BKFEN		= 0x00100000,
    184 	CRSEN		= 0x00080000,
    185 	COLEN		= 0x00040000,
    186 	THOL3		= 0x30000000,
    187 	THOL2		= 0x20000000,
    188 	THOL1		= 0x10000000,
    189 	THOL0		= 0x00000000,
    190 
    191 	WND		= 0x00080000,
    192 	TABRT		= 0x00040000,
    193 	FIFO		= 0x00020000,
    194 	LINK		= 0x00010000,
    195 	ColCountMask	= 0x0000ffff,
    196 	/* RxDesc.status */
    197 	IPON		= 0x20000000,
    198 	TCPON		= 0x10000000,
    199 	UDPON		= 0x08000000,
    200 	Wakup		= 0x00400000,
    201 	Magic		= 0x00200000,
    202 	Pause		= 0x00100000,
    203 	DEFbit		= 0x00200000,
    204 	BCAST		= 0x000c0000,
    205 	MCAST		= 0x00080000,
    206 	UCAST		= 0x00040000,
    207 	/* RxDesc.PSize */
    208 	TAGON		= 0x80000000,
    209 	RxDescCountMask	= 0x7f000000, // multi-desc pkt when > 1 ? -- FR
    210 	ABORT		= 0x00800000,
    211 	SHORT		= 0x00400000,
    212 	LIMIT		= 0x00200000,
    213 	MIIER		= 0x00100000,
    214 	OVRUN		= 0x00080000,
    215 	NIBON		= 0x00040000,
    216 	COLON		= 0x00020000,
    217 	CRCOK		= 0x00010000,
    218 	RxSizeMask	= 0x0000ffff
    219 	/*
    220 	* The asic could apparently do vlan, TSO, jumbo (sis191 only) and
    221 	* provide two (unused with Linux) Tx queues. No publically
    222 	* available documentation alas.
    223 	*/
    224 };
    225 
    226 enum sis190_eeprom_access_register_bits {
    227 	EECS	= 0x00000001,	// unused
    228 	EECLK	= 0x00000002,	// unused
    229 	EEDO	= 0x00000008,	// unused
    230 	EEDI	= 0x00000004,	// unused
    231 	EEREQ	= 0x00000080,
    232 	EEROP	= 0x00000200,
    233 	EEWOP	= 0x00000100	// unused
    234 };
    235 
    236 /* EEPROM Addresses */
    237 enum sis190_eeprom_address {
    238 	EEPROMSignature	= 0x00,
    239 	EEPROMCLK	= 0x01,	// unused
    240 	EEPROMInfo	= 0x02,
    241 	EEPROMMACAddr	= 0x03
    242 };
    243 
    244 enum sis190_feature {
    245 	F_HAS_RGMII	= 1,
    246 	F_PHY_88E1111	= 2,
    247 	F_PHY_BCM5461	= 4
    248 };
    249 
    250 struct sis190_private {
    251 	void *mmio_addr;
    252 	struct pci_device *pci_device;
    253 	struct net_device *dev;
    254 	u32 cur_rx;
    255 	u32 cur_tx;
    256 	u32 dirty_rx;
    257 	u32 dirty_tx;
    258 	u32 rx_dma;
    259 	u32 tx_dma;
    260 	struct RxDesc *RxDescRing;
    261 	struct TxDesc *TxDescRing;
    262 	struct io_buffer *Rx_iobuf[NUM_RX_DESC];
    263 	struct io_buffer *Tx_iobuf[NUM_TX_DESC];
    264 	struct mii_if_info mii_if;
    265 	struct list_head first_phy;
    266 	u32 features;
    267 };
    268 
    269 struct sis190_phy {
    270 	struct list_head list;
    271 	int phy_id;
    272 	u16 id[2];
    273 	u16 status;
    274 	u8  type;
    275 };
    276 
    277 enum sis190_phy_type {
    278 	UNKNOWN	= 0x00,
    279 	HOME	= 0x01,
    280 	LAN	= 0x02,
    281 	MIX	= 0x03
    282 };
    283 
    284 static struct mii_chip_info {
    285 	const char *name;
    286 	u16 id[2];
    287 	unsigned int type;
    288 	u32 feature;
    289 } mii_chip_table[] = {
    290 	{ "Atheros PHY",          { 0x004d, 0xd010 }, LAN, 0 },
    291 	{ "Atheros PHY AR8012",   { 0x004d, 0xd020 }, LAN, 0 },
    292 	{ "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN, F_PHY_BCM5461 },
    293 	{ "Broadcom PHY AC131",   { 0x0143, 0xbc70 }, LAN, 0 },
    294 	{ "Agere PHY ET1101B",    { 0x0282, 0xf010 }, LAN, 0 },
    295 	{ "Marvell PHY 88E1111",  { 0x0141, 0x0cc0 }, LAN, F_PHY_88E1111 },
    296 	{ "Realtek PHY RTL8201",  { 0x0000, 0x8200 }, LAN, 0 },
    297 	{ NULL, { 0x00, 0x00 }, 0, 0 }
    298 };
    299 
    300 static const struct {
    301 	const char *name;
    302 } sis_chip_info[] = {
    303 	{ "SiS 190 PCI Fast Ethernet adapter" },
    304 	{ "SiS 191 PCI Gigabit Ethernet adapter" },
    305 };
    306 
    307 static void sis190_phy_task(struct sis190_private *tp);
    308 static void sis190_free(struct net_device *dev);
    309 static inline void sis190_init_rxfilter(struct net_device *dev);
    310 
    311 #endif
    312