162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci	drivers/net/ethernet/dec/tulip/tulip.h
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci	Copyright 2000,2001  The Linux Kernel Team
562306a36Sopenharmony_ci	Written/copyright 1994-2001 by Donald Becker.
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci	This software may be used and distributed according to the terms
862306a36Sopenharmony_ci	of the GNU General Public License, incorporated herein by reference.
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci	Please submit bugs to http://bugzilla.kernel.org/ .
1162306a36Sopenharmony_ci*/
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#ifndef __NET_TULIP_H__
1462306a36Sopenharmony_ci#define __NET_TULIP_H__
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#include <linux/kernel.h>
1762306a36Sopenharmony_ci#include <linux/types.h>
1862306a36Sopenharmony_ci#include <linux/spinlock.h>
1962306a36Sopenharmony_ci#include <linux/netdevice.h>
2062306a36Sopenharmony_ci#include <linux/ethtool.h>
2162306a36Sopenharmony_ci#include <linux/timer.h>
2262306a36Sopenharmony_ci#include <linux/delay.h>
2362306a36Sopenharmony_ci#include <linux/pci.h>
2462306a36Sopenharmony_ci#include <asm/io.h>
2562306a36Sopenharmony_ci#include <asm/irq.h>
2662306a36Sopenharmony_ci#include <asm/unaligned.h>
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci/* undefine, or define to various debugging levels (>4 == obscene levels) */
3162306a36Sopenharmony_ci#define TULIP_DEBUG 1
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci#ifdef CONFIG_TULIP_MMIO
3462306a36Sopenharmony_ci#define TULIP_BAR	1	/* CBMA */
3562306a36Sopenharmony_ci#else
3662306a36Sopenharmony_ci#define TULIP_BAR	0	/* CBIO */
3762306a36Sopenharmony_ci#endif
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_cistruct tulip_chip_table {
4262306a36Sopenharmony_ci	char *chip_name;
4362306a36Sopenharmony_ci	int io_size;
4462306a36Sopenharmony_ci	int valid_intrs;	/* CSR7 interrupt enable settings */
4562306a36Sopenharmony_ci	int flags;
4662306a36Sopenharmony_ci	void (*media_timer) (struct timer_list *);
4762306a36Sopenharmony_ci	work_func_t media_task;
4862306a36Sopenharmony_ci};
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_cienum tbl_flag {
5262306a36Sopenharmony_ci	HAS_MII			= 0x00001,
5362306a36Sopenharmony_ci	HAS_MEDIA_TABLE		= 0x00002,
5462306a36Sopenharmony_ci	CSR12_IN_SROM		= 0x00004,
5562306a36Sopenharmony_ci	ALWAYS_CHECK_MII	= 0x00008,
5662306a36Sopenharmony_ci	HAS_ACPI		= 0x00010,
5762306a36Sopenharmony_ci	MC_HASH_ONLY		= 0x00020, /* Hash-only multicast filter. */
5862306a36Sopenharmony_ci	HAS_PNICNWAY		= 0x00080,
5962306a36Sopenharmony_ci	HAS_NWAY		= 0x00040, /* Uses internal NWay xcvr. */
6062306a36Sopenharmony_ci	HAS_INTR_MITIGATION	= 0x00100,
6162306a36Sopenharmony_ci	IS_ASIX			= 0x00200,
6262306a36Sopenharmony_ci	HAS_8023X		= 0x00400,
6362306a36Sopenharmony_ci	COMET_MAC_ADDR		= 0x00800,
6462306a36Sopenharmony_ci	HAS_PCI_MWI		= 0x01000,
6562306a36Sopenharmony_ci	HAS_PHY_IRQ		= 0x02000,
6662306a36Sopenharmony_ci	HAS_SWAPPED_SEEPROM	= 0x04000,
6762306a36Sopenharmony_ci	NEEDS_FAKE_MEDIA_TABLE	= 0x08000,
6862306a36Sopenharmony_ci	COMET_PM		= 0x10000,
6962306a36Sopenharmony_ci};
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci/* chip types.  careful!  order is VERY IMPORTANT here, as these
7362306a36Sopenharmony_ci * are used throughout the driver as indices into arrays */
7462306a36Sopenharmony_ci/* Note 21142 == 21143. */
7562306a36Sopenharmony_cienum chips {
7662306a36Sopenharmony_ci	DC21040 = 0,
7762306a36Sopenharmony_ci	DC21041 = 1,
7862306a36Sopenharmony_ci	DC21140 = 2,
7962306a36Sopenharmony_ci	DC21142 = 3, DC21143 = 3,
8062306a36Sopenharmony_ci	LC82C168,
8162306a36Sopenharmony_ci	MX98713,
8262306a36Sopenharmony_ci	MX98715,
8362306a36Sopenharmony_ci	MX98725,
8462306a36Sopenharmony_ci	AX88140,
8562306a36Sopenharmony_ci	PNIC2,
8662306a36Sopenharmony_ci	COMET,
8762306a36Sopenharmony_ci	COMPEX9881,
8862306a36Sopenharmony_ci	I21145,
8962306a36Sopenharmony_ci	DM910X,
9062306a36Sopenharmony_ci	CONEXANT,
9162306a36Sopenharmony_ci};
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_cienum MediaIs {
9562306a36Sopenharmony_ci	MediaIsFD = 1,
9662306a36Sopenharmony_ci	MediaAlwaysFD = 2,
9762306a36Sopenharmony_ci	MediaIsMII = 4,
9862306a36Sopenharmony_ci	MediaIsFx = 8,
9962306a36Sopenharmony_ci	MediaIs100 = 16
10062306a36Sopenharmony_ci};
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci/* Offsets to the Command and Status Registers, "CSRs".  All accesses
10462306a36Sopenharmony_ci   must be longword instructions and quadword aligned. */
10562306a36Sopenharmony_cienum tulip_offsets {
10662306a36Sopenharmony_ci	CSR0 = 0,
10762306a36Sopenharmony_ci	CSR1 = 0x08,
10862306a36Sopenharmony_ci	CSR2 = 0x10,
10962306a36Sopenharmony_ci	CSR3 = 0x18,
11062306a36Sopenharmony_ci	CSR4 = 0x20,
11162306a36Sopenharmony_ci	CSR5 = 0x28,
11262306a36Sopenharmony_ci	CSR6 = 0x30,
11362306a36Sopenharmony_ci	CSR7 = 0x38,
11462306a36Sopenharmony_ci	CSR8 = 0x40,
11562306a36Sopenharmony_ci	CSR9 = 0x48,
11662306a36Sopenharmony_ci	CSR10 = 0x50,
11762306a36Sopenharmony_ci	CSR11 = 0x58,
11862306a36Sopenharmony_ci	CSR12 = 0x60,
11962306a36Sopenharmony_ci	CSR13 = 0x68,
12062306a36Sopenharmony_ci	CSR14 = 0x70,
12162306a36Sopenharmony_ci	CSR15 = 0x78,
12262306a36Sopenharmony_ci	CSR18 = 0x88,
12362306a36Sopenharmony_ci	CSR19 = 0x8c,
12462306a36Sopenharmony_ci	CSR20 = 0x90,
12562306a36Sopenharmony_ci	CSR27 = 0xAC,
12662306a36Sopenharmony_ci	CSR28 = 0xB0,
12762306a36Sopenharmony_ci};
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci/* register offset and bits for CFDD PCI config reg */
13062306a36Sopenharmony_cienum pci_cfg_driver_reg {
13162306a36Sopenharmony_ci	CFDD = 0x40,
13262306a36Sopenharmony_ci	CFDD_Sleep = (1 << 31),
13362306a36Sopenharmony_ci	CFDD_Snooze = (1 << 30),
13462306a36Sopenharmony_ci};
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci#define RxPollInt (RxIntr|RxNoBuf|RxDied|RxJabber)
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci/* The bits in the CSR5 status registers, mostly interrupt sources. */
13962306a36Sopenharmony_cienum status_bits {
14062306a36Sopenharmony_ci	TimerInt = 0x800,
14162306a36Sopenharmony_ci	SystemError = 0x2000,
14262306a36Sopenharmony_ci	TPLnkFail = 0x1000,
14362306a36Sopenharmony_ci	TPLnkPass = 0x10,
14462306a36Sopenharmony_ci	NormalIntr = 0x10000,
14562306a36Sopenharmony_ci	AbnormalIntr = 0x8000,
14662306a36Sopenharmony_ci	RxJabber = 0x200,
14762306a36Sopenharmony_ci	RxDied = 0x100,
14862306a36Sopenharmony_ci	RxNoBuf = 0x80,
14962306a36Sopenharmony_ci	RxIntr = 0x40,
15062306a36Sopenharmony_ci	TxFIFOUnderflow = 0x20,
15162306a36Sopenharmony_ci	RxErrIntr = 0x10,
15262306a36Sopenharmony_ci	TxJabber = 0x08,
15362306a36Sopenharmony_ci	TxNoBuf = 0x04,
15462306a36Sopenharmony_ci	TxDied = 0x02,
15562306a36Sopenharmony_ci	TxIntr = 0x01,
15662306a36Sopenharmony_ci};
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci/* bit mask for CSR5 TX/RX process state */
15962306a36Sopenharmony_ci#define CSR5_TS	0x00700000
16062306a36Sopenharmony_ci#define CSR5_RS	0x000e0000
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_cienum tulip_mode_bits {
16362306a36Sopenharmony_ci	TxThreshold		= (1 << 22),
16462306a36Sopenharmony_ci	FullDuplex		= (1 << 9),
16562306a36Sopenharmony_ci	TxOn			= 0x2000,
16662306a36Sopenharmony_ci	AcceptBroadcast		= 0x0100,
16762306a36Sopenharmony_ci	AcceptAllMulticast	= 0x0080,
16862306a36Sopenharmony_ci	AcceptAllPhys		= 0x0040,
16962306a36Sopenharmony_ci	AcceptRunt		= 0x0008,
17062306a36Sopenharmony_ci	RxOn			= 0x0002,
17162306a36Sopenharmony_ci	RxTx			= (TxOn | RxOn),
17262306a36Sopenharmony_ci};
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_cienum tulip_busconfig_bits {
17662306a36Sopenharmony_ci	MWI			= (1 << 24),
17762306a36Sopenharmony_ci	MRL			= (1 << 23),
17862306a36Sopenharmony_ci	MRM			= (1 << 21),
17962306a36Sopenharmony_ci	CALShift		= 14,
18062306a36Sopenharmony_ci	BurstLenShift		= 8,
18162306a36Sopenharmony_ci};
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci/* The Tulip Rx and Tx buffer descriptors. */
18562306a36Sopenharmony_cistruct tulip_rx_desc {
18662306a36Sopenharmony_ci	__le32 status;
18762306a36Sopenharmony_ci	__le32 length;
18862306a36Sopenharmony_ci	__le32 buffer1;
18962306a36Sopenharmony_ci	__le32 buffer2;
19062306a36Sopenharmony_ci};
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_cistruct tulip_tx_desc {
19462306a36Sopenharmony_ci	__le32 status;
19562306a36Sopenharmony_ci	__le32 length;
19662306a36Sopenharmony_ci	__le32 buffer1;
19762306a36Sopenharmony_ci	__le32 buffer2;		/* We use only buffer 1.  */
19862306a36Sopenharmony_ci};
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_cienum desc_status_bits {
20262306a36Sopenharmony_ci	DescOwned    = 0x80000000,
20362306a36Sopenharmony_ci	DescWholePkt = 0x60000000,
20462306a36Sopenharmony_ci	DescEndPkt   = 0x40000000,
20562306a36Sopenharmony_ci	DescStartPkt = 0x20000000,
20662306a36Sopenharmony_ci	DescEndRing  = 0x02000000,
20762306a36Sopenharmony_ci	DescUseLink  = 0x01000000,
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci	/*
21062306a36Sopenharmony_ci	 * Error summary flag is logical or of 'CRC Error', 'Collision Seen',
21162306a36Sopenharmony_ci	 * 'Frame Too Long', 'Runt' and 'Descriptor Error' flags generated
21262306a36Sopenharmony_ci	 * within tulip chip.
21362306a36Sopenharmony_ci	 */
21462306a36Sopenharmony_ci	RxDescErrorSummary = 0x8000,
21562306a36Sopenharmony_ci	RxDescCRCError = 0x0002,
21662306a36Sopenharmony_ci	RxDescCollisionSeen = 0x0040,
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	/*
21962306a36Sopenharmony_ci	 * 'Frame Too Long' flag is set if packet length including CRC exceeds
22062306a36Sopenharmony_ci	 * 1518.  However, a full sized VLAN tagged frame is 1522 bytes
22162306a36Sopenharmony_ci	 * including CRC.
22262306a36Sopenharmony_ci	 *
22362306a36Sopenharmony_ci	 * The tulip chip does not block oversized frames, and if this flag is
22462306a36Sopenharmony_ci	 * set on a receive descriptor it does not indicate the frame has been
22562306a36Sopenharmony_ci	 * truncated.  The receive descriptor also includes the actual length.
22662306a36Sopenharmony_ci	 * Therefore we can safety ignore this flag and check the length
22762306a36Sopenharmony_ci	 * ourselves.
22862306a36Sopenharmony_ci	 */
22962306a36Sopenharmony_ci	RxDescFrameTooLong = 0x0080,
23062306a36Sopenharmony_ci	RxDescRunt = 0x0800,
23162306a36Sopenharmony_ci	RxDescDescErr = 0x4000,
23262306a36Sopenharmony_ci	RxWholePkt   = 0x00000300,
23362306a36Sopenharmony_ci	/*
23462306a36Sopenharmony_ci	 * Top three bits of 14 bit frame length (status bits 27-29) should
23562306a36Sopenharmony_ci	 * never be set as that would make frame over 2047 bytes. The Receive
23662306a36Sopenharmony_ci	 * Watchdog flag (bit 4) may indicate the length is over 2048 and the
23762306a36Sopenharmony_ci	 * length field is invalid.
23862306a36Sopenharmony_ci	 */
23962306a36Sopenharmony_ci	RxLengthOver2047 = 0x38000010
24062306a36Sopenharmony_ci};
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_cienum t21143_csr6_bits {
24462306a36Sopenharmony_ci	csr6_sc = (1<<31),
24562306a36Sopenharmony_ci	csr6_ra = (1<<30),
24662306a36Sopenharmony_ci	csr6_ign_dest_msb = (1<<26),
24762306a36Sopenharmony_ci	csr6_mbo = (1<<25),
24862306a36Sopenharmony_ci	csr6_scr = (1<<24),  /* scramble mode flag: can't be set */
24962306a36Sopenharmony_ci	csr6_pcs = (1<<23),  /* Enables PCS functions (symbol mode requires csr6_ps be set) default is set */
25062306a36Sopenharmony_ci	csr6_ttm = (1<<22),  /* Transmit Threshold Mode, set for 10baseT, 0 for 100BaseTX */
25162306a36Sopenharmony_ci	csr6_sf = (1<<21),   /* Store and forward. If set ignores TR bits */
25262306a36Sopenharmony_ci	csr6_hbd = (1<<19),  /* Heart beat disable. Disables SQE function in 10baseT */
25362306a36Sopenharmony_ci	csr6_ps = (1<<18),   /* Port Select. 0 (defualt) = 10baseT, 1 = 100baseTX: can't be set */
25462306a36Sopenharmony_ci	csr6_ca = (1<<17),   /* Collision Offset Enable. If set uses special algorithm in low collision situations */
25562306a36Sopenharmony_ci	csr6_trh = (1<<15),  /* Transmit Threshold high bit */
25662306a36Sopenharmony_ci	csr6_trl = (1<<14),  /* Transmit Threshold low bit */
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci	/***************************************************************
25962306a36Sopenharmony_ci	 * This table shows transmit threshold values based on media   *
26062306a36Sopenharmony_ci	 * and these two registers (from PNIC1 & 2 docs) Note: this is *
26162306a36Sopenharmony_ci	 * all meaningless if sf is set.                               *
26262306a36Sopenharmony_ci	 ***************************************************************/
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ci	/***********************************
26562306a36Sopenharmony_ci	 * (trh,trl) * 100BaseTX * 10BaseT *
26662306a36Sopenharmony_ci	 ***********************************
26762306a36Sopenharmony_ci	 *   (0,0)   *     128   *    72   *
26862306a36Sopenharmony_ci	 *   (0,1)   *     256   *    96   *
26962306a36Sopenharmony_ci	 *   (1,0)   *     512   *   128   *
27062306a36Sopenharmony_ci	 *   (1,1)   *    1024   *   160   *
27162306a36Sopenharmony_ci	 ***********************************/
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_ci	csr6_fc = (1<<12),   /* Forces a collision in next transmission (for testing in loopback mode) */
27462306a36Sopenharmony_ci	csr6_om_int_loop = (1<<10), /* internal (FIFO) loopback flag */
27562306a36Sopenharmony_ci	csr6_om_ext_loop = (1<<11), /* external (PMD) loopback flag */
27662306a36Sopenharmony_ci	/* set both and you get (PHY) loopback */
27762306a36Sopenharmony_ci	csr6_fd = (1<<9),    /* Full duplex mode, disables hearbeat, no loopback */
27862306a36Sopenharmony_ci	csr6_pm = (1<<7),    /* Pass All Multicast */
27962306a36Sopenharmony_ci	csr6_pr = (1<<6),    /* Promiscuous mode */
28062306a36Sopenharmony_ci	csr6_sb = (1<<5),    /* Start(1)/Stop(0) backoff counter */
28162306a36Sopenharmony_ci	csr6_if = (1<<4),    /* Inverse Filtering, rejects only addresses in address table: can't be set */
28262306a36Sopenharmony_ci	csr6_pb = (1<<3),    /* Pass Bad Frames, (1) causes even bad frames to be passed on */
28362306a36Sopenharmony_ci	csr6_ho = (1<<2),    /* Hash-only filtering mode: can't be set */
28462306a36Sopenharmony_ci	csr6_hp = (1<<0),    /* Hash/Perfect Receive Filtering Mode: can't be set */
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci	csr6_mask_capture = (csr6_sc | csr6_ca),
28762306a36Sopenharmony_ci	csr6_mask_defstate = (csr6_mask_capture | csr6_mbo),
28862306a36Sopenharmony_ci	csr6_mask_hdcap = (csr6_mask_defstate | csr6_hbd | csr6_ps),
28962306a36Sopenharmony_ci	csr6_mask_hdcaptt = (csr6_mask_hdcap  | csr6_trh | csr6_trl),
29062306a36Sopenharmony_ci	csr6_mask_fullcap = (csr6_mask_hdcaptt | csr6_fd),
29162306a36Sopenharmony_ci	csr6_mask_fullpromisc = (csr6_pr | csr6_pm),
29262306a36Sopenharmony_ci	csr6_mask_filters = (csr6_hp | csr6_ho | csr6_if),
29362306a36Sopenharmony_ci	csr6_mask_100bt = (csr6_scr | csr6_pcs | csr6_hbd),
29462306a36Sopenharmony_ci};
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_cienum tulip_comet_csr13_bits {
29762306a36Sopenharmony_ci/* The LINKOFFE and LINKONE work in conjunction with LSCE, i.e. they
29862306a36Sopenharmony_ci * determine which link status transition wakes up if LSCE is
29962306a36Sopenharmony_ci * enabled */
30062306a36Sopenharmony_ci        comet_csr13_linkoffe = (1 << 17),
30162306a36Sopenharmony_ci        comet_csr13_linkone = (1 << 16),
30262306a36Sopenharmony_ci        comet_csr13_wfre = (1 << 10),
30362306a36Sopenharmony_ci        comet_csr13_mpre = (1 << 9),
30462306a36Sopenharmony_ci        comet_csr13_lsce = (1 << 8),
30562306a36Sopenharmony_ci        comet_csr13_wfr = (1 << 2),
30662306a36Sopenharmony_ci        comet_csr13_mpr = (1 << 1),
30762306a36Sopenharmony_ci        comet_csr13_lsc = (1 << 0),
30862306a36Sopenharmony_ci};
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_cienum tulip_comet_csr18_bits {
31162306a36Sopenharmony_ci        comet_csr18_pmes_sticky = (1 << 24),
31262306a36Sopenharmony_ci        comet_csr18_pm_mode = (1 << 19),
31362306a36Sopenharmony_ci        comet_csr18_apm_mode = (1 << 18),
31462306a36Sopenharmony_ci        comet_csr18_d3a = (1 << 7)
31562306a36Sopenharmony_ci};
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_cienum tulip_comet_csr20_bits {
31862306a36Sopenharmony_ci        comet_csr20_pmes = (1 << 15),
31962306a36Sopenharmony_ci};
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci/* Keep the ring sizes a power of two for efficiency.
32262306a36Sopenharmony_ci   Making the Tx ring too large decreases the effectiveness of channel
32362306a36Sopenharmony_ci   bonding and packet priority.
32462306a36Sopenharmony_ci   There are no ill effects from too-large receive rings. */
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_ci#define TX_RING_SIZE	32
32762306a36Sopenharmony_ci#define RX_RING_SIZE	128
32862306a36Sopenharmony_ci#define MEDIA_MASK     31
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci/* The receiver on the DC21143 rev 65 can fail to close the last
33162306a36Sopenharmony_ci * receive descriptor in certain circumstances (see errata) when
33262306a36Sopenharmony_ci * using MWI. This can only occur if the receive buffer ends on
33362306a36Sopenharmony_ci * a cache line boundary, so the "+ 4" below ensures it doesn't.
33462306a36Sopenharmony_ci */
33562306a36Sopenharmony_ci#define PKT_BUF_SZ	(1536 + 4)	/* Size of each temporary Rx buffer. */
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci#define TULIP_MIN_CACHE_LINE	8	/* in units of 32-bit words */
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci#if defined(__sparc__) || defined(__hppa__)
34062306a36Sopenharmony_ci/* The UltraSparc PCI controllers will disconnect at every 64-byte
34162306a36Sopenharmony_ci * crossing anyways so it makes no sense to tell Tulip to burst
34262306a36Sopenharmony_ci * any more than that.
34362306a36Sopenharmony_ci */
34462306a36Sopenharmony_ci#define TULIP_MAX_CACHE_LINE	16	/* in units of 32-bit words */
34562306a36Sopenharmony_ci#else
34662306a36Sopenharmony_ci#define TULIP_MAX_CACHE_LINE	32	/* in units of 32-bit words */
34762306a36Sopenharmony_ci#endif
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_ci/* Ring-wrap flag in length field, use for last ring entry.
35162306a36Sopenharmony_ci	0x01000000 means chain on buffer2 address,
35262306a36Sopenharmony_ci	0x02000000 means use the ring start address in CSR2/3.
35362306a36Sopenharmony_ci   Note: Some work-alike chips do not function correctly in chained mode.
35462306a36Sopenharmony_ci   The ASIX chip works only in chained mode.
35562306a36Sopenharmony_ci   Thus we indicates ring mode, but always write the 'next' field for
35662306a36Sopenharmony_ci   chained mode as well.
35762306a36Sopenharmony_ci*/
35862306a36Sopenharmony_ci#define DESC_RING_WRAP 0x02000000
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci#define EEPROM_SIZE 512 	/* 2 << EEPROM_ADDRLEN */
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci#define RUN_AT(x) (jiffies + (x))
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci#define get_u16(ptr) get_unaligned_le16((ptr))
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_cistruct medialeaf {
36962306a36Sopenharmony_ci	u8 type;
37062306a36Sopenharmony_ci	u8 media;
37162306a36Sopenharmony_ci	unsigned char *leafdata;
37262306a36Sopenharmony_ci};
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_cistruct mediatable {
37662306a36Sopenharmony_ci	u16 defaultmedia;
37762306a36Sopenharmony_ci	u8 leafcount;
37862306a36Sopenharmony_ci	u8 csr12dir;		/* General purpose pin directions. */
37962306a36Sopenharmony_ci	unsigned has_mii:1;
38062306a36Sopenharmony_ci	unsigned has_nonmii:1;
38162306a36Sopenharmony_ci	unsigned has_reset:6;
38262306a36Sopenharmony_ci	u32 csr15dir;
38362306a36Sopenharmony_ci	u32 csr15val;		/* 21143 NWay setting. */
38462306a36Sopenharmony_ci	struct medialeaf mleaf[];
38562306a36Sopenharmony_ci};
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_cistruct mediainfo {
38962306a36Sopenharmony_ci	struct mediainfo *next;
39062306a36Sopenharmony_ci	int info_type;
39162306a36Sopenharmony_ci	int index;
39262306a36Sopenharmony_ci	unsigned char *info;
39362306a36Sopenharmony_ci};
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_cistruct ring_info {
39662306a36Sopenharmony_ci	struct sk_buff	*skb;
39762306a36Sopenharmony_ci	dma_addr_t	mapping;
39862306a36Sopenharmony_ci};
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_cistruct tulip_private {
40262306a36Sopenharmony_ci	const char *product_name;
40362306a36Sopenharmony_ci	struct net_device *next_module;
40462306a36Sopenharmony_ci	struct tulip_rx_desc *rx_ring;
40562306a36Sopenharmony_ci	struct tulip_tx_desc *tx_ring;
40662306a36Sopenharmony_ci	dma_addr_t rx_ring_dma;
40762306a36Sopenharmony_ci	dma_addr_t tx_ring_dma;
40862306a36Sopenharmony_ci	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
40962306a36Sopenharmony_ci	struct ring_info tx_buffers[TX_RING_SIZE];
41062306a36Sopenharmony_ci	/* The addresses of receive-in-place skbuffs. */
41162306a36Sopenharmony_ci	struct ring_info rx_buffers[RX_RING_SIZE];
41262306a36Sopenharmony_ci	u16 setup_frame[96];	/* Pseudo-Tx frame to init address table. */
41362306a36Sopenharmony_ci	int chip_id;
41462306a36Sopenharmony_ci	int revision;
41562306a36Sopenharmony_ci	int flags;
41662306a36Sopenharmony_ci	struct napi_struct napi;
41762306a36Sopenharmony_ci	struct timer_list timer;	/* Media selection timer. */
41862306a36Sopenharmony_ci	struct timer_list oom_timer;    /* Out of memory timer. */
41962306a36Sopenharmony_ci	u32 mc_filter[2];
42062306a36Sopenharmony_ci	spinlock_t lock;
42162306a36Sopenharmony_ci	spinlock_t mii_lock;
42262306a36Sopenharmony_ci	unsigned int cur_rx, cur_tx;	/* The next free ring entry */
42362306a36Sopenharmony_ci	unsigned int dirty_rx, dirty_tx;	/* The ring entries to be free()ed. */
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_ci#ifdef 	CONFIG_TULIP_NAPI_HW_MITIGATION
42662306a36Sopenharmony_ci        int mit_on;
42762306a36Sopenharmony_ci#endif
42862306a36Sopenharmony_ci	unsigned int full_duplex:1;	/* Full-duplex operation requested. */
42962306a36Sopenharmony_ci	unsigned int full_duplex_lock:1;
43062306a36Sopenharmony_ci	unsigned int fake_addr:1;	/* Multiport board faked address. */
43162306a36Sopenharmony_ci	unsigned int default_port:4;	/* Last dev->if_port value. */
43262306a36Sopenharmony_ci	unsigned int media2:4;	/* Secondary monitored media port. */
43362306a36Sopenharmony_ci	unsigned int medialock:1;	/* Don't sense media type. */
43462306a36Sopenharmony_ci	unsigned int mediasense:1;	/* Media sensing in progress. */
43562306a36Sopenharmony_ci	unsigned int nway:1, nwayset:1;		/* 21143 internal NWay. */
43662306a36Sopenharmony_ci	unsigned int timeout_recovery:1;
43762306a36Sopenharmony_ci	unsigned int csr0;	/* CSR0 setting. */
43862306a36Sopenharmony_ci	unsigned int csr6;	/* Current CSR6 control settings. */
43962306a36Sopenharmony_ci	unsigned char eeprom[EEPROM_SIZE];	/* Serial EEPROM contents. */
44062306a36Sopenharmony_ci	void (*link_change) (struct net_device * dev, int csr5);
44162306a36Sopenharmony_ci        struct ethtool_wolinfo wolinfo;        /* WOL settings */
44262306a36Sopenharmony_ci	u16 sym_advertise, mii_advertise; /* NWay capabilities advertised.  */
44362306a36Sopenharmony_ci	u16 lpar;		/* 21143 Link partner ability. */
44462306a36Sopenharmony_ci	u16 advertising[4];
44562306a36Sopenharmony_ci	signed char phys[4], mii_cnt;	/* MII device addresses. */
44662306a36Sopenharmony_ci	struct mediatable *mtable;
44762306a36Sopenharmony_ci	int cur_index;		/* Current media index. */
44862306a36Sopenharmony_ci	int saved_if_port;
44962306a36Sopenharmony_ci	struct pci_dev *pdev;
45062306a36Sopenharmony_ci	int ttimer;
45162306a36Sopenharmony_ci	int susp_rx;
45262306a36Sopenharmony_ci	unsigned long nir;
45362306a36Sopenharmony_ci	void __iomem *base_addr;
45462306a36Sopenharmony_ci	int csr12_shadow;
45562306a36Sopenharmony_ci	int pad0;		/* Used for 8-byte alignment */
45662306a36Sopenharmony_ci	struct work_struct media_work;
45762306a36Sopenharmony_ci	struct net_device *dev;
45862306a36Sopenharmony_ci};
45962306a36Sopenharmony_ci
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_cistruct eeprom_fixup {
46262306a36Sopenharmony_ci	char *name;
46362306a36Sopenharmony_ci	unsigned char addr0;
46462306a36Sopenharmony_ci	unsigned char addr1;
46562306a36Sopenharmony_ci	unsigned char addr2;
46662306a36Sopenharmony_ci	u16 newtable[32];	/* Max length below. */
46762306a36Sopenharmony_ci};
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci
47062306a36Sopenharmony_ci/* 21142.c */
47162306a36Sopenharmony_ciextern u16 t21142_csr14[];
47262306a36Sopenharmony_civoid t21142_media_task(struct work_struct *work);
47362306a36Sopenharmony_civoid t21142_start_nway(struct net_device *dev);
47462306a36Sopenharmony_civoid t21142_lnk_change(struct net_device *dev, int csr5);
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_ci
47762306a36Sopenharmony_ci/* PNIC2.c */
47862306a36Sopenharmony_civoid pnic2_lnk_change(struct net_device *dev, int csr5);
47962306a36Sopenharmony_civoid pnic2_timer(struct timer_list *t);
48062306a36Sopenharmony_civoid pnic2_start_nway(struct net_device *dev);
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ci/* eeprom.c */
48362306a36Sopenharmony_civoid tulip_parse_eeprom(struct net_device *dev);
48462306a36Sopenharmony_ciint tulip_read_eeprom(struct net_device *dev, int location, int addr_len);
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci/* interrupt.c */
48762306a36Sopenharmony_ciextern unsigned int tulip_max_interrupt_work;
48862306a36Sopenharmony_ciextern int tulip_rx_copybreak;
48962306a36Sopenharmony_ciirqreturn_t tulip_interrupt(int irq, void *dev_instance);
49062306a36Sopenharmony_ciint tulip_refill_rx(struct net_device *dev);
49162306a36Sopenharmony_ci#ifdef CONFIG_TULIP_NAPI
49262306a36Sopenharmony_ciint tulip_poll(struct napi_struct *napi, int budget);
49362306a36Sopenharmony_ci#endif
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci
49662306a36Sopenharmony_ci/* media.c */
49762306a36Sopenharmony_ciint tulip_mdio_read(struct net_device *dev, int phy_id, int location);
49862306a36Sopenharmony_civoid tulip_mdio_write(struct net_device *dev, int phy_id, int location, int value);
49962306a36Sopenharmony_civoid tulip_select_media(struct net_device *dev, int startup);
50062306a36Sopenharmony_ciint tulip_check_duplex(struct net_device *dev);
50162306a36Sopenharmony_civoid tulip_find_mii (struct net_device *dev, int board_idx);
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_ci/* pnic.c */
50462306a36Sopenharmony_civoid pnic_do_nway(struct net_device *dev);
50562306a36Sopenharmony_civoid pnic_lnk_change(struct net_device *dev, int csr5);
50662306a36Sopenharmony_civoid pnic_timer(struct timer_list *t);
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ci/* timer.c */
50962306a36Sopenharmony_civoid tulip_media_task(struct work_struct *work);
51062306a36Sopenharmony_civoid mxic_timer(struct timer_list *t);
51162306a36Sopenharmony_civoid comet_timer(struct timer_list *t);
51262306a36Sopenharmony_ci
51362306a36Sopenharmony_ci/* tulip_core.c */
51462306a36Sopenharmony_ciextern int tulip_debug;
51562306a36Sopenharmony_ciextern const char * const medianame[];
51662306a36Sopenharmony_ciextern const char tulip_media_cap[];
51762306a36Sopenharmony_ciextern const struct tulip_chip_table tulip_tbl[];
51862306a36Sopenharmony_civoid oom_timer(struct timer_list *t);
51962306a36Sopenharmony_ciextern u8 t21040_csr13[];
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_cistatic inline void tulip_start_rxtx(struct tulip_private *tp)
52262306a36Sopenharmony_ci{
52362306a36Sopenharmony_ci	void __iomem *ioaddr = tp->base_addr;
52462306a36Sopenharmony_ci	iowrite32(tp->csr6 | RxTx, ioaddr + CSR6);
52562306a36Sopenharmony_ci	barrier();
52662306a36Sopenharmony_ci	(void) ioread32(ioaddr + CSR6); /* mmio sync */
52762306a36Sopenharmony_ci}
52862306a36Sopenharmony_ci
52962306a36Sopenharmony_cistatic inline void tulip_stop_rxtx(struct tulip_private *tp)
53062306a36Sopenharmony_ci{
53162306a36Sopenharmony_ci	void __iomem *ioaddr = tp->base_addr;
53262306a36Sopenharmony_ci	u32 csr6 = ioread32(ioaddr + CSR6);
53362306a36Sopenharmony_ci
53462306a36Sopenharmony_ci	if (csr6 & RxTx) {
53562306a36Sopenharmony_ci		unsigned i=1300/10;
53662306a36Sopenharmony_ci		iowrite32(csr6 & ~RxTx, ioaddr + CSR6);
53762306a36Sopenharmony_ci		barrier();
53862306a36Sopenharmony_ci		/* wait until in-flight frame completes.
53962306a36Sopenharmony_ci		 * Max time @ 10BT: 1500*8b/10Mbps == 1200us (+ 100us margin)
54062306a36Sopenharmony_ci		 * Typically expect this loop to end in < 50 us on 100BT.
54162306a36Sopenharmony_ci		 */
54262306a36Sopenharmony_ci		while (--i && (ioread32(ioaddr + CSR5) & (CSR5_TS|CSR5_RS)))
54362306a36Sopenharmony_ci			udelay(10);
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ci		if (!i)
54662306a36Sopenharmony_ci			netdev_dbg(tp->dev, "tulip_stop_rxtx() failed (CSR5 0x%x CSR6 0x%x)\n",
54762306a36Sopenharmony_ci				   ioread32(ioaddr + CSR5),
54862306a36Sopenharmony_ci				   ioread32(ioaddr + CSR6));
54962306a36Sopenharmony_ci	}
55062306a36Sopenharmony_ci}
55162306a36Sopenharmony_ci
55262306a36Sopenharmony_cistatic inline void tulip_restart_rxtx(struct tulip_private *tp)
55362306a36Sopenharmony_ci{
55462306a36Sopenharmony_ci	tulip_stop_rxtx(tp);
55562306a36Sopenharmony_ci	udelay(5);
55662306a36Sopenharmony_ci	tulip_start_rxtx(tp);
55762306a36Sopenharmony_ci}
55862306a36Sopenharmony_ci
55962306a36Sopenharmony_cistatic inline void tulip_tx_timeout_complete(struct tulip_private *tp, void __iomem *ioaddr)
56062306a36Sopenharmony_ci{
56162306a36Sopenharmony_ci	/* Stop and restart the chip's Tx processes. */
56262306a36Sopenharmony_ci	tulip_restart_rxtx(tp);
56362306a36Sopenharmony_ci	/* Trigger an immediate transmit demand. */
56462306a36Sopenharmony_ci	iowrite32(0, ioaddr + CSR1);
56562306a36Sopenharmony_ci
56662306a36Sopenharmony_ci	tp->dev->stats.tx_errors++;
56762306a36Sopenharmony_ci}
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_ci#endif /* __NET_TULIP_H__ */
570