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