xref: /OK3568_Linux_fs/kernel/drivers/net/ethernet/dec/tulip/tulip.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun 	drivers/net/ethernet/dec/tulip/tulip.h
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun 	Copyright 2000,2001  The Linux Kernel Team
5*4882a593Smuzhiyun 	Written/copyright 1994-2001 by Donald Becker.
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun 	This software may be used and distributed according to the terms
8*4882a593Smuzhiyun 	of the GNU General Public License, incorporated herein by reference.
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun 	Please submit bugs to http://bugzilla.kernel.org/ .
11*4882a593Smuzhiyun */
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #ifndef __NET_TULIP_H__
14*4882a593Smuzhiyun #define __NET_TULIP_H__
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #include <linux/kernel.h>
17*4882a593Smuzhiyun #include <linux/types.h>
18*4882a593Smuzhiyun #include <linux/spinlock.h>
19*4882a593Smuzhiyun #include <linux/netdevice.h>
20*4882a593Smuzhiyun #include <linux/ethtool.h>
21*4882a593Smuzhiyun #include <linux/timer.h>
22*4882a593Smuzhiyun #include <linux/delay.h>
23*4882a593Smuzhiyun #include <linux/pci.h>
24*4882a593Smuzhiyun #include <asm/io.h>
25*4882a593Smuzhiyun #include <asm/irq.h>
26*4882a593Smuzhiyun #include <asm/unaligned.h>
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun /* undefine, or define to various debugging levels (>4 == obscene levels) */
31*4882a593Smuzhiyun #define TULIP_DEBUG 1
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #ifdef CONFIG_TULIP_MMIO
34*4882a593Smuzhiyun #define TULIP_BAR	1	/* CBMA */
35*4882a593Smuzhiyun #else
36*4882a593Smuzhiyun #define TULIP_BAR	0	/* CBIO */
37*4882a593Smuzhiyun #endif
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun struct tulip_chip_table {
42*4882a593Smuzhiyun 	char *chip_name;
43*4882a593Smuzhiyun 	int io_size;
44*4882a593Smuzhiyun 	int valid_intrs;	/* CSR7 interrupt enable settings */
45*4882a593Smuzhiyun 	int flags;
46*4882a593Smuzhiyun 	void (*media_timer) (struct timer_list *);
47*4882a593Smuzhiyun 	work_func_t media_task;
48*4882a593Smuzhiyun };
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun enum tbl_flag {
52*4882a593Smuzhiyun 	HAS_MII			= 0x00001,
53*4882a593Smuzhiyun 	HAS_MEDIA_TABLE		= 0x00002,
54*4882a593Smuzhiyun 	CSR12_IN_SROM		= 0x00004,
55*4882a593Smuzhiyun 	ALWAYS_CHECK_MII	= 0x00008,
56*4882a593Smuzhiyun 	HAS_ACPI		= 0x00010,
57*4882a593Smuzhiyun 	MC_HASH_ONLY		= 0x00020, /* Hash-only multicast filter. */
58*4882a593Smuzhiyun 	HAS_PNICNWAY		= 0x00080,
59*4882a593Smuzhiyun 	HAS_NWAY		= 0x00040, /* Uses internal NWay xcvr. */
60*4882a593Smuzhiyun 	HAS_INTR_MITIGATION	= 0x00100,
61*4882a593Smuzhiyun 	IS_ASIX			= 0x00200,
62*4882a593Smuzhiyun 	HAS_8023X		= 0x00400,
63*4882a593Smuzhiyun 	COMET_MAC_ADDR		= 0x00800,
64*4882a593Smuzhiyun 	HAS_PCI_MWI		= 0x01000,
65*4882a593Smuzhiyun 	HAS_PHY_IRQ		= 0x02000,
66*4882a593Smuzhiyun 	HAS_SWAPPED_SEEPROM	= 0x04000,
67*4882a593Smuzhiyun 	NEEDS_FAKE_MEDIA_TABLE	= 0x08000,
68*4882a593Smuzhiyun 	COMET_PM		= 0x10000,
69*4882a593Smuzhiyun };
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun /* chip types.  careful!  order is VERY IMPORTANT here, as these
73*4882a593Smuzhiyun  * are used throughout the driver as indices into arrays */
74*4882a593Smuzhiyun /* Note 21142 == 21143. */
75*4882a593Smuzhiyun enum chips {
76*4882a593Smuzhiyun 	DC21040 = 0,
77*4882a593Smuzhiyun 	DC21041 = 1,
78*4882a593Smuzhiyun 	DC21140 = 2,
79*4882a593Smuzhiyun 	DC21142 = 3, DC21143 = 3,
80*4882a593Smuzhiyun 	LC82C168,
81*4882a593Smuzhiyun 	MX98713,
82*4882a593Smuzhiyun 	MX98715,
83*4882a593Smuzhiyun 	MX98725,
84*4882a593Smuzhiyun 	AX88140,
85*4882a593Smuzhiyun 	PNIC2,
86*4882a593Smuzhiyun 	COMET,
87*4882a593Smuzhiyun 	COMPEX9881,
88*4882a593Smuzhiyun 	I21145,
89*4882a593Smuzhiyun 	DM910X,
90*4882a593Smuzhiyun 	CONEXANT,
91*4882a593Smuzhiyun };
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun enum MediaIs {
95*4882a593Smuzhiyun 	MediaIsFD = 1,
96*4882a593Smuzhiyun 	MediaAlwaysFD = 2,
97*4882a593Smuzhiyun 	MediaIsMII = 4,
98*4882a593Smuzhiyun 	MediaIsFx = 8,
99*4882a593Smuzhiyun 	MediaIs100 = 16
100*4882a593Smuzhiyun };
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun /* Offsets to the Command and Status Registers, "CSRs".  All accesses
104*4882a593Smuzhiyun    must be longword instructions and quadword aligned. */
105*4882a593Smuzhiyun enum tulip_offsets {
106*4882a593Smuzhiyun 	CSR0 = 0,
107*4882a593Smuzhiyun 	CSR1 = 0x08,
108*4882a593Smuzhiyun 	CSR2 = 0x10,
109*4882a593Smuzhiyun 	CSR3 = 0x18,
110*4882a593Smuzhiyun 	CSR4 = 0x20,
111*4882a593Smuzhiyun 	CSR5 = 0x28,
112*4882a593Smuzhiyun 	CSR6 = 0x30,
113*4882a593Smuzhiyun 	CSR7 = 0x38,
114*4882a593Smuzhiyun 	CSR8 = 0x40,
115*4882a593Smuzhiyun 	CSR9 = 0x48,
116*4882a593Smuzhiyun 	CSR10 = 0x50,
117*4882a593Smuzhiyun 	CSR11 = 0x58,
118*4882a593Smuzhiyun 	CSR12 = 0x60,
119*4882a593Smuzhiyun 	CSR13 = 0x68,
120*4882a593Smuzhiyun 	CSR14 = 0x70,
121*4882a593Smuzhiyun 	CSR15 = 0x78,
122*4882a593Smuzhiyun 	CSR18 = 0x88,
123*4882a593Smuzhiyun 	CSR19 = 0x8c,
124*4882a593Smuzhiyun 	CSR20 = 0x90,
125*4882a593Smuzhiyun 	CSR27 = 0xAC,
126*4882a593Smuzhiyun 	CSR28 = 0xB0,
127*4882a593Smuzhiyun };
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun /* register offset and bits for CFDD PCI config reg */
130*4882a593Smuzhiyun enum pci_cfg_driver_reg {
131*4882a593Smuzhiyun 	CFDD = 0x40,
132*4882a593Smuzhiyun 	CFDD_Sleep = (1 << 31),
133*4882a593Smuzhiyun 	CFDD_Snooze = (1 << 30),
134*4882a593Smuzhiyun };
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun #define RxPollInt (RxIntr|RxNoBuf|RxDied|RxJabber)
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun /* The bits in the CSR5 status registers, mostly interrupt sources. */
139*4882a593Smuzhiyun enum status_bits {
140*4882a593Smuzhiyun 	TimerInt = 0x800,
141*4882a593Smuzhiyun 	SystemError = 0x2000,
142*4882a593Smuzhiyun 	TPLnkFail = 0x1000,
143*4882a593Smuzhiyun 	TPLnkPass = 0x10,
144*4882a593Smuzhiyun 	NormalIntr = 0x10000,
145*4882a593Smuzhiyun 	AbnormalIntr = 0x8000,
146*4882a593Smuzhiyun 	RxJabber = 0x200,
147*4882a593Smuzhiyun 	RxDied = 0x100,
148*4882a593Smuzhiyun 	RxNoBuf = 0x80,
149*4882a593Smuzhiyun 	RxIntr = 0x40,
150*4882a593Smuzhiyun 	TxFIFOUnderflow = 0x20,
151*4882a593Smuzhiyun 	RxErrIntr = 0x10,
152*4882a593Smuzhiyun 	TxJabber = 0x08,
153*4882a593Smuzhiyun 	TxNoBuf = 0x04,
154*4882a593Smuzhiyun 	TxDied = 0x02,
155*4882a593Smuzhiyun 	TxIntr = 0x01,
156*4882a593Smuzhiyun };
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun /* bit mask for CSR5 TX/RX process state */
159*4882a593Smuzhiyun #define CSR5_TS	0x00700000
160*4882a593Smuzhiyun #define CSR5_RS	0x000e0000
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun enum tulip_mode_bits {
163*4882a593Smuzhiyun 	TxThreshold		= (1 << 22),
164*4882a593Smuzhiyun 	FullDuplex		= (1 << 9),
165*4882a593Smuzhiyun 	TxOn			= 0x2000,
166*4882a593Smuzhiyun 	AcceptBroadcast		= 0x0100,
167*4882a593Smuzhiyun 	AcceptAllMulticast	= 0x0080,
168*4882a593Smuzhiyun 	AcceptAllPhys		= 0x0040,
169*4882a593Smuzhiyun 	AcceptRunt		= 0x0008,
170*4882a593Smuzhiyun 	RxOn			= 0x0002,
171*4882a593Smuzhiyun 	RxTx			= (TxOn | RxOn),
172*4882a593Smuzhiyun };
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun enum tulip_busconfig_bits {
176*4882a593Smuzhiyun 	MWI			= (1 << 24),
177*4882a593Smuzhiyun 	MRL			= (1 << 23),
178*4882a593Smuzhiyun 	MRM			= (1 << 21),
179*4882a593Smuzhiyun 	CALShift		= 14,
180*4882a593Smuzhiyun 	BurstLenShift		= 8,
181*4882a593Smuzhiyun };
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun /* The Tulip Rx and Tx buffer descriptors. */
185*4882a593Smuzhiyun struct tulip_rx_desc {
186*4882a593Smuzhiyun 	__le32 status;
187*4882a593Smuzhiyun 	__le32 length;
188*4882a593Smuzhiyun 	__le32 buffer1;
189*4882a593Smuzhiyun 	__le32 buffer2;
190*4882a593Smuzhiyun };
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun struct tulip_tx_desc {
194*4882a593Smuzhiyun 	__le32 status;
195*4882a593Smuzhiyun 	__le32 length;
196*4882a593Smuzhiyun 	__le32 buffer1;
197*4882a593Smuzhiyun 	__le32 buffer2;		/* We use only buffer 1.  */
198*4882a593Smuzhiyun };
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun enum desc_status_bits {
202*4882a593Smuzhiyun 	DescOwned    = 0x80000000,
203*4882a593Smuzhiyun 	DescWholePkt = 0x60000000,
204*4882a593Smuzhiyun 	DescEndPkt   = 0x40000000,
205*4882a593Smuzhiyun 	DescStartPkt = 0x20000000,
206*4882a593Smuzhiyun 	DescEndRing  = 0x02000000,
207*4882a593Smuzhiyun 	DescUseLink  = 0x01000000,
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun 	/*
210*4882a593Smuzhiyun 	 * Error summary flag is logical or of 'CRC Error', 'Collision Seen',
211*4882a593Smuzhiyun 	 * 'Frame Too Long', 'Runt' and 'Descriptor Error' flags generated
212*4882a593Smuzhiyun 	 * within tulip chip.
213*4882a593Smuzhiyun 	 */
214*4882a593Smuzhiyun 	RxDescErrorSummary = 0x8000,
215*4882a593Smuzhiyun 	RxDescCRCError = 0x0002,
216*4882a593Smuzhiyun 	RxDescCollisionSeen = 0x0040,
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun 	/*
219*4882a593Smuzhiyun 	 * 'Frame Too Long' flag is set if packet length including CRC exceeds
220*4882a593Smuzhiyun 	 * 1518.  However, a full sized VLAN tagged frame is 1522 bytes
221*4882a593Smuzhiyun 	 * including CRC.
222*4882a593Smuzhiyun 	 *
223*4882a593Smuzhiyun 	 * The tulip chip does not block oversized frames, and if this flag is
224*4882a593Smuzhiyun 	 * set on a receive descriptor it does not indicate the frame has been
225*4882a593Smuzhiyun 	 * truncated.  The receive descriptor also includes the actual length.
226*4882a593Smuzhiyun 	 * Therefore we can safety ignore this flag and check the length
227*4882a593Smuzhiyun 	 * ourselves.
228*4882a593Smuzhiyun 	 */
229*4882a593Smuzhiyun 	RxDescFrameTooLong = 0x0080,
230*4882a593Smuzhiyun 	RxDescRunt = 0x0800,
231*4882a593Smuzhiyun 	RxDescDescErr = 0x4000,
232*4882a593Smuzhiyun 	RxWholePkt   = 0x00000300,
233*4882a593Smuzhiyun 	/*
234*4882a593Smuzhiyun 	 * Top three bits of 14 bit frame length (status bits 27-29) should
235*4882a593Smuzhiyun 	 * never be set as that would make frame over 2047 bytes. The Receive
236*4882a593Smuzhiyun 	 * Watchdog flag (bit 4) may indicate the length is over 2048 and the
237*4882a593Smuzhiyun 	 * length field is invalid.
238*4882a593Smuzhiyun 	 */
239*4882a593Smuzhiyun 	RxLengthOver2047 = 0x38000010
240*4882a593Smuzhiyun };
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun enum t21143_csr6_bits {
244*4882a593Smuzhiyun 	csr6_sc = (1<<31),
245*4882a593Smuzhiyun 	csr6_ra = (1<<30),
246*4882a593Smuzhiyun 	csr6_ign_dest_msb = (1<<26),
247*4882a593Smuzhiyun 	csr6_mbo = (1<<25),
248*4882a593Smuzhiyun 	csr6_scr = (1<<24),  /* scramble mode flag: can't be set */
249*4882a593Smuzhiyun 	csr6_pcs = (1<<23),  /* Enables PCS functions (symbol mode requires csr6_ps be set) default is set */
250*4882a593Smuzhiyun 	csr6_ttm = (1<<22),  /* Transmit Threshold Mode, set for 10baseT, 0 for 100BaseTX */
251*4882a593Smuzhiyun 	csr6_sf = (1<<21),   /* Store and forward. If set ignores TR bits */
252*4882a593Smuzhiyun 	csr6_hbd = (1<<19),  /* Heart beat disable. Disables SQE function in 10baseT */
253*4882a593Smuzhiyun 	csr6_ps = (1<<18),   /* Port Select. 0 (defualt) = 10baseT, 1 = 100baseTX: can't be set */
254*4882a593Smuzhiyun 	csr6_ca = (1<<17),   /* Collision Offset Enable. If set uses special algorithm in low collision situations */
255*4882a593Smuzhiyun 	csr6_trh = (1<<15),  /* Transmit Threshold high bit */
256*4882a593Smuzhiyun 	csr6_trl = (1<<14),  /* Transmit Threshold low bit */
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun 	/***************************************************************
259*4882a593Smuzhiyun 	 * This table shows transmit threshold values based on media   *
260*4882a593Smuzhiyun 	 * and these two registers (from PNIC1 & 2 docs) Note: this is *
261*4882a593Smuzhiyun 	 * all meaningless if sf is set.                               *
262*4882a593Smuzhiyun 	 ***************************************************************/
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun 	/***********************************
265*4882a593Smuzhiyun 	 * (trh,trl) * 100BaseTX * 10BaseT *
266*4882a593Smuzhiyun 	 ***********************************
267*4882a593Smuzhiyun 	 *   (0,0)   *     128   *    72   *
268*4882a593Smuzhiyun 	 *   (0,1)   *     256   *    96   *
269*4882a593Smuzhiyun 	 *   (1,0)   *     512   *   128   *
270*4882a593Smuzhiyun 	 *   (1,1)   *    1024   *   160   *
271*4882a593Smuzhiyun 	 ***********************************/
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun 	csr6_fc = (1<<12),   /* Forces a collision in next transmission (for testing in loopback mode) */
274*4882a593Smuzhiyun 	csr6_om_int_loop = (1<<10), /* internal (FIFO) loopback flag */
275*4882a593Smuzhiyun 	csr6_om_ext_loop = (1<<11), /* external (PMD) loopback flag */
276*4882a593Smuzhiyun 	/* set both and you get (PHY) loopback */
277*4882a593Smuzhiyun 	csr6_fd = (1<<9),    /* Full duplex mode, disables hearbeat, no loopback */
278*4882a593Smuzhiyun 	csr6_pm = (1<<7),    /* Pass All Multicast */
279*4882a593Smuzhiyun 	csr6_pr = (1<<6),    /* Promiscuous mode */
280*4882a593Smuzhiyun 	csr6_sb = (1<<5),    /* Start(1)/Stop(0) backoff counter */
281*4882a593Smuzhiyun 	csr6_if = (1<<4),    /* Inverse Filtering, rejects only addresses in address table: can't be set */
282*4882a593Smuzhiyun 	csr6_pb = (1<<3),    /* Pass Bad Frames, (1) causes even bad frames to be passed on */
283*4882a593Smuzhiyun 	csr6_ho = (1<<2),    /* Hash-only filtering mode: can't be set */
284*4882a593Smuzhiyun 	csr6_hp = (1<<0),    /* Hash/Perfect Receive Filtering Mode: can't be set */
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	csr6_mask_capture = (csr6_sc | csr6_ca),
287*4882a593Smuzhiyun 	csr6_mask_defstate = (csr6_mask_capture | csr6_mbo),
288*4882a593Smuzhiyun 	csr6_mask_hdcap = (csr6_mask_defstate | csr6_hbd | csr6_ps),
289*4882a593Smuzhiyun 	csr6_mask_hdcaptt = (csr6_mask_hdcap  | csr6_trh | csr6_trl),
290*4882a593Smuzhiyun 	csr6_mask_fullcap = (csr6_mask_hdcaptt | csr6_fd),
291*4882a593Smuzhiyun 	csr6_mask_fullpromisc = (csr6_pr | csr6_pm),
292*4882a593Smuzhiyun 	csr6_mask_filters = (csr6_hp | csr6_ho | csr6_if),
293*4882a593Smuzhiyun 	csr6_mask_100bt = (csr6_scr | csr6_pcs | csr6_hbd),
294*4882a593Smuzhiyun };
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun enum tulip_comet_csr13_bits {
297*4882a593Smuzhiyun /* The LINKOFFE and LINKONE work in conjunction with LSCE, i.e. they
298*4882a593Smuzhiyun  * determine which link status transition wakes up if LSCE is
299*4882a593Smuzhiyun  * enabled */
300*4882a593Smuzhiyun         comet_csr13_linkoffe = (1 << 17),
301*4882a593Smuzhiyun         comet_csr13_linkone = (1 << 16),
302*4882a593Smuzhiyun         comet_csr13_wfre = (1 << 10),
303*4882a593Smuzhiyun         comet_csr13_mpre = (1 << 9),
304*4882a593Smuzhiyun         comet_csr13_lsce = (1 << 8),
305*4882a593Smuzhiyun         comet_csr13_wfr = (1 << 2),
306*4882a593Smuzhiyun         comet_csr13_mpr = (1 << 1),
307*4882a593Smuzhiyun         comet_csr13_lsc = (1 << 0),
308*4882a593Smuzhiyun };
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun enum tulip_comet_csr18_bits {
311*4882a593Smuzhiyun         comet_csr18_pmes_sticky = (1 << 24),
312*4882a593Smuzhiyun         comet_csr18_pm_mode = (1 << 19),
313*4882a593Smuzhiyun         comet_csr18_apm_mode = (1 << 18),
314*4882a593Smuzhiyun         comet_csr18_d3a = (1 << 7)
315*4882a593Smuzhiyun };
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun enum tulip_comet_csr20_bits {
318*4882a593Smuzhiyun         comet_csr20_pmes = (1 << 15),
319*4882a593Smuzhiyun };
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun /* Keep the ring sizes a power of two for efficiency.
322*4882a593Smuzhiyun    Making the Tx ring too large decreases the effectiveness of channel
323*4882a593Smuzhiyun    bonding and packet priority.
324*4882a593Smuzhiyun    There are no ill effects from too-large receive rings. */
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun #define TX_RING_SIZE	32
327*4882a593Smuzhiyun #define RX_RING_SIZE	128
328*4882a593Smuzhiyun #define MEDIA_MASK     31
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun /* The receiver on the DC21143 rev 65 can fail to close the last
331*4882a593Smuzhiyun  * receive descriptor in certain circumstances (see errata) when
332*4882a593Smuzhiyun  * using MWI. This can only occur if the receive buffer ends on
333*4882a593Smuzhiyun  * a cache line boundary, so the "+ 4" below ensures it doesn't.
334*4882a593Smuzhiyun  */
335*4882a593Smuzhiyun #define PKT_BUF_SZ	(1536 + 4)	/* Size of each temporary Rx buffer. */
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun #define TULIP_MIN_CACHE_LINE	8	/* in units of 32-bit words */
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun #if defined(__sparc__) || defined(__hppa__)
340*4882a593Smuzhiyun /* The UltraSparc PCI controllers will disconnect at every 64-byte
341*4882a593Smuzhiyun  * crossing anyways so it makes no sense to tell Tulip to burst
342*4882a593Smuzhiyun  * any more than that.
343*4882a593Smuzhiyun  */
344*4882a593Smuzhiyun #define TULIP_MAX_CACHE_LINE	16	/* in units of 32-bit words */
345*4882a593Smuzhiyun #else
346*4882a593Smuzhiyun #define TULIP_MAX_CACHE_LINE	32	/* in units of 32-bit words */
347*4882a593Smuzhiyun #endif
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun /* Ring-wrap flag in length field, use for last ring entry.
351*4882a593Smuzhiyun 	0x01000000 means chain on buffer2 address,
352*4882a593Smuzhiyun 	0x02000000 means use the ring start address in CSR2/3.
353*4882a593Smuzhiyun    Note: Some work-alike chips do not function correctly in chained mode.
354*4882a593Smuzhiyun    The ASIX chip works only in chained mode.
355*4882a593Smuzhiyun    Thus we indicates ring mode, but always write the 'next' field for
356*4882a593Smuzhiyun    chained mode as well.
357*4882a593Smuzhiyun */
358*4882a593Smuzhiyun #define DESC_RING_WRAP 0x02000000
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun #define EEPROM_SIZE 512 	/* 2 << EEPROM_ADDRLEN */
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun #define RUN_AT(x) (jiffies + (x))
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun #define get_u16(ptr) get_unaligned_le16((ptr))
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun struct medialeaf {
369*4882a593Smuzhiyun 	u8 type;
370*4882a593Smuzhiyun 	u8 media;
371*4882a593Smuzhiyun 	unsigned char *leafdata;
372*4882a593Smuzhiyun };
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun struct mediatable {
376*4882a593Smuzhiyun 	u16 defaultmedia;
377*4882a593Smuzhiyun 	u8 leafcount;
378*4882a593Smuzhiyun 	u8 csr12dir;		/* General purpose pin directions. */
379*4882a593Smuzhiyun 	unsigned has_mii:1;
380*4882a593Smuzhiyun 	unsigned has_nonmii:1;
381*4882a593Smuzhiyun 	unsigned has_reset:6;
382*4882a593Smuzhiyun 	u32 csr15dir;
383*4882a593Smuzhiyun 	u32 csr15val;		/* 21143 NWay setting. */
384*4882a593Smuzhiyun 	struct medialeaf mleaf[];
385*4882a593Smuzhiyun };
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun struct mediainfo {
389*4882a593Smuzhiyun 	struct mediainfo *next;
390*4882a593Smuzhiyun 	int info_type;
391*4882a593Smuzhiyun 	int index;
392*4882a593Smuzhiyun 	unsigned char *info;
393*4882a593Smuzhiyun };
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun struct ring_info {
396*4882a593Smuzhiyun 	struct sk_buff	*skb;
397*4882a593Smuzhiyun 	dma_addr_t	mapping;
398*4882a593Smuzhiyun };
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun struct tulip_private {
402*4882a593Smuzhiyun 	const char *product_name;
403*4882a593Smuzhiyun 	struct net_device *next_module;
404*4882a593Smuzhiyun 	struct tulip_rx_desc *rx_ring;
405*4882a593Smuzhiyun 	struct tulip_tx_desc *tx_ring;
406*4882a593Smuzhiyun 	dma_addr_t rx_ring_dma;
407*4882a593Smuzhiyun 	dma_addr_t tx_ring_dma;
408*4882a593Smuzhiyun 	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
409*4882a593Smuzhiyun 	struct ring_info tx_buffers[TX_RING_SIZE];
410*4882a593Smuzhiyun 	/* The addresses of receive-in-place skbuffs. */
411*4882a593Smuzhiyun 	struct ring_info rx_buffers[RX_RING_SIZE];
412*4882a593Smuzhiyun 	u16 setup_frame[96];	/* Pseudo-Tx frame to init address table. */
413*4882a593Smuzhiyun 	int chip_id;
414*4882a593Smuzhiyun 	int revision;
415*4882a593Smuzhiyun 	int flags;
416*4882a593Smuzhiyun 	struct napi_struct napi;
417*4882a593Smuzhiyun 	struct timer_list timer;	/* Media selection timer. */
418*4882a593Smuzhiyun 	struct timer_list oom_timer;    /* Out of memory timer. */
419*4882a593Smuzhiyun 	u32 mc_filter[2];
420*4882a593Smuzhiyun 	spinlock_t lock;
421*4882a593Smuzhiyun 	spinlock_t mii_lock;
422*4882a593Smuzhiyun 	unsigned int cur_rx, cur_tx;	/* The next free ring entry */
423*4882a593Smuzhiyun 	unsigned int dirty_rx, dirty_tx;	/* The ring entries to be free()ed. */
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun #ifdef 	CONFIG_TULIP_NAPI_HW_MITIGATION
426*4882a593Smuzhiyun         int mit_on;
427*4882a593Smuzhiyun #endif
428*4882a593Smuzhiyun 	unsigned int full_duplex:1;	/* Full-duplex operation requested. */
429*4882a593Smuzhiyun 	unsigned int full_duplex_lock:1;
430*4882a593Smuzhiyun 	unsigned int fake_addr:1;	/* Multiport board faked address. */
431*4882a593Smuzhiyun 	unsigned int default_port:4;	/* Last dev->if_port value. */
432*4882a593Smuzhiyun 	unsigned int media2:4;	/* Secondary monitored media port. */
433*4882a593Smuzhiyun 	unsigned int medialock:1;	/* Don't sense media type. */
434*4882a593Smuzhiyun 	unsigned int mediasense:1;	/* Media sensing in progress. */
435*4882a593Smuzhiyun 	unsigned int nway:1, nwayset:1;		/* 21143 internal NWay. */
436*4882a593Smuzhiyun 	unsigned int timeout_recovery:1;
437*4882a593Smuzhiyun 	unsigned int csr0;	/* CSR0 setting. */
438*4882a593Smuzhiyun 	unsigned int csr6;	/* Current CSR6 control settings. */
439*4882a593Smuzhiyun 	unsigned char eeprom[EEPROM_SIZE];	/* Serial EEPROM contents. */
440*4882a593Smuzhiyun 	void (*link_change) (struct net_device * dev, int csr5);
441*4882a593Smuzhiyun         struct ethtool_wolinfo wolinfo;        /* WOL settings */
442*4882a593Smuzhiyun 	u16 sym_advertise, mii_advertise; /* NWay capabilities advertised.  */
443*4882a593Smuzhiyun 	u16 lpar;		/* 21143 Link partner ability. */
444*4882a593Smuzhiyun 	u16 advertising[4];
445*4882a593Smuzhiyun 	signed char phys[4], mii_cnt;	/* MII device addresses. */
446*4882a593Smuzhiyun 	struct mediatable *mtable;
447*4882a593Smuzhiyun 	int cur_index;		/* Current media index. */
448*4882a593Smuzhiyun 	int saved_if_port;
449*4882a593Smuzhiyun 	struct pci_dev *pdev;
450*4882a593Smuzhiyun 	int ttimer;
451*4882a593Smuzhiyun 	int susp_rx;
452*4882a593Smuzhiyun 	unsigned long nir;
453*4882a593Smuzhiyun 	void __iomem *base_addr;
454*4882a593Smuzhiyun 	int csr12_shadow;
455*4882a593Smuzhiyun 	int pad0;		/* Used for 8-byte alignment */
456*4882a593Smuzhiyun 	struct work_struct media_work;
457*4882a593Smuzhiyun 	struct net_device *dev;
458*4882a593Smuzhiyun };
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun struct eeprom_fixup {
462*4882a593Smuzhiyun 	char *name;
463*4882a593Smuzhiyun 	unsigned char addr0;
464*4882a593Smuzhiyun 	unsigned char addr1;
465*4882a593Smuzhiyun 	unsigned char addr2;
466*4882a593Smuzhiyun 	u16 newtable[32];	/* Max length below. */
467*4882a593Smuzhiyun };
468*4882a593Smuzhiyun 
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun /* 21142.c */
471*4882a593Smuzhiyun extern u16 t21142_csr14[];
472*4882a593Smuzhiyun void t21142_media_task(struct work_struct *work);
473*4882a593Smuzhiyun void t21142_start_nway(struct net_device *dev);
474*4882a593Smuzhiyun void t21142_lnk_change(struct net_device *dev, int csr5);
475*4882a593Smuzhiyun 
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun /* PNIC2.c */
478*4882a593Smuzhiyun void pnic2_lnk_change(struct net_device *dev, int csr5);
479*4882a593Smuzhiyun void pnic2_timer(struct timer_list *t);
480*4882a593Smuzhiyun void pnic2_start_nway(struct net_device *dev);
481*4882a593Smuzhiyun void pnic2_lnk_change(struct net_device *dev, int csr5);
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun /* eeprom.c */
484*4882a593Smuzhiyun void tulip_parse_eeprom(struct net_device *dev);
485*4882a593Smuzhiyun int tulip_read_eeprom(struct net_device *dev, int location, int addr_len);
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun /* interrupt.c */
488*4882a593Smuzhiyun extern unsigned int tulip_max_interrupt_work;
489*4882a593Smuzhiyun extern int tulip_rx_copybreak;
490*4882a593Smuzhiyun irqreturn_t tulip_interrupt(int irq, void *dev_instance);
491*4882a593Smuzhiyun int tulip_refill_rx(struct net_device *dev);
492*4882a593Smuzhiyun #ifdef CONFIG_TULIP_NAPI
493*4882a593Smuzhiyun int tulip_poll(struct napi_struct *napi, int budget);
494*4882a593Smuzhiyun #endif
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun 
497*4882a593Smuzhiyun /* media.c */
498*4882a593Smuzhiyun int tulip_mdio_read(struct net_device *dev, int phy_id, int location);
499*4882a593Smuzhiyun void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int value);
500*4882a593Smuzhiyun void tulip_select_media(struct net_device *dev, int startup);
501*4882a593Smuzhiyun int tulip_check_duplex(struct net_device *dev);
502*4882a593Smuzhiyun void tulip_find_mii (struct net_device *dev, int board_idx);
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun /* pnic.c */
505*4882a593Smuzhiyun void pnic_do_nway(struct net_device *dev);
506*4882a593Smuzhiyun void pnic_lnk_change(struct net_device *dev, int csr5);
507*4882a593Smuzhiyun void pnic_timer(struct timer_list *t);
508*4882a593Smuzhiyun 
509*4882a593Smuzhiyun /* timer.c */
510*4882a593Smuzhiyun void tulip_media_task(struct work_struct *work);
511*4882a593Smuzhiyun void mxic_timer(struct timer_list *t);
512*4882a593Smuzhiyun void comet_timer(struct timer_list *t);
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun /* tulip_core.c */
515*4882a593Smuzhiyun extern int tulip_debug;
516*4882a593Smuzhiyun extern const char * const medianame[];
517*4882a593Smuzhiyun extern const char tulip_media_cap[];
518*4882a593Smuzhiyun extern const struct tulip_chip_table tulip_tbl[];
519*4882a593Smuzhiyun void oom_timer(struct timer_list *t);
520*4882a593Smuzhiyun extern u8 t21040_csr13[];
521*4882a593Smuzhiyun 
tulip_start_rxtx(struct tulip_private * tp)522*4882a593Smuzhiyun static inline void tulip_start_rxtx(struct tulip_private *tp)
523*4882a593Smuzhiyun {
524*4882a593Smuzhiyun 	void __iomem *ioaddr = tp->base_addr;
525*4882a593Smuzhiyun 	iowrite32(tp->csr6 | RxTx, ioaddr + CSR6);
526*4882a593Smuzhiyun 	barrier();
527*4882a593Smuzhiyun 	(void) ioread32(ioaddr + CSR6); /* mmio sync */
528*4882a593Smuzhiyun }
529*4882a593Smuzhiyun 
tulip_stop_rxtx(struct tulip_private * tp)530*4882a593Smuzhiyun static inline void tulip_stop_rxtx(struct tulip_private *tp)
531*4882a593Smuzhiyun {
532*4882a593Smuzhiyun 	void __iomem *ioaddr = tp->base_addr;
533*4882a593Smuzhiyun 	u32 csr6 = ioread32(ioaddr + CSR6);
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun 	if (csr6 & RxTx) {
536*4882a593Smuzhiyun 		unsigned i=1300/10;
537*4882a593Smuzhiyun 		iowrite32(csr6 & ~RxTx, ioaddr + CSR6);
538*4882a593Smuzhiyun 		barrier();
539*4882a593Smuzhiyun 		/* wait until in-flight frame completes.
540*4882a593Smuzhiyun 		 * Max time @ 10BT: 1500*8b/10Mbps == 1200us (+ 100us margin)
541*4882a593Smuzhiyun 		 * Typically expect this loop to end in < 50 us on 100BT.
542*4882a593Smuzhiyun 		 */
543*4882a593Smuzhiyun 		while (--i && (ioread32(ioaddr + CSR5) & (CSR5_TS|CSR5_RS)))
544*4882a593Smuzhiyun 			udelay(10);
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun 		if (!i)
547*4882a593Smuzhiyun 			netdev_dbg(tp->dev, "tulip_stop_rxtx() failed (CSR5 0x%x CSR6 0x%x)\n",
548*4882a593Smuzhiyun 				   ioread32(ioaddr + CSR5),
549*4882a593Smuzhiyun 				   ioread32(ioaddr + CSR6));
550*4882a593Smuzhiyun 	}
551*4882a593Smuzhiyun }
552*4882a593Smuzhiyun 
tulip_restart_rxtx(struct tulip_private * tp)553*4882a593Smuzhiyun static inline void tulip_restart_rxtx(struct tulip_private *tp)
554*4882a593Smuzhiyun {
555*4882a593Smuzhiyun 	tulip_stop_rxtx(tp);
556*4882a593Smuzhiyun 	udelay(5);
557*4882a593Smuzhiyun 	tulip_start_rxtx(tp);
558*4882a593Smuzhiyun }
559*4882a593Smuzhiyun 
tulip_tx_timeout_complete(struct tulip_private * tp,void __iomem * ioaddr)560*4882a593Smuzhiyun static inline void tulip_tx_timeout_complete(struct tulip_private *tp, void __iomem *ioaddr)
561*4882a593Smuzhiyun {
562*4882a593Smuzhiyun 	/* Stop and restart the chip's Tx processes. */
563*4882a593Smuzhiyun 	tulip_restart_rxtx(tp);
564*4882a593Smuzhiyun 	/* Trigger an immediate transmit demand. */
565*4882a593Smuzhiyun 	iowrite32(0, ioaddr + CSR1);
566*4882a593Smuzhiyun 
567*4882a593Smuzhiyun 	tp->dev->stats.tx_errors++;
568*4882a593Smuzhiyun }
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun #endif /* __NET_TULIP_H__ */
571