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 <ipxe/ethernet.h>
17 #include <ipxe/if_ether.h>
18 #include <ipxe/io.h>
19 #include <ipxe/iobuf.h>
20 #include <ipxe/malloc.h>
21 #include <ipxe/netdevice.h>
22 #include <ipxe/pci.h>
23 #include <ipxe/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 (Interrupt 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 publicly
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 void sis190_phy_task(struct sis190_private *tp);
301 static void sis190_free(struct net_device *dev);
302 static inline void sis190_init_rxfilter(struct net_device *dev);
303 
304 #endif
305