18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci drivers/net/ethernet/dec/tulip/tulip.h 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci Copyright 2000,2001 The Linux Kernel Team 58c2ecf20Sopenharmony_ci Written/copyright 1994-2001 by Donald Becker. 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci This software may be used and distributed according to the terms 88c2ecf20Sopenharmony_ci of the GNU General Public License, incorporated herein by reference. 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci Please submit bugs to http://bugzilla.kernel.org/ . 118c2ecf20Sopenharmony_ci*/ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#ifndef __NET_TULIP_H__ 148c2ecf20Sopenharmony_ci#define __NET_TULIP_H__ 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#include <linux/kernel.h> 178c2ecf20Sopenharmony_ci#include <linux/types.h> 188c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 198c2ecf20Sopenharmony_ci#include <linux/netdevice.h> 208c2ecf20Sopenharmony_ci#include <linux/ethtool.h> 218c2ecf20Sopenharmony_ci#include <linux/timer.h> 228c2ecf20Sopenharmony_ci#include <linux/delay.h> 238c2ecf20Sopenharmony_ci#include <linux/pci.h> 248c2ecf20Sopenharmony_ci#include <asm/io.h> 258c2ecf20Sopenharmony_ci#include <asm/irq.h> 268c2ecf20Sopenharmony_ci#include <asm/unaligned.h> 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci/* undefine, or define to various debugging levels (>4 == obscene levels) */ 318c2ecf20Sopenharmony_ci#define TULIP_DEBUG 1 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#ifdef CONFIG_TULIP_MMIO 348c2ecf20Sopenharmony_ci#define TULIP_BAR 1 /* CBMA */ 358c2ecf20Sopenharmony_ci#else 368c2ecf20Sopenharmony_ci#define TULIP_BAR 0 /* CBIO */ 378c2ecf20Sopenharmony_ci#endif 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cistruct tulip_chip_table { 428c2ecf20Sopenharmony_ci char *chip_name; 438c2ecf20Sopenharmony_ci int io_size; 448c2ecf20Sopenharmony_ci int valid_intrs; /* CSR7 interrupt enable settings */ 458c2ecf20Sopenharmony_ci int flags; 468c2ecf20Sopenharmony_ci void (*media_timer) (struct timer_list *); 478c2ecf20Sopenharmony_ci work_func_t media_task; 488c2ecf20Sopenharmony_ci}; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cienum tbl_flag { 528c2ecf20Sopenharmony_ci HAS_MII = 0x00001, 538c2ecf20Sopenharmony_ci HAS_MEDIA_TABLE = 0x00002, 548c2ecf20Sopenharmony_ci CSR12_IN_SROM = 0x00004, 558c2ecf20Sopenharmony_ci ALWAYS_CHECK_MII = 0x00008, 568c2ecf20Sopenharmony_ci HAS_ACPI = 0x00010, 578c2ecf20Sopenharmony_ci MC_HASH_ONLY = 0x00020, /* Hash-only multicast filter. */ 588c2ecf20Sopenharmony_ci HAS_PNICNWAY = 0x00080, 598c2ecf20Sopenharmony_ci HAS_NWAY = 0x00040, /* Uses internal NWay xcvr. */ 608c2ecf20Sopenharmony_ci HAS_INTR_MITIGATION = 0x00100, 618c2ecf20Sopenharmony_ci IS_ASIX = 0x00200, 628c2ecf20Sopenharmony_ci HAS_8023X = 0x00400, 638c2ecf20Sopenharmony_ci COMET_MAC_ADDR = 0x00800, 648c2ecf20Sopenharmony_ci HAS_PCI_MWI = 0x01000, 658c2ecf20Sopenharmony_ci HAS_PHY_IRQ = 0x02000, 668c2ecf20Sopenharmony_ci HAS_SWAPPED_SEEPROM = 0x04000, 678c2ecf20Sopenharmony_ci NEEDS_FAKE_MEDIA_TABLE = 0x08000, 688c2ecf20Sopenharmony_ci COMET_PM = 0x10000, 698c2ecf20Sopenharmony_ci}; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci/* chip types. careful! order is VERY IMPORTANT here, as these 738c2ecf20Sopenharmony_ci * are used throughout the driver as indices into arrays */ 748c2ecf20Sopenharmony_ci/* Note 21142 == 21143. */ 758c2ecf20Sopenharmony_cienum chips { 768c2ecf20Sopenharmony_ci DC21040 = 0, 778c2ecf20Sopenharmony_ci DC21041 = 1, 788c2ecf20Sopenharmony_ci DC21140 = 2, 798c2ecf20Sopenharmony_ci DC21142 = 3, DC21143 = 3, 808c2ecf20Sopenharmony_ci LC82C168, 818c2ecf20Sopenharmony_ci MX98713, 828c2ecf20Sopenharmony_ci MX98715, 838c2ecf20Sopenharmony_ci MX98725, 848c2ecf20Sopenharmony_ci AX88140, 858c2ecf20Sopenharmony_ci PNIC2, 868c2ecf20Sopenharmony_ci COMET, 878c2ecf20Sopenharmony_ci COMPEX9881, 888c2ecf20Sopenharmony_ci I21145, 898c2ecf20Sopenharmony_ci DM910X, 908c2ecf20Sopenharmony_ci CONEXANT, 918c2ecf20Sopenharmony_ci}; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_cienum MediaIs { 958c2ecf20Sopenharmony_ci MediaIsFD = 1, 968c2ecf20Sopenharmony_ci MediaAlwaysFD = 2, 978c2ecf20Sopenharmony_ci MediaIsMII = 4, 988c2ecf20Sopenharmony_ci MediaIsFx = 8, 998c2ecf20Sopenharmony_ci MediaIs100 = 16 1008c2ecf20Sopenharmony_ci}; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci/* Offsets to the Command and Status Registers, "CSRs". All accesses 1048c2ecf20Sopenharmony_ci must be longword instructions and quadword aligned. */ 1058c2ecf20Sopenharmony_cienum tulip_offsets { 1068c2ecf20Sopenharmony_ci CSR0 = 0, 1078c2ecf20Sopenharmony_ci CSR1 = 0x08, 1088c2ecf20Sopenharmony_ci CSR2 = 0x10, 1098c2ecf20Sopenharmony_ci CSR3 = 0x18, 1108c2ecf20Sopenharmony_ci CSR4 = 0x20, 1118c2ecf20Sopenharmony_ci CSR5 = 0x28, 1128c2ecf20Sopenharmony_ci CSR6 = 0x30, 1138c2ecf20Sopenharmony_ci CSR7 = 0x38, 1148c2ecf20Sopenharmony_ci CSR8 = 0x40, 1158c2ecf20Sopenharmony_ci CSR9 = 0x48, 1168c2ecf20Sopenharmony_ci CSR10 = 0x50, 1178c2ecf20Sopenharmony_ci CSR11 = 0x58, 1188c2ecf20Sopenharmony_ci CSR12 = 0x60, 1198c2ecf20Sopenharmony_ci CSR13 = 0x68, 1208c2ecf20Sopenharmony_ci CSR14 = 0x70, 1218c2ecf20Sopenharmony_ci CSR15 = 0x78, 1228c2ecf20Sopenharmony_ci CSR18 = 0x88, 1238c2ecf20Sopenharmony_ci CSR19 = 0x8c, 1248c2ecf20Sopenharmony_ci CSR20 = 0x90, 1258c2ecf20Sopenharmony_ci CSR27 = 0xAC, 1268c2ecf20Sopenharmony_ci CSR28 = 0xB0, 1278c2ecf20Sopenharmony_ci}; 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci/* register offset and bits for CFDD PCI config reg */ 1308c2ecf20Sopenharmony_cienum pci_cfg_driver_reg { 1318c2ecf20Sopenharmony_ci CFDD = 0x40, 1328c2ecf20Sopenharmony_ci CFDD_Sleep = (1 << 31), 1338c2ecf20Sopenharmony_ci CFDD_Snooze = (1 << 30), 1348c2ecf20Sopenharmony_ci}; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci#define RxPollInt (RxIntr|RxNoBuf|RxDied|RxJabber) 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci/* The bits in the CSR5 status registers, mostly interrupt sources. */ 1398c2ecf20Sopenharmony_cienum status_bits { 1408c2ecf20Sopenharmony_ci TimerInt = 0x800, 1418c2ecf20Sopenharmony_ci SystemError = 0x2000, 1428c2ecf20Sopenharmony_ci TPLnkFail = 0x1000, 1438c2ecf20Sopenharmony_ci TPLnkPass = 0x10, 1448c2ecf20Sopenharmony_ci NormalIntr = 0x10000, 1458c2ecf20Sopenharmony_ci AbnormalIntr = 0x8000, 1468c2ecf20Sopenharmony_ci RxJabber = 0x200, 1478c2ecf20Sopenharmony_ci RxDied = 0x100, 1488c2ecf20Sopenharmony_ci RxNoBuf = 0x80, 1498c2ecf20Sopenharmony_ci RxIntr = 0x40, 1508c2ecf20Sopenharmony_ci TxFIFOUnderflow = 0x20, 1518c2ecf20Sopenharmony_ci RxErrIntr = 0x10, 1528c2ecf20Sopenharmony_ci TxJabber = 0x08, 1538c2ecf20Sopenharmony_ci TxNoBuf = 0x04, 1548c2ecf20Sopenharmony_ci TxDied = 0x02, 1558c2ecf20Sopenharmony_ci TxIntr = 0x01, 1568c2ecf20Sopenharmony_ci}; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci/* bit mask for CSR5 TX/RX process state */ 1598c2ecf20Sopenharmony_ci#define CSR5_TS 0x00700000 1608c2ecf20Sopenharmony_ci#define CSR5_RS 0x000e0000 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_cienum tulip_mode_bits { 1638c2ecf20Sopenharmony_ci TxThreshold = (1 << 22), 1648c2ecf20Sopenharmony_ci FullDuplex = (1 << 9), 1658c2ecf20Sopenharmony_ci TxOn = 0x2000, 1668c2ecf20Sopenharmony_ci AcceptBroadcast = 0x0100, 1678c2ecf20Sopenharmony_ci AcceptAllMulticast = 0x0080, 1688c2ecf20Sopenharmony_ci AcceptAllPhys = 0x0040, 1698c2ecf20Sopenharmony_ci AcceptRunt = 0x0008, 1708c2ecf20Sopenharmony_ci RxOn = 0x0002, 1718c2ecf20Sopenharmony_ci RxTx = (TxOn | RxOn), 1728c2ecf20Sopenharmony_ci}; 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_cienum tulip_busconfig_bits { 1768c2ecf20Sopenharmony_ci MWI = (1 << 24), 1778c2ecf20Sopenharmony_ci MRL = (1 << 23), 1788c2ecf20Sopenharmony_ci MRM = (1 << 21), 1798c2ecf20Sopenharmony_ci CALShift = 14, 1808c2ecf20Sopenharmony_ci BurstLenShift = 8, 1818c2ecf20Sopenharmony_ci}; 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci/* The Tulip Rx and Tx buffer descriptors. */ 1858c2ecf20Sopenharmony_cistruct tulip_rx_desc { 1868c2ecf20Sopenharmony_ci __le32 status; 1878c2ecf20Sopenharmony_ci __le32 length; 1888c2ecf20Sopenharmony_ci __le32 buffer1; 1898c2ecf20Sopenharmony_ci __le32 buffer2; 1908c2ecf20Sopenharmony_ci}; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_cistruct tulip_tx_desc { 1948c2ecf20Sopenharmony_ci __le32 status; 1958c2ecf20Sopenharmony_ci __le32 length; 1968c2ecf20Sopenharmony_ci __le32 buffer1; 1978c2ecf20Sopenharmony_ci __le32 buffer2; /* We use only buffer 1. */ 1988c2ecf20Sopenharmony_ci}; 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_cienum desc_status_bits { 2028c2ecf20Sopenharmony_ci DescOwned = 0x80000000, 2038c2ecf20Sopenharmony_ci DescWholePkt = 0x60000000, 2048c2ecf20Sopenharmony_ci DescEndPkt = 0x40000000, 2058c2ecf20Sopenharmony_ci DescStartPkt = 0x20000000, 2068c2ecf20Sopenharmony_ci DescEndRing = 0x02000000, 2078c2ecf20Sopenharmony_ci DescUseLink = 0x01000000, 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci /* 2108c2ecf20Sopenharmony_ci * Error summary flag is logical or of 'CRC Error', 'Collision Seen', 2118c2ecf20Sopenharmony_ci * 'Frame Too Long', 'Runt' and 'Descriptor Error' flags generated 2128c2ecf20Sopenharmony_ci * within tulip chip. 2138c2ecf20Sopenharmony_ci */ 2148c2ecf20Sopenharmony_ci RxDescErrorSummary = 0x8000, 2158c2ecf20Sopenharmony_ci RxDescCRCError = 0x0002, 2168c2ecf20Sopenharmony_ci RxDescCollisionSeen = 0x0040, 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci /* 2198c2ecf20Sopenharmony_ci * 'Frame Too Long' flag is set if packet length including CRC exceeds 2208c2ecf20Sopenharmony_ci * 1518. However, a full sized VLAN tagged frame is 1522 bytes 2218c2ecf20Sopenharmony_ci * including CRC. 2228c2ecf20Sopenharmony_ci * 2238c2ecf20Sopenharmony_ci * The tulip chip does not block oversized frames, and if this flag is 2248c2ecf20Sopenharmony_ci * set on a receive descriptor it does not indicate the frame has been 2258c2ecf20Sopenharmony_ci * truncated. The receive descriptor also includes the actual length. 2268c2ecf20Sopenharmony_ci * Therefore we can safety ignore this flag and check the length 2278c2ecf20Sopenharmony_ci * ourselves. 2288c2ecf20Sopenharmony_ci */ 2298c2ecf20Sopenharmony_ci RxDescFrameTooLong = 0x0080, 2308c2ecf20Sopenharmony_ci RxDescRunt = 0x0800, 2318c2ecf20Sopenharmony_ci RxDescDescErr = 0x4000, 2328c2ecf20Sopenharmony_ci RxWholePkt = 0x00000300, 2338c2ecf20Sopenharmony_ci /* 2348c2ecf20Sopenharmony_ci * Top three bits of 14 bit frame length (status bits 27-29) should 2358c2ecf20Sopenharmony_ci * never be set as that would make frame over 2047 bytes. The Receive 2368c2ecf20Sopenharmony_ci * Watchdog flag (bit 4) may indicate the length is over 2048 and the 2378c2ecf20Sopenharmony_ci * length field is invalid. 2388c2ecf20Sopenharmony_ci */ 2398c2ecf20Sopenharmony_ci RxLengthOver2047 = 0x38000010 2408c2ecf20Sopenharmony_ci}; 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_cienum t21143_csr6_bits { 2448c2ecf20Sopenharmony_ci csr6_sc = (1<<31), 2458c2ecf20Sopenharmony_ci csr6_ra = (1<<30), 2468c2ecf20Sopenharmony_ci csr6_ign_dest_msb = (1<<26), 2478c2ecf20Sopenharmony_ci csr6_mbo = (1<<25), 2488c2ecf20Sopenharmony_ci csr6_scr = (1<<24), /* scramble mode flag: can't be set */ 2498c2ecf20Sopenharmony_ci csr6_pcs = (1<<23), /* Enables PCS functions (symbol mode requires csr6_ps be set) default is set */ 2508c2ecf20Sopenharmony_ci csr6_ttm = (1<<22), /* Transmit Threshold Mode, set for 10baseT, 0 for 100BaseTX */ 2518c2ecf20Sopenharmony_ci csr6_sf = (1<<21), /* Store and forward. If set ignores TR bits */ 2528c2ecf20Sopenharmony_ci csr6_hbd = (1<<19), /* Heart beat disable. Disables SQE function in 10baseT */ 2538c2ecf20Sopenharmony_ci csr6_ps = (1<<18), /* Port Select. 0 (defualt) = 10baseT, 1 = 100baseTX: can't be set */ 2548c2ecf20Sopenharmony_ci csr6_ca = (1<<17), /* Collision Offset Enable. If set uses special algorithm in low collision situations */ 2558c2ecf20Sopenharmony_ci csr6_trh = (1<<15), /* Transmit Threshold high bit */ 2568c2ecf20Sopenharmony_ci csr6_trl = (1<<14), /* Transmit Threshold low bit */ 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci /*************************************************************** 2598c2ecf20Sopenharmony_ci * This table shows transmit threshold values based on media * 2608c2ecf20Sopenharmony_ci * and these two registers (from PNIC1 & 2 docs) Note: this is * 2618c2ecf20Sopenharmony_ci * all meaningless if sf is set. * 2628c2ecf20Sopenharmony_ci ***************************************************************/ 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci /*********************************** 2658c2ecf20Sopenharmony_ci * (trh,trl) * 100BaseTX * 10BaseT * 2668c2ecf20Sopenharmony_ci *********************************** 2678c2ecf20Sopenharmony_ci * (0,0) * 128 * 72 * 2688c2ecf20Sopenharmony_ci * (0,1) * 256 * 96 * 2698c2ecf20Sopenharmony_ci * (1,0) * 512 * 128 * 2708c2ecf20Sopenharmony_ci * (1,1) * 1024 * 160 * 2718c2ecf20Sopenharmony_ci ***********************************/ 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci csr6_fc = (1<<12), /* Forces a collision in next transmission (for testing in loopback mode) */ 2748c2ecf20Sopenharmony_ci csr6_om_int_loop = (1<<10), /* internal (FIFO) loopback flag */ 2758c2ecf20Sopenharmony_ci csr6_om_ext_loop = (1<<11), /* external (PMD) loopback flag */ 2768c2ecf20Sopenharmony_ci /* set both and you get (PHY) loopback */ 2778c2ecf20Sopenharmony_ci csr6_fd = (1<<9), /* Full duplex mode, disables hearbeat, no loopback */ 2788c2ecf20Sopenharmony_ci csr6_pm = (1<<7), /* Pass All Multicast */ 2798c2ecf20Sopenharmony_ci csr6_pr = (1<<6), /* Promiscuous mode */ 2808c2ecf20Sopenharmony_ci csr6_sb = (1<<5), /* Start(1)/Stop(0) backoff counter */ 2818c2ecf20Sopenharmony_ci csr6_if = (1<<4), /* Inverse Filtering, rejects only addresses in address table: can't be set */ 2828c2ecf20Sopenharmony_ci csr6_pb = (1<<3), /* Pass Bad Frames, (1) causes even bad frames to be passed on */ 2838c2ecf20Sopenharmony_ci csr6_ho = (1<<2), /* Hash-only filtering mode: can't be set */ 2848c2ecf20Sopenharmony_ci csr6_hp = (1<<0), /* Hash/Perfect Receive Filtering Mode: can't be set */ 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci csr6_mask_capture = (csr6_sc | csr6_ca), 2878c2ecf20Sopenharmony_ci csr6_mask_defstate = (csr6_mask_capture | csr6_mbo), 2888c2ecf20Sopenharmony_ci csr6_mask_hdcap = (csr6_mask_defstate | csr6_hbd | csr6_ps), 2898c2ecf20Sopenharmony_ci csr6_mask_hdcaptt = (csr6_mask_hdcap | csr6_trh | csr6_trl), 2908c2ecf20Sopenharmony_ci csr6_mask_fullcap = (csr6_mask_hdcaptt | csr6_fd), 2918c2ecf20Sopenharmony_ci csr6_mask_fullpromisc = (csr6_pr | csr6_pm), 2928c2ecf20Sopenharmony_ci csr6_mask_filters = (csr6_hp | csr6_ho | csr6_if), 2938c2ecf20Sopenharmony_ci csr6_mask_100bt = (csr6_scr | csr6_pcs | csr6_hbd), 2948c2ecf20Sopenharmony_ci}; 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_cienum tulip_comet_csr13_bits { 2978c2ecf20Sopenharmony_ci/* The LINKOFFE and LINKONE work in conjunction with LSCE, i.e. they 2988c2ecf20Sopenharmony_ci * determine which link status transition wakes up if LSCE is 2998c2ecf20Sopenharmony_ci * enabled */ 3008c2ecf20Sopenharmony_ci comet_csr13_linkoffe = (1 << 17), 3018c2ecf20Sopenharmony_ci comet_csr13_linkone = (1 << 16), 3028c2ecf20Sopenharmony_ci comet_csr13_wfre = (1 << 10), 3038c2ecf20Sopenharmony_ci comet_csr13_mpre = (1 << 9), 3048c2ecf20Sopenharmony_ci comet_csr13_lsce = (1 << 8), 3058c2ecf20Sopenharmony_ci comet_csr13_wfr = (1 << 2), 3068c2ecf20Sopenharmony_ci comet_csr13_mpr = (1 << 1), 3078c2ecf20Sopenharmony_ci comet_csr13_lsc = (1 << 0), 3088c2ecf20Sopenharmony_ci}; 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_cienum tulip_comet_csr18_bits { 3118c2ecf20Sopenharmony_ci comet_csr18_pmes_sticky = (1 << 24), 3128c2ecf20Sopenharmony_ci comet_csr18_pm_mode = (1 << 19), 3138c2ecf20Sopenharmony_ci comet_csr18_apm_mode = (1 << 18), 3148c2ecf20Sopenharmony_ci comet_csr18_d3a = (1 << 7) 3158c2ecf20Sopenharmony_ci}; 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_cienum tulip_comet_csr20_bits { 3188c2ecf20Sopenharmony_ci comet_csr20_pmes = (1 << 15), 3198c2ecf20Sopenharmony_ci}; 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci/* Keep the ring sizes a power of two for efficiency. 3228c2ecf20Sopenharmony_ci Making the Tx ring too large decreases the effectiveness of channel 3238c2ecf20Sopenharmony_ci bonding and packet priority. 3248c2ecf20Sopenharmony_ci There are no ill effects from too-large receive rings. */ 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci#define TX_RING_SIZE 32 3278c2ecf20Sopenharmony_ci#define RX_RING_SIZE 128 3288c2ecf20Sopenharmony_ci#define MEDIA_MASK 31 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci/* The receiver on the DC21143 rev 65 can fail to close the last 3318c2ecf20Sopenharmony_ci * receive descriptor in certain circumstances (see errata) when 3328c2ecf20Sopenharmony_ci * using MWI. This can only occur if the receive buffer ends on 3338c2ecf20Sopenharmony_ci * a cache line boundary, so the "+ 4" below ensures it doesn't. 3348c2ecf20Sopenharmony_ci */ 3358c2ecf20Sopenharmony_ci#define PKT_BUF_SZ (1536 + 4) /* Size of each temporary Rx buffer. */ 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci#define TULIP_MIN_CACHE_LINE 8 /* in units of 32-bit words */ 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci#if defined(__sparc__) || defined(__hppa__) 3408c2ecf20Sopenharmony_ci/* The UltraSparc PCI controllers will disconnect at every 64-byte 3418c2ecf20Sopenharmony_ci * crossing anyways so it makes no sense to tell Tulip to burst 3428c2ecf20Sopenharmony_ci * any more than that. 3438c2ecf20Sopenharmony_ci */ 3448c2ecf20Sopenharmony_ci#define TULIP_MAX_CACHE_LINE 16 /* in units of 32-bit words */ 3458c2ecf20Sopenharmony_ci#else 3468c2ecf20Sopenharmony_ci#define TULIP_MAX_CACHE_LINE 32 /* in units of 32-bit words */ 3478c2ecf20Sopenharmony_ci#endif 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci/* Ring-wrap flag in length field, use for last ring entry. 3518c2ecf20Sopenharmony_ci 0x01000000 means chain on buffer2 address, 3528c2ecf20Sopenharmony_ci 0x02000000 means use the ring start address in CSR2/3. 3538c2ecf20Sopenharmony_ci Note: Some work-alike chips do not function correctly in chained mode. 3548c2ecf20Sopenharmony_ci The ASIX chip works only in chained mode. 3558c2ecf20Sopenharmony_ci Thus we indicates ring mode, but always write the 'next' field for 3568c2ecf20Sopenharmony_ci chained mode as well. 3578c2ecf20Sopenharmony_ci*/ 3588c2ecf20Sopenharmony_ci#define DESC_RING_WRAP 0x02000000 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci#define EEPROM_SIZE 512 /* 2 << EEPROM_ADDRLEN */ 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_ci#define RUN_AT(x) (jiffies + (x)) 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci#define get_u16(ptr) get_unaligned_le16((ptr)) 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_cistruct medialeaf { 3698c2ecf20Sopenharmony_ci u8 type; 3708c2ecf20Sopenharmony_ci u8 media; 3718c2ecf20Sopenharmony_ci unsigned char *leafdata; 3728c2ecf20Sopenharmony_ci}; 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_cistruct mediatable { 3768c2ecf20Sopenharmony_ci u16 defaultmedia; 3778c2ecf20Sopenharmony_ci u8 leafcount; 3788c2ecf20Sopenharmony_ci u8 csr12dir; /* General purpose pin directions. */ 3798c2ecf20Sopenharmony_ci unsigned has_mii:1; 3808c2ecf20Sopenharmony_ci unsigned has_nonmii:1; 3818c2ecf20Sopenharmony_ci unsigned has_reset:6; 3828c2ecf20Sopenharmony_ci u32 csr15dir; 3838c2ecf20Sopenharmony_ci u32 csr15val; /* 21143 NWay setting. */ 3848c2ecf20Sopenharmony_ci struct medialeaf mleaf[]; 3858c2ecf20Sopenharmony_ci}; 3868c2ecf20Sopenharmony_ci 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_cistruct mediainfo { 3898c2ecf20Sopenharmony_ci struct mediainfo *next; 3908c2ecf20Sopenharmony_ci int info_type; 3918c2ecf20Sopenharmony_ci int index; 3928c2ecf20Sopenharmony_ci unsigned char *info; 3938c2ecf20Sopenharmony_ci}; 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_cistruct ring_info { 3968c2ecf20Sopenharmony_ci struct sk_buff *skb; 3978c2ecf20Sopenharmony_ci dma_addr_t mapping; 3988c2ecf20Sopenharmony_ci}; 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_cistruct tulip_private { 4028c2ecf20Sopenharmony_ci const char *product_name; 4038c2ecf20Sopenharmony_ci struct net_device *next_module; 4048c2ecf20Sopenharmony_ci struct tulip_rx_desc *rx_ring; 4058c2ecf20Sopenharmony_ci struct tulip_tx_desc *tx_ring; 4068c2ecf20Sopenharmony_ci dma_addr_t rx_ring_dma; 4078c2ecf20Sopenharmony_ci dma_addr_t tx_ring_dma; 4088c2ecf20Sopenharmony_ci /* The saved address of a sent-in-place packet/buffer, for skfree(). */ 4098c2ecf20Sopenharmony_ci struct ring_info tx_buffers[TX_RING_SIZE]; 4108c2ecf20Sopenharmony_ci /* The addresses of receive-in-place skbuffs. */ 4118c2ecf20Sopenharmony_ci struct ring_info rx_buffers[RX_RING_SIZE]; 4128c2ecf20Sopenharmony_ci u16 setup_frame[96]; /* Pseudo-Tx frame to init address table. */ 4138c2ecf20Sopenharmony_ci int chip_id; 4148c2ecf20Sopenharmony_ci int revision; 4158c2ecf20Sopenharmony_ci int flags; 4168c2ecf20Sopenharmony_ci struct napi_struct napi; 4178c2ecf20Sopenharmony_ci struct timer_list timer; /* Media selection timer. */ 4188c2ecf20Sopenharmony_ci struct timer_list oom_timer; /* Out of memory timer. */ 4198c2ecf20Sopenharmony_ci u32 mc_filter[2]; 4208c2ecf20Sopenharmony_ci spinlock_t lock; 4218c2ecf20Sopenharmony_ci spinlock_t mii_lock; 4228c2ecf20Sopenharmony_ci unsigned int cur_rx, cur_tx; /* The next free ring entry */ 4238c2ecf20Sopenharmony_ci unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_ci#ifdef CONFIG_TULIP_NAPI_HW_MITIGATION 4268c2ecf20Sopenharmony_ci int mit_on; 4278c2ecf20Sopenharmony_ci#endif 4288c2ecf20Sopenharmony_ci unsigned int full_duplex:1; /* Full-duplex operation requested. */ 4298c2ecf20Sopenharmony_ci unsigned int full_duplex_lock:1; 4308c2ecf20Sopenharmony_ci unsigned int fake_addr:1; /* Multiport board faked address. */ 4318c2ecf20Sopenharmony_ci unsigned int default_port:4; /* Last dev->if_port value. */ 4328c2ecf20Sopenharmony_ci unsigned int media2:4; /* Secondary monitored media port. */ 4338c2ecf20Sopenharmony_ci unsigned int medialock:1; /* Don't sense media type. */ 4348c2ecf20Sopenharmony_ci unsigned int mediasense:1; /* Media sensing in progress. */ 4358c2ecf20Sopenharmony_ci unsigned int nway:1, nwayset:1; /* 21143 internal NWay. */ 4368c2ecf20Sopenharmony_ci unsigned int timeout_recovery:1; 4378c2ecf20Sopenharmony_ci unsigned int csr0; /* CSR0 setting. */ 4388c2ecf20Sopenharmony_ci unsigned int csr6; /* Current CSR6 control settings. */ 4398c2ecf20Sopenharmony_ci unsigned char eeprom[EEPROM_SIZE]; /* Serial EEPROM contents. */ 4408c2ecf20Sopenharmony_ci void (*link_change) (struct net_device * dev, int csr5); 4418c2ecf20Sopenharmony_ci struct ethtool_wolinfo wolinfo; /* WOL settings */ 4428c2ecf20Sopenharmony_ci u16 sym_advertise, mii_advertise; /* NWay capabilities advertised. */ 4438c2ecf20Sopenharmony_ci u16 lpar; /* 21143 Link partner ability. */ 4448c2ecf20Sopenharmony_ci u16 advertising[4]; 4458c2ecf20Sopenharmony_ci signed char phys[4], mii_cnt; /* MII device addresses. */ 4468c2ecf20Sopenharmony_ci struct mediatable *mtable; 4478c2ecf20Sopenharmony_ci int cur_index; /* Current media index. */ 4488c2ecf20Sopenharmony_ci int saved_if_port; 4498c2ecf20Sopenharmony_ci struct pci_dev *pdev; 4508c2ecf20Sopenharmony_ci int ttimer; 4518c2ecf20Sopenharmony_ci int susp_rx; 4528c2ecf20Sopenharmony_ci unsigned long nir; 4538c2ecf20Sopenharmony_ci void __iomem *base_addr; 4548c2ecf20Sopenharmony_ci int csr12_shadow; 4558c2ecf20Sopenharmony_ci int pad0; /* Used for 8-byte alignment */ 4568c2ecf20Sopenharmony_ci struct work_struct media_work; 4578c2ecf20Sopenharmony_ci struct net_device *dev; 4588c2ecf20Sopenharmony_ci}; 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_ci 4618c2ecf20Sopenharmony_cistruct eeprom_fixup { 4628c2ecf20Sopenharmony_ci char *name; 4638c2ecf20Sopenharmony_ci unsigned char addr0; 4648c2ecf20Sopenharmony_ci unsigned char addr1; 4658c2ecf20Sopenharmony_ci unsigned char addr2; 4668c2ecf20Sopenharmony_ci u16 newtable[32]; /* Max length below. */ 4678c2ecf20Sopenharmony_ci}; 4688c2ecf20Sopenharmony_ci 4698c2ecf20Sopenharmony_ci 4708c2ecf20Sopenharmony_ci/* 21142.c */ 4718c2ecf20Sopenharmony_ciextern u16 t21142_csr14[]; 4728c2ecf20Sopenharmony_civoid t21142_media_task(struct work_struct *work); 4738c2ecf20Sopenharmony_civoid t21142_start_nway(struct net_device *dev); 4748c2ecf20Sopenharmony_civoid t21142_lnk_change(struct net_device *dev, int csr5); 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci 4778c2ecf20Sopenharmony_ci/* PNIC2.c */ 4788c2ecf20Sopenharmony_civoid pnic2_lnk_change(struct net_device *dev, int csr5); 4798c2ecf20Sopenharmony_civoid pnic2_timer(struct timer_list *t); 4808c2ecf20Sopenharmony_civoid pnic2_start_nway(struct net_device *dev); 4818c2ecf20Sopenharmony_civoid pnic2_lnk_change(struct net_device *dev, int csr5); 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_ci/* eeprom.c */ 4848c2ecf20Sopenharmony_civoid tulip_parse_eeprom(struct net_device *dev); 4858c2ecf20Sopenharmony_ciint tulip_read_eeprom(struct net_device *dev, int location, int addr_len); 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_ci/* interrupt.c */ 4888c2ecf20Sopenharmony_ciextern unsigned int tulip_max_interrupt_work; 4898c2ecf20Sopenharmony_ciextern int tulip_rx_copybreak; 4908c2ecf20Sopenharmony_ciirqreturn_t tulip_interrupt(int irq, void *dev_instance); 4918c2ecf20Sopenharmony_ciint tulip_refill_rx(struct net_device *dev); 4928c2ecf20Sopenharmony_ci#ifdef CONFIG_TULIP_NAPI 4938c2ecf20Sopenharmony_ciint tulip_poll(struct napi_struct *napi, int budget); 4948c2ecf20Sopenharmony_ci#endif 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_ci/* media.c */ 4988c2ecf20Sopenharmony_ciint tulip_mdio_read(struct net_device *dev, int phy_id, int location); 4998c2ecf20Sopenharmony_civoid tulip_mdio_write(struct net_device *dev, int phy_id, int location, int value); 5008c2ecf20Sopenharmony_civoid tulip_select_media(struct net_device *dev, int startup); 5018c2ecf20Sopenharmony_ciint tulip_check_duplex(struct net_device *dev); 5028c2ecf20Sopenharmony_civoid tulip_find_mii (struct net_device *dev, int board_idx); 5038c2ecf20Sopenharmony_ci 5048c2ecf20Sopenharmony_ci/* pnic.c */ 5058c2ecf20Sopenharmony_civoid pnic_do_nway(struct net_device *dev); 5068c2ecf20Sopenharmony_civoid pnic_lnk_change(struct net_device *dev, int csr5); 5078c2ecf20Sopenharmony_civoid pnic_timer(struct timer_list *t); 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_ci/* timer.c */ 5108c2ecf20Sopenharmony_civoid tulip_media_task(struct work_struct *work); 5118c2ecf20Sopenharmony_civoid mxic_timer(struct timer_list *t); 5128c2ecf20Sopenharmony_civoid comet_timer(struct timer_list *t); 5138c2ecf20Sopenharmony_ci 5148c2ecf20Sopenharmony_ci/* tulip_core.c */ 5158c2ecf20Sopenharmony_ciextern int tulip_debug; 5168c2ecf20Sopenharmony_ciextern const char * const medianame[]; 5178c2ecf20Sopenharmony_ciextern const char tulip_media_cap[]; 5188c2ecf20Sopenharmony_ciextern const struct tulip_chip_table tulip_tbl[]; 5198c2ecf20Sopenharmony_civoid oom_timer(struct timer_list *t); 5208c2ecf20Sopenharmony_ciextern u8 t21040_csr13[]; 5218c2ecf20Sopenharmony_ci 5228c2ecf20Sopenharmony_cistatic inline void tulip_start_rxtx(struct tulip_private *tp) 5238c2ecf20Sopenharmony_ci{ 5248c2ecf20Sopenharmony_ci void __iomem *ioaddr = tp->base_addr; 5258c2ecf20Sopenharmony_ci iowrite32(tp->csr6 | RxTx, ioaddr + CSR6); 5268c2ecf20Sopenharmony_ci barrier(); 5278c2ecf20Sopenharmony_ci (void) ioread32(ioaddr + CSR6); /* mmio sync */ 5288c2ecf20Sopenharmony_ci} 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_cistatic inline void tulip_stop_rxtx(struct tulip_private *tp) 5318c2ecf20Sopenharmony_ci{ 5328c2ecf20Sopenharmony_ci void __iomem *ioaddr = tp->base_addr; 5338c2ecf20Sopenharmony_ci u32 csr6 = ioread32(ioaddr + CSR6); 5348c2ecf20Sopenharmony_ci 5358c2ecf20Sopenharmony_ci if (csr6 & RxTx) { 5368c2ecf20Sopenharmony_ci unsigned i=1300/10; 5378c2ecf20Sopenharmony_ci iowrite32(csr6 & ~RxTx, ioaddr + CSR6); 5388c2ecf20Sopenharmony_ci barrier(); 5398c2ecf20Sopenharmony_ci /* wait until in-flight frame completes. 5408c2ecf20Sopenharmony_ci * Max time @ 10BT: 1500*8b/10Mbps == 1200us (+ 100us margin) 5418c2ecf20Sopenharmony_ci * Typically expect this loop to end in < 50 us on 100BT. 5428c2ecf20Sopenharmony_ci */ 5438c2ecf20Sopenharmony_ci while (--i && (ioread32(ioaddr + CSR5) & (CSR5_TS|CSR5_RS))) 5448c2ecf20Sopenharmony_ci udelay(10); 5458c2ecf20Sopenharmony_ci 5468c2ecf20Sopenharmony_ci if (!i) 5478c2ecf20Sopenharmony_ci netdev_dbg(tp->dev, "tulip_stop_rxtx() failed (CSR5 0x%x CSR6 0x%x)\n", 5488c2ecf20Sopenharmony_ci ioread32(ioaddr + CSR5), 5498c2ecf20Sopenharmony_ci ioread32(ioaddr + CSR6)); 5508c2ecf20Sopenharmony_ci } 5518c2ecf20Sopenharmony_ci} 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_cistatic inline void tulip_restart_rxtx(struct tulip_private *tp) 5548c2ecf20Sopenharmony_ci{ 5558c2ecf20Sopenharmony_ci tulip_stop_rxtx(tp); 5568c2ecf20Sopenharmony_ci udelay(5); 5578c2ecf20Sopenharmony_ci tulip_start_rxtx(tp); 5588c2ecf20Sopenharmony_ci} 5598c2ecf20Sopenharmony_ci 5608c2ecf20Sopenharmony_cistatic inline void tulip_tx_timeout_complete(struct tulip_private *tp, void __iomem *ioaddr) 5618c2ecf20Sopenharmony_ci{ 5628c2ecf20Sopenharmony_ci /* Stop and restart the chip's Tx processes. */ 5638c2ecf20Sopenharmony_ci tulip_restart_rxtx(tp); 5648c2ecf20Sopenharmony_ci /* Trigger an immediate transmit demand. */ 5658c2ecf20Sopenharmony_ci iowrite32(0, ioaddr + CSR1); 5668c2ecf20Sopenharmony_ci 5678c2ecf20Sopenharmony_ci tp->dev->stats.tx_errors++; 5688c2ecf20Sopenharmony_ci} 5698c2ecf20Sopenharmony_ci 5708c2ecf20Sopenharmony_ci#endif /* __NET_TULIP_H__ */ 571