1c1b6a3d8SThomas Bogendoerfer // SPDX-License-Identifier: GPL-2.0 2c1b6a3d8SThomas Bogendoerfer /* Driver for SGI's IOC3 based Ethernet cards as found in the PCI card. 38862bf1eSJeff Kirsher * 48862bf1eSJeff Kirsher * Copyright (C) 1999, 2000, 01, 03, 06 Ralf Baechle 58862bf1eSJeff Kirsher * Copyright (C) 1995, 1999, 2000, 2001 by Silicon Graphics, Inc. 68862bf1eSJeff Kirsher * 78862bf1eSJeff Kirsher * References: 88862bf1eSJeff Kirsher * o IOC3 ASIC specification 4.51, 1996-04-18 98862bf1eSJeff Kirsher * o IEEE 802.3 specification, 2000 edition 108862bf1eSJeff Kirsher * o DP38840A Specification, National Semiconductor, March 1997 118862bf1eSJeff Kirsher * 128862bf1eSJeff Kirsher * To do: 138862bf1eSJeff Kirsher * 148862bf1eSJeff Kirsher * o Handle allocation failures in ioc3_alloc_skb() more gracefully. 158862bf1eSJeff Kirsher * o Handle allocation failures in ioc3_init_rings(). 168862bf1eSJeff Kirsher * o Use prefetching for large packets. What is a good lower limit for 178862bf1eSJeff Kirsher * prefetching? 188862bf1eSJeff Kirsher * o We're probably allocating a bit too much memory. 198862bf1eSJeff Kirsher * o Use hardware checksums. 208862bf1eSJeff Kirsher * o Convert to using a IOC3 meta driver. 218862bf1eSJeff Kirsher * o Which PHYs might possibly be attached to the IOC3 in real live, 228862bf1eSJeff Kirsher * which workarounds are required for them? Do we ever have Lucent's? 238862bf1eSJeff Kirsher * o For the 2.5 branch kill the mii-tool ioctls. 248862bf1eSJeff Kirsher */ 258862bf1eSJeff Kirsher 268862bf1eSJeff Kirsher #define IOC3_NAME "ioc3-eth" 278862bf1eSJeff Kirsher #define IOC3_VERSION "2.6.3-4" 288862bf1eSJeff Kirsher 298862bf1eSJeff Kirsher #include <linux/delay.h> 308862bf1eSJeff Kirsher #include <linux/kernel.h> 318862bf1eSJeff Kirsher #include <linux/mm.h> 328862bf1eSJeff Kirsher #include <linux/errno.h> 338862bf1eSJeff Kirsher #include <linux/module.h> 348862bf1eSJeff Kirsher #include <linux/pci.h> 358862bf1eSJeff Kirsher #include <linux/crc32.h> 368862bf1eSJeff Kirsher #include <linux/mii.h> 378862bf1eSJeff Kirsher #include <linux/in.h> 38c1b6a3d8SThomas Bogendoerfer #include <linux/io.h> 398862bf1eSJeff Kirsher #include <linux/ip.h> 408862bf1eSJeff Kirsher #include <linux/tcp.h> 418862bf1eSJeff Kirsher #include <linux/udp.h> 428862bf1eSJeff Kirsher #include <linux/dma-mapping.h> 438862bf1eSJeff Kirsher #include <linux/gfp.h> 448862bf1eSJeff Kirsher 458862bf1eSJeff Kirsher #ifdef CONFIG_SERIAL_8250 468862bf1eSJeff Kirsher #include <linux/serial_core.h> 478862bf1eSJeff Kirsher #include <linux/serial_8250.h> 488862bf1eSJeff Kirsher #include <linux/serial_reg.h> 498862bf1eSJeff Kirsher #endif 508862bf1eSJeff Kirsher 518862bf1eSJeff Kirsher #include <linux/netdevice.h> 528862bf1eSJeff Kirsher #include <linux/etherdevice.h> 538862bf1eSJeff Kirsher #include <linux/ethtool.h> 548862bf1eSJeff Kirsher #include <linux/skbuff.h> 558862bf1eSJeff Kirsher #include <net/ip.h> 568862bf1eSJeff Kirsher 578862bf1eSJeff Kirsher #include <asm/byteorder.h> 588862bf1eSJeff Kirsher #include <asm/pgtable.h> 597c0f6ba6SLinus Torvalds #include <linux/uaccess.h> 608862bf1eSJeff Kirsher #include <asm/sn/types.h> 618862bf1eSJeff Kirsher #include <asm/sn/ioc3.h> 628862bf1eSJeff Kirsher #include <asm/pci/bridge.h> 638862bf1eSJeff Kirsher 64c1b6a3d8SThomas Bogendoerfer /* 64 RX buffers. This is tunable in the range of 16 <= x < 512. The 658862bf1eSJeff Kirsher * value must be a power of two. 668862bf1eSJeff Kirsher */ 678862bf1eSJeff Kirsher #define RX_BUFFS 64 688862bf1eSJeff Kirsher 698862bf1eSJeff Kirsher #define ETCSR_FD ((17 << ETCSR_IPGR2_SHIFT) | (11 << ETCSR_IPGR1_SHIFT) | 21) 708862bf1eSJeff Kirsher #define ETCSR_HD ((21 << ETCSR_IPGR2_SHIFT) | (21 << ETCSR_IPGR1_SHIFT) | 21) 718862bf1eSJeff Kirsher 728862bf1eSJeff Kirsher /* Private per NIC data of the driver. */ 738862bf1eSJeff Kirsher struct ioc3_private { 74cbe7d517SThomas Bogendoerfer struct ioc3_ethregs *regs; 75cbe7d517SThomas Bogendoerfer struct ioc3 *all_regs; 76cbe7d517SThomas Bogendoerfer u32 *ssram; 778862bf1eSJeff Kirsher unsigned long *rxr; /* pointer to receiver ring */ 788862bf1eSJeff Kirsher struct ioc3_etxd *txr; 798862bf1eSJeff Kirsher struct sk_buff *rx_skbs[512]; 808862bf1eSJeff Kirsher struct sk_buff *tx_skbs[128]; 818862bf1eSJeff Kirsher int rx_ci; /* RX consumer index */ 828862bf1eSJeff Kirsher int rx_pi; /* RX producer index */ 838862bf1eSJeff Kirsher int tx_ci; /* TX consumer index */ 848862bf1eSJeff Kirsher int tx_pi; /* TX producer index */ 858862bf1eSJeff Kirsher int txqlen; 868862bf1eSJeff Kirsher u32 emcr, ehar_h, ehar_l; 878862bf1eSJeff Kirsher spinlock_t ioc3_lock; 888862bf1eSJeff Kirsher struct mii_if_info mii; 898862bf1eSJeff Kirsher 90dfcc16c9SJason A. Donenfeld struct net_device *dev; 918862bf1eSJeff Kirsher struct pci_dev *pdev; 928862bf1eSJeff Kirsher 938862bf1eSJeff Kirsher /* Members used by autonegotiation */ 948862bf1eSJeff Kirsher struct timer_list ioc3_timer; 958862bf1eSJeff Kirsher }; 968862bf1eSJeff Kirsher 978862bf1eSJeff Kirsher static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); 988862bf1eSJeff Kirsher static void ioc3_set_multicast_list(struct net_device *dev); 9928d304efSYueHaibing static netdev_tx_t ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev); 1008862bf1eSJeff Kirsher static void ioc3_timeout(struct net_device *dev); 1018862bf1eSJeff Kirsher static inline unsigned int ioc3_hash(const unsigned char *addr); 1028862bf1eSJeff Kirsher static inline void ioc3_stop(struct ioc3_private *ip); 1038862bf1eSJeff Kirsher static void ioc3_init(struct net_device *dev); 1048862bf1eSJeff Kirsher 1058862bf1eSJeff Kirsher static const char ioc3_str[] = "IOC3 Ethernet"; 1068862bf1eSJeff Kirsher static const struct ethtool_ops ioc3_ethtool_ops; 1078862bf1eSJeff Kirsher 1088862bf1eSJeff Kirsher /* We use this to acquire receive skb's that we can DMA directly into. */ 1098862bf1eSJeff Kirsher 1108862bf1eSJeff Kirsher #define IOC3_CACHELINE 128UL 1118862bf1eSJeff Kirsher 1128862bf1eSJeff Kirsher static inline unsigned long aligned_rx_skb_addr(unsigned long addr) 1138862bf1eSJeff Kirsher { 1148862bf1eSJeff Kirsher return (~addr + 1) & (IOC3_CACHELINE - 1UL); 1158862bf1eSJeff Kirsher } 1168862bf1eSJeff Kirsher 1178862bf1eSJeff Kirsher static inline struct sk_buff *ioc3_alloc_skb(unsigned long length, 1188862bf1eSJeff Kirsher unsigned int gfp_mask) 1198862bf1eSJeff Kirsher { 1208862bf1eSJeff Kirsher struct sk_buff *skb; 1218862bf1eSJeff Kirsher 1228862bf1eSJeff Kirsher skb = alloc_skb(length + IOC3_CACHELINE - 1, gfp_mask); 1238862bf1eSJeff Kirsher if (likely(skb)) { 1248862bf1eSJeff Kirsher int offset = aligned_rx_skb_addr((unsigned long)skb->data); 125c1b6a3d8SThomas Bogendoerfer 1268862bf1eSJeff Kirsher if (offset) 1278862bf1eSJeff Kirsher skb_reserve(skb, offset); 1288862bf1eSJeff Kirsher } 1298862bf1eSJeff Kirsher 1308862bf1eSJeff Kirsher return skb; 1318862bf1eSJeff Kirsher } 1328862bf1eSJeff Kirsher 1338862bf1eSJeff Kirsher static inline unsigned long ioc3_map(void *ptr, unsigned long vdev) 1348862bf1eSJeff Kirsher { 1358862bf1eSJeff Kirsher #ifdef CONFIG_SGI_IP27 1368862bf1eSJeff Kirsher vdev <<= 57; /* Shift to PCI64_ATTR_VIRTUAL */ 1378862bf1eSJeff Kirsher 1388862bf1eSJeff Kirsher return vdev | (0xaUL << PCI64_ATTR_TARG_SHFT) | PCI64_ATTR_PREF | 1398862bf1eSJeff Kirsher ((unsigned long)ptr & TO_PHYS_MASK); 1408862bf1eSJeff Kirsher #else 1418862bf1eSJeff Kirsher return virt_to_bus(ptr); 1428862bf1eSJeff Kirsher #endif 1438862bf1eSJeff Kirsher } 1448862bf1eSJeff Kirsher 1458862bf1eSJeff Kirsher /* BEWARE: The IOC3 documentation documents the size of rx buffers as 146c1b6a3d8SThomas Bogendoerfer * 1644 while it's actually 1664. This one was nasty to track down ... 147c1b6a3d8SThomas Bogendoerfer */ 1488862bf1eSJeff Kirsher #define RX_OFFSET 10 1498862bf1eSJeff Kirsher #define RX_BUF_ALLOC_SIZE (1664 + RX_OFFSET + IOC3_CACHELINE) 1508862bf1eSJeff Kirsher 1518862bf1eSJeff Kirsher #define IOC3_SIZE 0x100000 1528862bf1eSJeff Kirsher 1538862bf1eSJeff Kirsher static inline u32 mcr_pack(u32 pulse, u32 sample) 1548862bf1eSJeff Kirsher { 1558862bf1eSJeff Kirsher return (pulse << 10) | (sample << 2); 1568862bf1eSJeff Kirsher } 1578862bf1eSJeff Kirsher 158cbe7d517SThomas Bogendoerfer static int nic_wait(u32 __iomem *mcr) 1598862bf1eSJeff Kirsher { 160cbe7d517SThomas Bogendoerfer u32 m; 1618862bf1eSJeff Kirsher 1628862bf1eSJeff Kirsher do { 163cbe7d517SThomas Bogendoerfer m = readl(mcr); 164cbe7d517SThomas Bogendoerfer } while (!(m & 2)); 1658862bf1eSJeff Kirsher 166cbe7d517SThomas Bogendoerfer return m & 1; 1678862bf1eSJeff Kirsher } 1688862bf1eSJeff Kirsher 169cbe7d517SThomas Bogendoerfer static int nic_reset(u32 __iomem *mcr) 1708862bf1eSJeff Kirsher { 1718862bf1eSJeff Kirsher int presence; 1728862bf1eSJeff Kirsher 173cbe7d517SThomas Bogendoerfer writel(mcr_pack(500, 65), mcr); 174cbe7d517SThomas Bogendoerfer presence = nic_wait(mcr); 1758862bf1eSJeff Kirsher 176cbe7d517SThomas Bogendoerfer writel(mcr_pack(0, 500), mcr); 177cbe7d517SThomas Bogendoerfer nic_wait(mcr); 1788862bf1eSJeff Kirsher 1798862bf1eSJeff Kirsher return presence; 1808862bf1eSJeff Kirsher } 1818862bf1eSJeff Kirsher 182cbe7d517SThomas Bogendoerfer static inline int nic_read_bit(u32 __iomem *mcr) 1838862bf1eSJeff Kirsher { 1848862bf1eSJeff Kirsher int result; 1858862bf1eSJeff Kirsher 186cbe7d517SThomas Bogendoerfer writel(mcr_pack(6, 13), mcr); 187cbe7d517SThomas Bogendoerfer result = nic_wait(mcr); 188cbe7d517SThomas Bogendoerfer writel(mcr_pack(0, 100), mcr); 189cbe7d517SThomas Bogendoerfer nic_wait(mcr); 1908862bf1eSJeff Kirsher 1918862bf1eSJeff Kirsher return result; 1928862bf1eSJeff Kirsher } 1938862bf1eSJeff Kirsher 194cbe7d517SThomas Bogendoerfer static inline void nic_write_bit(u32 __iomem *mcr, int bit) 1958862bf1eSJeff Kirsher { 1968862bf1eSJeff Kirsher if (bit) 197cbe7d517SThomas Bogendoerfer writel(mcr_pack(6, 110), mcr); 1988862bf1eSJeff Kirsher else 199cbe7d517SThomas Bogendoerfer writel(mcr_pack(80, 30), mcr); 2008862bf1eSJeff Kirsher 201cbe7d517SThomas Bogendoerfer nic_wait(mcr); 2028862bf1eSJeff Kirsher } 2038862bf1eSJeff Kirsher 204c1b6a3d8SThomas Bogendoerfer /* Read a byte from an iButton device 2058862bf1eSJeff Kirsher */ 206cbe7d517SThomas Bogendoerfer static u32 nic_read_byte(u32 __iomem *mcr) 2078862bf1eSJeff Kirsher { 2088862bf1eSJeff Kirsher u32 result = 0; 2098862bf1eSJeff Kirsher int i; 2108862bf1eSJeff Kirsher 2118862bf1eSJeff Kirsher for (i = 0; i < 8; i++) 212cbe7d517SThomas Bogendoerfer result = (result >> 1) | (nic_read_bit(mcr) << 7); 2138862bf1eSJeff Kirsher 2148862bf1eSJeff Kirsher return result; 2158862bf1eSJeff Kirsher } 2168862bf1eSJeff Kirsher 217c1b6a3d8SThomas Bogendoerfer /* Write a byte to an iButton device 2188862bf1eSJeff Kirsher */ 219cbe7d517SThomas Bogendoerfer static void nic_write_byte(u32 __iomem *mcr, int byte) 2208862bf1eSJeff Kirsher { 2218862bf1eSJeff Kirsher int i, bit; 2228862bf1eSJeff Kirsher 2238862bf1eSJeff Kirsher for (i = 8; i; i--) { 2248862bf1eSJeff Kirsher bit = byte & 1; 2258862bf1eSJeff Kirsher byte >>= 1; 2268862bf1eSJeff Kirsher 227cbe7d517SThomas Bogendoerfer nic_write_bit(mcr, bit); 2288862bf1eSJeff Kirsher } 2298862bf1eSJeff Kirsher } 2308862bf1eSJeff Kirsher 231cbe7d517SThomas Bogendoerfer static u64 nic_find(u32 __iomem *mcr, int *last) 2328862bf1eSJeff Kirsher { 2338862bf1eSJeff Kirsher int a, b, index, disc; 2348862bf1eSJeff Kirsher u64 address = 0; 2358862bf1eSJeff Kirsher 236cbe7d517SThomas Bogendoerfer nic_reset(mcr); 2378862bf1eSJeff Kirsher /* Search ROM. */ 238cbe7d517SThomas Bogendoerfer nic_write_byte(mcr, 0xf0); 2398862bf1eSJeff Kirsher 2408862bf1eSJeff Kirsher /* Algorithm from ``Book of iButton Standards''. */ 2418862bf1eSJeff Kirsher for (index = 0, disc = 0; index < 64; index++) { 242cbe7d517SThomas Bogendoerfer a = nic_read_bit(mcr); 243cbe7d517SThomas Bogendoerfer b = nic_read_bit(mcr); 2448862bf1eSJeff Kirsher 2458862bf1eSJeff Kirsher if (a && b) { 246c1b6a3d8SThomas Bogendoerfer pr_warn("NIC search failed (not fatal).\n"); 2478862bf1eSJeff Kirsher *last = 0; 2488862bf1eSJeff Kirsher return 0; 2498862bf1eSJeff Kirsher } 2508862bf1eSJeff Kirsher 2518862bf1eSJeff Kirsher if (!a && !b) { 2528862bf1eSJeff Kirsher if (index == *last) { 2538862bf1eSJeff Kirsher address |= 1UL << index; 2548862bf1eSJeff Kirsher } else if (index > *last) { 2558862bf1eSJeff Kirsher address &= ~(1UL << index); 2568862bf1eSJeff Kirsher disc = index; 257c1b6a3d8SThomas Bogendoerfer } else if ((address & (1UL << index)) == 0) { 2588862bf1eSJeff Kirsher disc = index; 259c1b6a3d8SThomas Bogendoerfer } 260cbe7d517SThomas Bogendoerfer nic_write_bit(mcr, address & (1UL << index)); 2618862bf1eSJeff Kirsher continue; 2628862bf1eSJeff Kirsher } else { 2638862bf1eSJeff Kirsher if (a) 2648862bf1eSJeff Kirsher address |= 1UL << index; 2658862bf1eSJeff Kirsher else 2668862bf1eSJeff Kirsher address &= ~(1UL << index); 267cbe7d517SThomas Bogendoerfer nic_write_bit(mcr, a); 2688862bf1eSJeff Kirsher continue; 2698862bf1eSJeff Kirsher } 2708862bf1eSJeff Kirsher } 2718862bf1eSJeff Kirsher 2728862bf1eSJeff Kirsher *last = disc; 2738862bf1eSJeff Kirsher 2748862bf1eSJeff Kirsher return address; 2758862bf1eSJeff Kirsher } 2768862bf1eSJeff Kirsher 277cbe7d517SThomas Bogendoerfer static int nic_init(u32 __iomem *mcr) 2788862bf1eSJeff Kirsher { 2798862bf1eSJeff Kirsher const char *unknown = "unknown"; 2808862bf1eSJeff Kirsher const char *type = unknown; 2818862bf1eSJeff Kirsher u8 crc; 2828862bf1eSJeff Kirsher u8 serial[6]; 2838862bf1eSJeff Kirsher int save = 0, i; 2848862bf1eSJeff Kirsher 2858862bf1eSJeff Kirsher while (1) { 2868862bf1eSJeff Kirsher u64 reg; 287c1b6a3d8SThomas Bogendoerfer 288cbe7d517SThomas Bogendoerfer reg = nic_find(mcr, &save); 2898862bf1eSJeff Kirsher 2908862bf1eSJeff Kirsher switch (reg & 0xff) { 2918862bf1eSJeff Kirsher case 0x91: 2928862bf1eSJeff Kirsher type = "DS1981U"; 2938862bf1eSJeff Kirsher break; 2948862bf1eSJeff Kirsher default: 2958862bf1eSJeff Kirsher if (save == 0) { 2968862bf1eSJeff Kirsher /* Let the caller try again. */ 2978862bf1eSJeff Kirsher return -1; 2988862bf1eSJeff Kirsher } 2998862bf1eSJeff Kirsher continue; 3008862bf1eSJeff Kirsher } 3018862bf1eSJeff Kirsher 302cbe7d517SThomas Bogendoerfer nic_reset(mcr); 3038862bf1eSJeff Kirsher 3048862bf1eSJeff Kirsher /* Match ROM. */ 305cbe7d517SThomas Bogendoerfer nic_write_byte(mcr, 0x55); 3068862bf1eSJeff Kirsher for (i = 0; i < 8; i++) 307cbe7d517SThomas Bogendoerfer nic_write_byte(mcr, (reg >> (i << 3)) & 0xff); 3088862bf1eSJeff Kirsher 3098862bf1eSJeff Kirsher reg >>= 8; /* Shift out type. */ 3108862bf1eSJeff Kirsher for (i = 0; i < 6; i++) { 3118862bf1eSJeff Kirsher serial[i] = reg & 0xff; 3128862bf1eSJeff Kirsher reg >>= 8; 3138862bf1eSJeff Kirsher } 3148862bf1eSJeff Kirsher crc = reg & 0xff; 3158862bf1eSJeff Kirsher break; 3168862bf1eSJeff Kirsher } 3178862bf1eSJeff Kirsher 318c1b6a3d8SThomas Bogendoerfer pr_info("Found %s NIC", type); 3198862bf1eSJeff Kirsher if (type != unknown) 320c1b6a3d8SThomas Bogendoerfer pr_cont(" registration number %pM, CRC %02x", serial, crc); 321c1b6a3d8SThomas Bogendoerfer pr_cont(".\n"); 3228862bf1eSJeff Kirsher 3238862bf1eSJeff Kirsher return 0; 3248862bf1eSJeff Kirsher } 3258862bf1eSJeff Kirsher 326c1b6a3d8SThomas Bogendoerfer /* Read the NIC (Number-In-a-Can) device used to store the MAC address on 3278862bf1eSJeff Kirsher * SN0 / SN00 nodeboards and PCI cards. 3288862bf1eSJeff Kirsher */ 3298862bf1eSJeff Kirsher static void ioc3_get_eaddr_nic(struct ioc3_private *ip) 3308862bf1eSJeff Kirsher { 331cbe7d517SThomas Bogendoerfer u32 __iomem *mcr = &ip->all_regs->mcr; 3328862bf1eSJeff Kirsher int tries = 2; /* There may be some problem with the battery? */ 333cbe7d517SThomas Bogendoerfer u8 nic[14]; 3348862bf1eSJeff Kirsher int i; 3358862bf1eSJeff Kirsher 336cbe7d517SThomas Bogendoerfer writel(1 << 21, &ip->all_regs->gpcr_s); 3378862bf1eSJeff Kirsher 3388862bf1eSJeff Kirsher while (tries--) { 339cbe7d517SThomas Bogendoerfer if (!nic_init(mcr)) 3408862bf1eSJeff Kirsher break; 3418862bf1eSJeff Kirsher udelay(500); 3428862bf1eSJeff Kirsher } 3438862bf1eSJeff Kirsher 3448862bf1eSJeff Kirsher if (tries < 0) { 345c1b6a3d8SThomas Bogendoerfer pr_err("Failed to read MAC address\n"); 3468862bf1eSJeff Kirsher return; 3478862bf1eSJeff Kirsher } 3488862bf1eSJeff Kirsher 3498862bf1eSJeff Kirsher /* Read Memory. */ 350cbe7d517SThomas Bogendoerfer nic_write_byte(mcr, 0xf0); 351cbe7d517SThomas Bogendoerfer nic_write_byte(mcr, 0x00); 352cbe7d517SThomas Bogendoerfer nic_write_byte(mcr, 0x00); 3538862bf1eSJeff Kirsher 3548862bf1eSJeff Kirsher for (i = 13; i >= 0; i--) 355cbe7d517SThomas Bogendoerfer nic[i] = nic_read_byte(mcr); 3568862bf1eSJeff Kirsher 3578862bf1eSJeff Kirsher for (i = 2; i < 8; i++) 358dfcc16c9SJason A. Donenfeld ip->dev->dev_addr[i - 2] = nic[i]; 3598862bf1eSJeff Kirsher } 3608862bf1eSJeff Kirsher 361c1b6a3d8SThomas Bogendoerfer /* Ok, this is hosed by design. It's necessary to know what machine the 3628862bf1eSJeff Kirsher * NIC is in in order to know how to read the NIC address. We also have 3638862bf1eSJeff Kirsher * to know if it's a PCI card or a NIC in on the node board ... 3648862bf1eSJeff Kirsher */ 3658862bf1eSJeff Kirsher static void ioc3_get_eaddr(struct ioc3_private *ip) 3668862bf1eSJeff Kirsher { 3678862bf1eSJeff Kirsher ioc3_get_eaddr_nic(ip); 3688862bf1eSJeff Kirsher 369c1b6a3d8SThomas Bogendoerfer pr_info("Ethernet address is %pM.\n", ip->dev->dev_addr); 3708862bf1eSJeff Kirsher } 3718862bf1eSJeff Kirsher 3728862bf1eSJeff Kirsher static void __ioc3_set_mac_address(struct net_device *dev) 3738862bf1eSJeff Kirsher { 3748862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 3758862bf1eSJeff Kirsher 376cbe7d517SThomas Bogendoerfer writel((dev->dev_addr[5] << 8) | 377cbe7d517SThomas Bogendoerfer dev->dev_addr[4], 378cbe7d517SThomas Bogendoerfer &ip->regs->emar_h); 379cbe7d517SThomas Bogendoerfer writel((dev->dev_addr[3] << 24) | 380cbe7d517SThomas Bogendoerfer (dev->dev_addr[2] << 16) | 381cbe7d517SThomas Bogendoerfer (dev->dev_addr[1] << 8) | 382cbe7d517SThomas Bogendoerfer dev->dev_addr[0], 383cbe7d517SThomas Bogendoerfer &ip->regs->emar_l); 3848862bf1eSJeff Kirsher } 3858862bf1eSJeff Kirsher 3868862bf1eSJeff Kirsher static int ioc3_set_mac_address(struct net_device *dev, void *addr) 3878862bf1eSJeff Kirsher { 3888862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 3898862bf1eSJeff Kirsher struct sockaddr *sa = addr; 3908862bf1eSJeff Kirsher 3918862bf1eSJeff Kirsher memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); 3928862bf1eSJeff Kirsher 3938862bf1eSJeff Kirsher spin_lock_irq(&ip->ioc3_lock); 3948862bf1eSJeff Kirsher __ioc3_set_mac_address(dev); 3958862bf1eSJeff Kirsher spin_unlock_irq(&ip->ioc3_lock); 3968862bf1eSJeff Kirsher 3978862bf1eSJeff Kirsher return 0; 3988862bf1eSJeff Kirsher } 3998862bf1eSJeff Kirsher 400c1b6a3d8SThomas Bogendoerfer /* Caller must hold the ioc3_lock ever for MII readers. This is also 4018862bf1eSJeff Kirsher * used to protect the transmitter side but it's low contention. 4028862bf1eSJeff Kirsher */ 4038862bf1eSJeff Kirsher static int ioc3_mdio_read(struct net_device *dev, int phy, int reg) 4048862bf1eSJeff Kirsher { 4058862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 406cbe7d517SThomas Bogendoerfer struct ioc3_ethregs *regs = ip->regs; 4078862bf1eSJeff Kirsher 408cbe7d517SThomas Bogendoerfer while (readl(®s->micr) & MICR_BUSY) 409cbe7d517SThomas Bogendoerfer ; 410cbe7d517SThomas Bogendoerfer writel((phy << MICR_PHYADDR_SHIFT) | reg | MICR_READTRIG, 411cbe7d517SThomas Bogendoerfer ®s->micr); 412cbe7d517SThomas Bogendoerfer while (readl(®s->micr) & MICR_BUSY) 413cbe7d517SThomas Bogendoerfer ; 4148862bf1eSJeff Kirsher 415cbe7d517SThomas Bogendoerfer return readl(®s->midr_r) & MIDR_DATA_MASK; 4168862bf1eSJeff Kirsher } 4178862bf1eSJeff Kirsher 4188862bf1eSJeff Kirsher static void ioc3_mdio_write(struct net_device *dev, int phy, int reg, int data) 4198862bf1eSJeff Kirsher { 4208862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 421cbe7d517SThomas Bogendoerfer struct ioc3_ethregs *regs = ip->regs; 4228862bf1eSJeff Kirsher 423cbe7d517SThomas Bogendoerfer while (readl(®s->micr) & MICR_BUSY) 424cbe7d517SThomas Bogendoerfer ; 425cbe7d517SThomas Bogendoerfer writel(data, ®s->midr_w); 426cbe7d517SThomas Bogendoerfer writel((phy << MICR_PHYADDR_SHIFT) | reg, ®s->micr); 427cbe7d517SThomas Bogendoerfer while (readl(®s->micr) & MICR_BUSY) 428cbe7d517SThomas Bogendoerfer ; 4298862bf1eSJeff Kirsher } 4308862bf1eSJeff Kirsher 4318862bf1eSJeff Kirsher static int ioc3_mii_init(struct ioc3_private *ip); 4328862bf1eSJeff Kirsher 4338862bf1eSJeff Kirsher static struct net_device_stats *ioc3_get_stats(struct net_device *dev) 4348862bf1eSJeff Kirsher { 4358862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 436cbe7d517SThomas Bogendoerfer struct ioc3_ethregs *regs = ip->regs; 4378862bf1eSJeff Kirsher 438cbe7d517SThomas Bogendoerfer dev->stats.collisions += readl(®s->etcdc) & ETCDC_COLLCNT_MASK; 4398862bf1eSJeff Kirsher return &dev->stats; 4408862bf1eSJeff Kirsher } 4418862bf1eSJeff Kirsher 442c1b6a3d8SThomas Bogendoerfer static void ioc3_tcpudp_checksum(struct sk_buff *skb, u32 hwsum, int len) 4438862bf1eSJeff Kirsher { 4448862bf1eSJeff Kirsher struct ethhdr *eh = eth_hdr(skb); 4458862bf1eSJeff Kirsher unsigned int proto; 4468862bf1eSJeff Kirsher unsigned char *cp; 447c1b6a3d8SThomas Bogendoerfer struct iphdr *ih; 448c1b6a3d8SThomas Bogendoerfer u32 csum, ehsum; 449c1b6a3d8SThomas Bogendoerfer u16 *ew; 4508862bf1eSJeff Kirsher 451c1b6a3d8SThomas Bogendoerfer /* Did hardware handle the checksum at all? The cases we can handle 4528862bf1eSJeff Kirsher * are: 4538862bf1eSJeff Kirsher * 4548862bf1eSJeff Kirsher * - TCP and UDP checksums of IPv4 only. 4558862bf1eSJeff Kirsher * - IPv6 would be doable but we keep that for later ... 4568862bf1eSJeff Kirsher * - Only unfragmented packets. Did somebody already tell you 4578862bf1eSJeff Kirsher * fragmentation is evil? 4588862bf1eSJeff Kirsher * - don't care about packet size. Worst case when processing a 4598862bf1eSJeff Kirsher * malformed packet we'll try to access the packet at ip header + 4608862bf1eSJeff Kirsher * 64 bytes which is still inside the skb. Even in the unlikely 4618862bf1eSJeff Kirsher * case where the checksum is right the higher layers will still 4628862bf1eSJeff Kirsher * drop the packet as appropriate. 4638862bf1eSJeff Kirsher */ 4648862bf1eSJeff Kirsher if (eh->h_proto != htons(ETH_P_IP)) 4658862bf1eSJeff Kirsher return; 4668862bf1eSJeff Kirsher 4678862bf1eSJeff Kirsher ih = (struct iphdr *)((char *)eh + ETH_HLEN); 4688862bf1eSJeff Kirsher if (ip_is_fragment(ih)) 4698862bf1eSJeff Kirsher return; 4708862bf1eSJeff Kirsher 4718862bf1eSJeff Kirsher proto = ih->protocol; 4728862bf1eSJeff Kirsher if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) 4738862bf1eSJeff Kirsher return; 4748862bf1eSJeff Kirsher 4758862bf1eSJeff Kirsher /* Same as tx - compute csum of pseudo header */ 4768862bf1eSJeff Kirsher csum = hwsum + 4778862bf1eSJeff Kirsher (ih->tot_len - (ih->ihl << 2)) + 478c1b6a3d8SThomas Bogendoerfer htons((u16)ih->protocol) + 4798862bf1eSJeff Kirsher (ih->saddr >> 16) + (ih->saddr & 0xffff) + 4808862bf1eSJeff Kirsher (ih->daddr >> 16) + (ih->daddr & 0xffff); 4818862bf1eSJeff Kirsher 4828862bf1eSJeff Kirsher /* Sum up ethernet dest addr, src addr and protocol */ 483c1b6a3d8SThomas Bogendoerfer ew = (u16 *)eh; 4848862bf1eSJeff Kirsher ehsum = ew[0] + ew[1] + ew[2] + ew[3] + ew[4] + ew[5] + ew[6]; 4858862bf1eSJeff Kirsher 4868862bf1eSJeff Kirsher ehsum = (ehsum & 0xffff) + (ehsum >> 16); 4878862bf1eSJeff Kirsher ehsum = (ehsum & 0xffff) + (ehsum >> 16); 4888862bf1eSJeff Kirsher 4898862bf1eSJeff Kirsher csum += 0xffff ^ ehsum; 4908862bf1eSJeff Kirsher 4918862bf1eSJeff Kirsher /* In the next step we also subtract the 1's complement 492c1b6a3d8SThomas Bogendoerfer * checksum of the trailing ethernet CRC. 493c1b6a3d8SThomas Bogendoerfer */ 4948862bf1eSJeff Kirsher cp = (char *)eh + len; /* points at trailing CRC */ 4958862bf1eSJeff Kirsher if (len & 1) { 496c1b6a3d8SThomas Bogendoerfer csum += 0xffff ^ (u16)((cp[1] << 8) | cp[0]); 497c1b6a3d8SThomas Bogendoerfer csum += 0xffff ^ (u16)((cp[3] << 8) | cp[2]); 4988862bf1eSJeff Kirsher } else { 499c1b6a3d8SThomas Bogendoerfer csum += 0xffff ^ (u16)((cp[0] << 8) | cp[1]); 500c1b6a3d8SThomas Bogendoerfer csum += 0xffff ^ (u16)((cp[2] << 8) | cp[3]); 5018862bf1eSJeff Kirsher } 5028862bf1eSJeff Kirsher 5038862bf1eSJeff Kirsher csum = (csum & 0xffff) + (csum >> 16); 5048862bf1eSJeff Kirsher csum = (csum & 0xffff) + (csum >> 16); 5058862bf1eSJeff Kirsher 5068862bf1eSJeff Kirsher if (csum == 0xffff) 5078862bf1eSJeff Kirsher skb->ip_summed = CHECKSUM_UNNECESSARY; 5088862bf1eSJeff Kirsher } 5098862bf1eSJeff Kirsher 5108862bf1eSJeff Kirsher static inline void ioc3_rx(struct net_device *dev) 5118862bf1eSJeff Kirsher { 5128862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 5138862bf1eSJeff Kirsher struct sk_buff *skb, *new_skb; 5148862bf1eSJeff Kirsher int rx_entry, n_entry, len; 5158862bf1eSJeff Kirsher struct ioc3_erxbuf *rxb; 5168862bf1eSJeff Kirsher unsigned long *rxr; 5178862bf1eSJeff Kirsher u32 w0, err; 5188862bf1eSJeff Kirsher 51964699336SJoe Perches rxr = ip->rxr; /* Ring base */ 5208862bf1eSJeff Kirsher rx_entry = ip->rx_ci; /* RX consume index */ 5218862bf1eSJeff Kirsher n_entry = ip->rx_pi; 5228862bf1eSJeff Kirsher 5238862bf1eSJeff Kirsher skb = ip->rx_skbs[rx_entry]; 5248862bf1eSJeff Kirsher rxb = (struct ioc3_erxbuf *)(skb->data - RX_OFFSET); 5258862bf1eSJeff Kirsher w0 = be32_to_cpu(rxb->w0); 5268862bf1eSJeff Kirsher 5278862bf1eSJeff Kirsher while (w0 & ERXBUF_V) { 5288862bf1eSJeff Kirsher err = be32_to_cpu(rxb->err); /* It's valid ... */ 5298862bf1eSJeff Kirsher if (err & ERXBUF_GOODPKT) { 5308862bf1eSJeff Kirsher len = ((w0 >> ERXBUF_BYTECNT_SHIFT) & 0x7ff) - 4; 5318862bf1eSJeff Kirsher skb_trim(skb, len); 5328862bf1eSJeff Kirsher skb->protocol = eth_type_trans(skb, dev); 5338862bf1eSJeff Kirsher 5348862bf1eSJeff Kirsher new_skb = ioc3_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_ATOMIC); 5358862bf1eSJeff Kirsher if (!new_skb) { 5368862bf1eSJeff Kirsher /* Ouch, drop packet and just recycle packet 537c1b6a3d8SThomas Bogendoerfer * to keep the ring filled. 538c1b6a3d8SThomas Bogendoerfer */ 5398862bf1eSJeff Kirsher dev->stats.rx_dropped++; 5408862bf1eSJeff Kirsher new_skb = skb; 5418862bf1eSJeff Kirsher goto next; 5428862bf1eSJeff Kirsher } 5438862bf1eSJeff Kirsher 5448862bf1eSJeff Kirsher if (likely(dev->features & NETIF_F_RXCSUM)) 5458862bf1eSJeff Kirsher ioc3_tcpudp_checksum(skb, 546c1b6a3d8SThomas Bogendoerfer w0 & ERXBUF_IPCKSUM_MASK, 547c1b6a3d8SThomas Bogendoerfer len); 5488862bf1eSJeff Kirsher 5498862bf1eSJeff Kirsher netif_rx(skb); 5508862bf1eSJeff Kirsher 5518862bf1eSJeff Kirsher ip->rx_skbs[rx_entry] = NULL; /* Poison */ 5528862bf1eSJeff Kirsher 5538862bf1eSJeff Kirsher /* Because we reserve afterwards. */ 5548862bf1eSJeff Kirsher skb_put(new_skb, (1664 + RX_OFFSET)); 5558862bf1eSJeff Kirsher rxb = (struct ioc3_erxbuf *)new_skb->data; 5568862bf1eSJeff Kirsher skb_reserve(new_skb, RX_OFFSET); 5578862bf1eSJeff Kirsher 5588862bf1eSJeff Kirsher dev->stats.rx_packets++; /* Statistics */ 5598862bf1eSJeff Kirsher dev->stats.rx_bytes += len; 5608862bf1eSJeff Kirsher } else { 5618862bf1eSJeff Kirsher /* The frame is invalid and the skb never 562c1b6a3d8SThomas Bogendoerfer * reached the network layer so we can just 563c1b6a3d8SThomas Bogendoerfer * recycle it. 564c1b6a3d8SThomas Bogendoerfer */ 5658862bf1eSJeff Kirsher new_skb = skb; 5668862bf1eSJeff Kirsher dev->stats.rx_errors++; 5678862bf1eSJeff Kirsher } 5688862bf1eSJeff Kirsher if (err & ERXBUF_CRCERR) /* Statistics */ 5698862bf1eSJeff Kirsher dev->stats.rx_crc_errors++; 5708862bf1eSJeff Kirsher if (err & ERXBUF_FRAMERR) 5718862bf1eSJeff Kirsher dev->stats.rx_frame_errors++; 5728862bf1eSJeff Kirsher next: 5738862bf1eSJeff Kirsher ip->rx_skbs[n_entry] = new_skb; 5748862bf1eSJeff Kirsher rxr[n_entry] = cpu_to_be64(ioc3_map(rxb, 1)); 5758862bf1eSJeff Kirsher rxb->w0 = 0; /* Clear valid flag */ 5768862bf1eSJeff Kirsher n_entry = (n_entry + 1) & 511; /* Update erpir */ 5778862bf1eSJeff Kirsher 5788862bf1eSJeff Kirsher /* Now go on to the next ring entry. */ 5798862bf1eSJeff Kirsher rx_entry = (rx_entry + 1) & 511; 5808862bf1eSJeff Kirsher skb = ip->rx_skbs[rx_entry]; 5818862bf1eSJeff Kirsher rxb = (struct ioc3_erxbuf *)(skb->data - RX_OFFSET); 5828862bf1eSJeff Kirsher w0 = be32_to_cpu(rxb->w0); 5838862bf1eSJeff Kirsher } 584cbe7d517SThomas Bogendoerfer writel((n_entry << 3) | ERPIR_ARM, &ip->regs->erpir); 5858862bf1eSJeff Kirsher ip->rx_pi = n_entry; 5868862bf1eSJeff Kirsher ip->rx_ci = rx_entry; 5878862bf1eSJeff Kirsher } 5888862bf1eSJeff Kirsher 5898862bf1eSJeff Kirsher static inline void ioc3_tx(struct net_device *dev) 5908862bf1eSJeff Kirsher { 5918862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 592cbe7d517SThomas Bogendoerfer struct ioc3_ethregs *regs = ip->regs; 5938862bf1eSJeff Kirsher unsigned long packets, bytes; 5948862bf1eSJeff Kirsher int tx_entry, o_entry; 5958862bf1eSJeff Kirsher struct sk_buff *skb; 5968862bf1eSJeff Kirsher u32 etcir; 5978862bf1eSJeff Kirsher 5988862bf1eSJeff Kirsher spin_lock(&ip->ioc3_lock); 599cbe7d517SThomas Bogendoerfer etcir = readl(®s->etcir); 6008862bf1eSJeff Kirsher 6018862bf1eSJeff Kirsher tx_entry = (etcir >> 7) & 127; 6028862bf1eSJeff Kirsher o_entry = ip->tx_ci; 6038862bf1eSJeff Kirsher packets = 0; 6048862bf1eSJeff Kirsher bytes = 0; 6058862bf1eSJeff Kirsher 6068862bf1eSJeff Kirsher while (o_entry != tx_entry) { 6078862bf1eSJeff Kirsher packets++; 6088862bf1eSJeff Kirsher skb = ip->tx_skbs[o_entry]; 6098862bf1eSJeff Kirsher bytes += skb->len; 610d1a096c2SYang Wei dev_consume_skb_irq(skb); 6118862bf1eSJeff Kirsher ip->tx_skbs[o_entry] = NULL; 6128862bf1eSJeff Kirsher 6138862bf1eSJeff Kirsher o_entry = (o_entry + 1) & 127; /* Next */ 6148862bf1eSJeff Kirsher 615cbe7d517SThomas Bogendoerfer etcir = readl(®s->etcir); /* More pkts sent? */ 6168862bf1eSJeff Kirsher tx_entry = (etcir >> 7) & 127; 6178862bf1eSJeff Kirsher } 6188862bf1eSJeff Kirsher 6198862bf1eSJeff Kirsher dev->stats.tx_packets += packets; 6208862bf1eSJeff Kirsher dev->stats.tx_bytes += bytes; 6218862bf1eSJeff Kirsher ip->txqlen -= packets; 6228862bf1eSJeff Kirsher 6238862bf1eSJeff Kirsher if (ip->txqlen < 128) 6248862bf1eSJeff Kirsher netif_wake_queue(dev); 6258862bf1eSJeff Kirsher 6268862bf1eSJeff Kirsher ip->tx_ci = o_entry; 6278862bf1eSJeff Kirsher spin_unlock(&ip->ioc3_lock); 6288862bf1eSJeff Kirsher } 6298862bf1eSJeff Kirsher 630c1b6a3d8SThomas Bogendoerfer /* Deal with fatal IOC3 errors. This condition might be caused by a hard or 6318862bf1eSJeff Kirsher * software problems, so we should try to recover 6328862bf1eSJeff Kirsher * more gracefully if this ever happens. In theory we might be flooded 6338862bf1eSJeff Kirsher * with such error interrupts if something really goes wrong, so we might 6348862bf1eSJeff Kirsher * also consider to take the interface down. 6358862bf1eSJeff Kirsher */ 6368862bf1eSJeff Kirsher static void ioc3_error(struct net_device *dev, u32 eisr) 6378862bf1eSJeff Kirsher { 6388862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 6398862bf1eSJeff Kirsher 6408862bf1eSJeff Kirsher spin_lock(&ip->ioc3_lock); 6418862bf1eSJeff Kirsher 6428862bf1eSJeff Kirsher if (eisr & EISR_RXOFLO) 643c1b6a3d8SThomas Bogendoerfer net_err_ratelimited("%s: RX overflow.\n", dev->name); 6448862bf1eSJeff Kirsher if (eisr & EISR_RXBUFOFLO) 645c1b6a3d8SThomas Bogendoerfer net_err_ratelimited("%s: RX buffer overflow.\n", dev->name); 6468862bf1eSJeff Kirsher if (eisr & EISR_RXMEMERR) 647c1b6a3d8SThomas Bogendoerfer net_err_ratelimited("%s: RX PCI error.\n", dev->name); 6488862bf1eSJeff Kirsher if (eisr & EISR_RXPARERR) 649c1b6a3d8SThomas Bogendoerfer net_err_ratelimited("%s: RX SSRAM parity error.\n", dev->name); 6508862bf1eSJeff Kirsher if (eisr & EISR_TXBUFUFLO) 651c1b6a3d8SThomas Bogendoerfer net_err_ratelimited("%s: TX buffer underflow.\n", dev->name); 6528862bf1eSJeff Kirsher if (eisr & EISR_TXMEMERR) 653c1b6a3d8SThomas Bogendoerfer net_err_ratelimited("%s: TX PCI error.\n", dev->name); 6548862bf1eSJeff Kirsher 6558862bf1eSJeff Kirsher ioc3_stop(ip); 6568862bf1eSJeff Kirsher ioc3_init(dev); 6578862bf1eSJeff Kirsher ioc3_mii_init(ip); 6588862bf1eSJeff Kirsher 6598862bf1eSJeff Kirsher netif_wake_queue(dev); 6608862bf1eSJeff Kirsher 6618862bf1eSJeff Kirsher spin_unlock(&ip->ioc3_lock); 6628862bf1eSJeff Kirsher } 6638862bf1eSJeff Kirsher 6648862bf1eSJeff Kirsher /* The interrupt handler does all of the Rx thread work and cleans up 665c1b6a3d8SThomas Bogendoerfer * after the Tx thread. 666c1b6a3d8SThomas Bogendoerfer */ 667cbe7d517SThomas Bogendoerfer static irqreturn_t ioc3_interrupt(int irq, void *dev_id) 6688862bf1eSJeff Kirsher { 669cbe7d517SThomas Bogendoerfer struct ioc3_private *ip = netdev_priv(dev_id); 670cbe7d517SThomas Bogendoerfer struct ioc3_ethregs *regs = ip->regs; 6718862bf1eSJeff Kirsher u32 eisr; 6728862bf1eSJeff Kirsher 673cbe7d517SThomas Bogendoerfer eisr = readl(®s->eisr); 674cbe7d517SThomas Bogendoerfer writel(eisr, ®s->eisr); 675cbe7d517SThomas Bogendoerfer readl(®s->eisr); /* Flush */ 6768862bf1eSJeff Kirsher 6778862bf1eSJeff Kirsher if (eisr & (EISR_RXOFLO | EISR_RXBUFOFLO | EISR_RXMEMERR | 6788862bf1eSJeff Kirsher EISR_RXPARERR | EISR_TXBUFUFLO | EISR_TXMEMERR)) 679cbe7d517SThomas Bogendoerfer ioc3_error(dev_id, eisr); 6808862bf1eSJeff Kirsher if (eisr & EISR_RXTIMERINT) 681cbe7d517SThomas Bogendoerfer ioc3_rx(dev_id); 6828862bf1eSJeff Kirsher if (eisr & EISR_TXEXPLICIT) 683cbe7d517SThomas Bogendoerfer ioc3_tx(dev_id); 6848862bf1eSJeff Kirsher 6858862bf1eSJeff Kirsher return IRQ_HANDLED; 6868862bf1eSJeff Kirsher } 6878862bf1eSJeff Kirsher 6888862bf1eSJeff Kirsher static inline void ioc3_setup_duplex(struct ioc3_private *ip) 6898862bf1eSJeff Kirsher { 690cbe7d517SThomas Bogendoerfer struct ioc3_ethregs *regs = ip->regs; 6918862bf1eSJeff Kirsher 6928862bf1eSJeff Kirsher if (ip->mii.full_duplex) { 693cbe7d517SThomas Bogendoerfer writel(ETCSR_FD, ®s->etcsr); 6948862bf1eSJeff Kirsher ip->emcr |= EMCR_DUPLEX; 6958862bf1eSJeff Kirsher } else { 696cbe7d517SThomas Bogendoerfer writel(ETCSR_HD, ®s->etcsr); 6978862bf1eSJeff Kirsher ip->emcr &= ~EMCR_DUPLEX; 6988862bf1eSJeff Kirsher } 699cbe7d517SThomas Bogendoerfer writel(ip->emcr, ®s->emcr); 7008862bf1eSJeff Kirsher } 7018862bf1eSJeff Kirsher 702dfc57004SKees Cook static void ioc3_timer(struct timer_list *t) 7038862bf1eSJeff Kirsher { 704dfc57004SKees Cook struct ioc3_private *ip = from_timer(ip, t, ioc3_timer); 7058862bf1eSJeff Kirsher 7068862bf1eSJeff Kirsher /* Print the link status if it has changed */ 7078862bf1eSJeff Kirsher mii_check_media(&ip->mii, 1, 0); 7088862bf1eSJeff Kirsher ioc3_setup_duplex(ip); 7098862bf1eSJeff Kirsher 7108862bf1eSJeff Kirsher ip->ioc3_timer.expires = jiffies + ((12 * HZ) / 10); /* 1.2s */ 7118862bf1eSJeff Kirsher add_timer(&ip->ioc3_timer); 7128862bf1eSJeff Kirsher } 7138862bf1eSJeff Kirsher 714c1b6a3d8SThomas Bogendoerfer /* Try to find a PHY. There is no apparent relation between the MII addresses 7158862bf1eSJeff Kirsher * in the SGI documentation and what we find in reality, so we simply probe 7168862bf1eSJeff Kirsher * for the PHY. It seems IOC3 PHYs usually live on address 31. One of my 7178862bf1eSJeff Kirsher * onboard IOC3s has the special oddity that probing doesn't seem to find it 7188862bf1eSJeff Kirsher * yet the interface seems to work fine, so if probing fails we for now will 7198862bf1eSJeff Kirsher * simply default to PHY 31 instead of bailing out. 7208862bf1eSJeff Kirsher */ 7218862bf1eSJeff Kirsher static int ioc3_mii_init(struct ioc3_private *ip) 7228862bf1eSJeff Kirsher { 7238862bf1eSJeff Kirsher int ioc3_phy_workaround = 1; 724c1b6a3d8SThomas Bogendoerfer int i, found = 0, res = 0; 7258862bf1eSJeff Kirsher u16 word; 7268862bf1eSJeff Kirsher 7278862bf1eSJeff Kirsher for (i = 0; i < 32; i++) { 728dfcc16c9SJason A. Donenfeld word = ioc3_mdio_read(ip->dev, i, MII_PHYSID1); 7298862bf1eSJeff Kirsher 7308862bf1eSJeff Kirsher if (word != 0xffff && word != 0x0000) { 7318862bf1eSJeff Kirsher found = 1; 7328862bf1eSJeff Kirsher break; /* Found a PHY */ 7338862bf1eSJeff Kirsher } 7348862bf1eSJeff Kirsher } 7358862bf1eSJeff Kirsher 7368862bf1eSJeff Kirsher if (!found) { 737c1b6a3d8SThomas Bogendoerfer if (ioc3_phy_workaround) { 7388862bf1eSJeff Kirsher i = 31; 739c1b6a3d8SThomas Bogendoerfer } else { 7408862bf1eSJeff Kirsher ip->mii.phy_id = -1; 7418862bf1eSJeff Kirsher res = -ENODEV; 7428862bf1eSJeff Kirsher goto out; 7438862bf1eSJeff Kirsher } 7448862bf1eSJeff Kirsher } 7458862bf1eSJeff Kirsher 7468862bf1eSJeff Kirsher ip->mii.phy_id = i; 7478862bf1eSJeff Kirsher 7488862bf1eSJeff Kirsher out: 7498862bf1eSJeff Kirsher return res; 7508862bf1eSJeff Kirsher } 7518862bf1eSJeff Kirsher 7528862bf1eSJeff Kirsher static void ioc3_mii_start(struct ioc3_private *ip) 7538862bf1eSJeff Kirsher { 7548862bf1eSJeff Kirsher ip->ioc3_timer.expires = jiffies + (12 * HZ) / 10; /* 1.2 sec. */ 7558862bf1eSJeff Kirsher add_timer(&ip->ioc3_timer); 7568862bf1eSJeff Kirsher } 7578862bf1eSJeff Kirsher 7588862bf1eSJeff Kirsher static inline void ioc3_clean_rx_ring(struct ioc3_private *ip) 7598862bf1eSJeff Kirsher { 760c1b6a3d8SThomas Bogendoerfer struct ioc3_erxbuf *rxb; 7618862bf1eSJeff Kirsher struct sk_buff *skb; 7628862bf1eSJeff Kirsher int i; 7638862bf1eSJeff Kirsher 7648862bf1eSJeff Kirsher for (i = ip->rx_ci; i & 15; i++) { 7658862bf1eSJeff Kirsher ip->rx_skbs[ip->rx_pi] = ip->rx_skbs[ip->rx_ci]; 7668862bf1eSJeff Kirsher ip->rxr[ip->rx_pi++] = ip->rxr[ip->rx_ci++]; 7678862bf1eSJeff Kirsher } 7688862bf1eSJeff Kirsher ip->rx_pi &= 511; 7698862bf1eSJeff Kirsher ip->rx_ci &= 511; 7708862bf1eSJeff Kirsher 7718862bf1eSJeff Kirsher for (i = ip->rx_ci; i != ip->rx_pi; i = (i + 1) & 511) { 7728862bf1eSJeff Kirsher skb = ip->rx_skbs[i]; 7738862bf1eSJeff Kirsher rxb = (struct ioc3_erxbuf *)(skb->data - RX_OFFSET); 7748862bf1eSJeff Kirsher rxb->w0 = 0; 7758862bf1eSJeff Kirsher } 7768862bf1eSJeff Kirsher } 7778862bf1eSJeff Kirsher 7788862bf1eSJeff Kirsher static inline void ioc3_clean_tx_ring(struct ioc3_private *ip) 7798862bf1eSJeff Kirsher { 7808862bf1eSJeff Kirsher struct sk_buff *skb; 7818862bf1eSJeff Kirsher int i; 7828862bf1eSJeff Kirsher 7838862bf1eSJeff Kirsher for (i = 0; i < 128; i++) { 7848862bf1eSJeff Kirsher skb = ip->tx_skbs[i]; 7858862bf1eSJeff Kirsher if (skb) { 7868862bf1eSJeff Kirsher ip->tx_skbs[i] = NULL; 7878862bf1eSJeff Kirsher dev_kfree_skb_any(skb); 7888862bf1eSJeff Kirsher } 7898862bf1eSJeff Kirsher ip->txr[i].cmd = 0; 7908862bf1eSJeff Kirsher } 7918862bf1eSJeff Kirsher ip->tx_pi = 0; 7928862bf1eSJeff Kirsher ip->tx_ci = 0; 7938862bf1eSJeff Kirsher } 7948862bf1eSJeff Kirsher 7958862bf1eSJeff Kirsher static void ioc3_free_rings(struct ioc3_private *ip) 7968862bf1eSJeff Kirsher { 7978862bf1eSJeff Kirsher struct sk_buff *skb; 7988862bf1eSJeff Kirsher int rx_entry, n_entry; 7998862bf1eSJeff Kirsher 8008862bf1eSJeff Kirsher if (ip->txr) { 8018862bf1eSJeff Kirsher ioc3_clean_tx_ring(ip); 8028862bf1eSJeff Kirsher free_pages((unsigned long)ip->txr, 2); 8038862bf1eSJeff Kirsher ip->txr = NULL; 8048862bf1eSJeff Kirsher } 8058862bf1eSJeff Kirsher 8068862bf1eSJeff Kirsher if (ip->rxr) { 8078862bf1eSJeff Kirsher n_entry = ip->rx_ci; 8088862bf1eSJeff Kirsher rx_entry = ip->rx_pi; 8098862bf1eSJeff Kirsher 8108862bf1eSJeff Kirsher while (n_entry != rx_entry) { 8118862bf1eSJeff Kirsher skb = ip->rx_skbs[n_entry]; 8128862bf1eSJeff Kirsher if (skb) 8138862bf1eSJeff Kirsher dev_kfree_skb_any(skb); 8148862bf1eSJeff Kirsher 8158862bf1eSJeff Kirsher n_entry = (n_entry + 1) & 511; 8168862bf1eSJeff Kirsher } 8178862bf1eSJeff Kirsher free_page((unsigned long)ip->rxr); 8188862bf1eSJeff Kirsher ip->rxr = NULL; 8198862bf1eSJeff Kirsher } 8208862bf1eSJeff Kirsher } 8218862bf1eSJeff Kirsher 8228862bf1eSJeff Kirsher static void ioc3_alloc_rings(struct net_device *dev) 8238862bf1eSJeff Kirsher { 8248862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 8258862bf1eSJeff Kirsher struct ioc3_erxbuf *rxb; 8268862bf1eSJeff Kirsher unsigned long *rxr; 8278862bf1eSJeff Kirsher int i; 8288862bf1eSJeff Kirsher 829c1b6a3d8SThomas Bogendoerfer if (!ip->rxr) { 8308862bf1eSJeff Kirsher /* Allocate and initialize rx ring. 4kb = 512 entries */ 8318862bf1eSJeff Kirsher ip->rxr = (unsigned long *)get_zeroed_page(GFP_ATOMIC); 83264699336SJoe Perches rxr = ip->rxr; 8338862bf1eSJeff Kirsher if (!rxr) 834c1b6a3d8SThomas Bogendoerfer pr_err("%s: get_zeroed_page() failed!\n", __func__); 8358862bf1eSJeff Kirsher 8368862bf1eSJeff Kirsher /* Now the rx buffers. The RX ring may be larger but 837c1b6a3d8SThomas Bogendoerfer * we only allocate 16 buffers for now. Need to tune 838c1b6a3d8SThomas Bogendoerfer * this for performance and memory later. 839c1b6a3d8SThomas Bogendoerfer */ 8408862bf1eSJeff Kirsher for (i = 0; i < RX_BUFFS; i++) { 8418862bf1eSJeff Kirsher struct sk_buff *skb; 8428862bf1eSJeff Kirsher 8438862bf1eSJeff Kirsher skb = ioc3_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_ATOMIC); 8448862bf1eSJeff Kirsher if (!skb) { 8459af744d7SMichal Hocko show_free_areas(0, NULL); 8468862bf1eSJeff Kirsher continue; 8478862bf1eSJeff Kirsher } 8488862bf1eSJeff Kirsher 8498862bf1eSJeff Kirsher ip->rx_skbs[i] = skb; 8508862bf1eSJeff Kirsher 8518862bf1eSJeff Kirsher /* Because we reserve afterwards. */ 8528862bf1eSJeff Kirsher skb_put(skb, (1664 + RX_OFFSET)); 8538862bf1eSJeff Kirsher rxb = (struct ioc3_erxbuf *)skb->data; 8548862bf1eSJeff Kirsher rxr[i] = cpu_to_be64(ioc3_map(rxb, 1)); 8558862bf1eSJeff Kirsher skb_reserve(skb, RX_OFFSET); 8568862bf1eSJeff Kirsher } 8578862bf1eSJeff Kirsher ip->rx_ci = 0; 8588862bf1eSJeff Kirsher ip->rx_pi = RX_BUFFS; 8598862bf1eSJeff Kirsher } 8608862bf1eSJeff Kirsher 861c1b6a3d8SThomas Bogendoerfer if (!ip->txr) { 8628862bf1eSJeff Kirsher /* Allocate and initialize tx rings. 16kb = 128 bufs. */ 8638862bf1eSJeff Kirsher ip->txr = (struct ioc3_etxd *)__get_free_pages(GFP_KERNEL, 2); 8648862bf1eSJeff Kirsher if (!ip->txr) 865c1b6a3d8SThomas Bogendoerfer pr_err("%s: __get_free_pages() failed!\n", __func__); 8668862bf1eSJeff Kirsher ip->tx_pi = 0; 8678862bf1eSJeff Kirsher ip->tx_ci = 0; 8688862bf1eSJeff Kirsher } 8698862bf1eSJeff Kirsher } 8708862bf1eSJeff Kirsher 8718862bf1eSJeff Kirsher static void ioc3_init_rings(struct net_device *dev) 8728862bf1eSJeff Kirsher { 8738862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 874cbe7d517SThomas Bogendoerfer struct ioc3_ethregs *regs = ip->regs; 8758862bf1eSJeff Kirsher unsigned long ring; 8768862bf1eSJeff Kirsher 8778862bf1eSJeff Kirsher ioc3_free_rings(ip); 8788862bf1eSJeff Kirsher ioc3_alloc_rings(dev); 8798862bf1eSJeff Kirsher 8808862bf1eSJeff Kirsher ioc3_clean_rx_ring(ip); 8818862bf1eSJeff Kirsher ioc3_clean_tx_ring(ip); 8828862bf1eSJeff Kirsher 8838862bf1eSJeff Kirsher /* Now the rx ring base, consume & produce registers. */ 8848862bf1eSJeff Kirsher ring = ioc3_map(ip->rxr, 0); 885cbe7d517SThomas Bogendoerfer writel(ring >> 32, ®s->erbr_h); 886cbe7d517SThomas Bogendoerfer writel(ring & 0xffffffff, ®s->erbr_l); 887cbe7d517SThomas Bogendoerfer writel(ip->rx_ci << 3, ®s->ercir); 888cbe7d517SThomas Bogendoerfer writel((ip->rx_pi << 3) | ERPIR_ARM, ®s->erpir); 8898862bf1eSJeff Kirsher 8908862bf1eSJeff Kirsher ring = ioc3_map(ip->txr, 0); 8918862bf1eSJeff Kirsher 8928862bf1eSJeff Kirsher ip->txqlen = 0; /* nothing queued */ 8938862bf1eSJeff Kirsher 8948862bf1eSJeff Kirsher /* Now the tx ring base, consume & produce registers. */ 895cbe7d517SThomas Bogendoerfer writel(ring >> 32, ®s->etbr_h); 896cbe7d517SThomas Bogendoerfer writel(ring & 0xffffffff, ®s->etbr_l); 897cbe7d517SThomas Bogendoerfer writel(ip->tx_pi << 7, ®s->etpir); 898cbe7d517SThomas Bogendoerfer writel(ip->tx_ci << 7, ®s->etcir); 899cbe7d517SThomas Bogendoerfer readl(®s->etcir); /* Flush */ 9008862bf1eSJeff Kirsher } 9018862bf1eSJeff Kirsher 9028862bf1eSJeff Kirsher static inline void ioc3_ssram_disc(struct ioc3_private *ip) 9038862bf1eSJeff Kirsher { 904cbe7d517SThomas Bogendoerfer struct ioc3_ethregs *regs = ip->regs; 905cbe7d517SThomas Bogendoerfer u32 *ssram0 = &ip->ssram[0x0000]; 906cbe7d517SThomas Bogendoerfer u32 *ssram1 = &ip->ssram[0x4000]; 907cbe7d517SThomas Bogendoerfer u32 pattern = 0x5555; 9088862bf1eSJeff Kirsher 9098862bf1eSJeff Kirsher /* Assume the larger size SSRAM and enable parity checking */ 910cbe7d517SThomas Bogendoerfer writel(readl(®s->emcr) | (EMCR_BUFSIZ | EMCR_RAMPAR), ®s->emcr); 911cbe7d517SThomas Bogendoerfer readl(®s->emcr); /* Flush */ 9128862bf1eSJeff Kirsher 913cbe7d517SThomas Bogendoerfer writel(pattern, ssram0); 914cbe7d517SThomas Bogendoerfer writel(~pattern & IOC3_SSRAM_DM, ssram1); 9158862bf1eSJeff Kirsher 916cbe7d517SThomas Bogendoerfer if ((readl(ssram0) & IOC3_SSRAM_DM) != pattern || 917cbe7d517SThomas Bogendoerfer (readl(ssram1) & IOC3_SSRAM_DM) != (~pattern & IOC3_SSRAM_DM)) { 9188862bf1eSJeff Kirsher /* set ssram size to 64 KB */ 919cbe7d517SThomas Bogendoerfer ip->emcr |= EMCR_RAMPAR; 920cbe7d517SThomas Bogendoerfer writel(readl(®s->emcr) & ~EMCR_BUFSIZ, ®s->emcr); 921cbe7d517SThomas Bogendoerfer } else { 922cbe7d517SThomas Bogendoerfer ip->emcr |= EMCR_BUFSIZ | EMCR_RAMPAR; 923cbe7d517SThomas Bogendoerfer } 9248862bf1eSJeff Kirsher } 9258862bf1eSJeff Kirsher 9268862bf1eSJeff Kirsher static void ioc3_init(struct net_device *dev) 9278862bf1eSJeff Kirsher { 9288862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 929cbe7d517SThomas Bogendoerfer struct ioc3_ethregs *regs = ip->regs; 9308862bf1eSJeff Kirsher 9318862bf1eSJeff Kirsher del_timer_sync(&ip->ioc3_timer); /* Kill if running */ 9328862bf1eSJeff Kirsher 933cbe7d517SThomas Bogendoerfer writel(EMCR_RST, ®s->emcr); /* Reset */ 934cbe7d517SThomas Bogendoerfer readl(®s->emcr); /* Flush WB */ 9358862bf1eSJeff Kirsher udelay(4); /* Give it time ... */ 936cbe7d517SThomas Bogendoerfer writel(0, ®s->emcr); 937cbe7d517SThomas Bogendoerfer readl(®s->emcr); 9388862bf1eSJeff Kirsher 9398862bf1eSJeff Kirsher /* Misc registers */ 9408862bf1eSJeff Kirsher #ifdef CONFIG_SGI_IP27 941cbe7d517SThomas Bogendoerfer /* Barrier on last store */ 942cbe7d517SThomas Bogendoerfer writel(PCI64_ATTR_BAR >> 32, ®s->erbar); 9438862bf1eSJeff Kirsher #else 944cbe7d517SThomas Bogendoerfer /* Let PCI API get it right */ 945cbe7d517SThomas Bogendoerfer writel(0, ®s->erbar); 9468862bf1eSJeff Kirsher #endif 947cbe7d517SThomas Bogendoerfer readl(®s->etcdc); /* Clear on read */ 948cbe7d517SThomas Bogendoerfer writel(15, ®s->ercsr); /* RX low watermark */ 949cbe7d517SThomas Bogendoerfer writel(0, ®s->ertr); /* Interrupt immediately */ 9508862bf1eSJeff Kirsher __ioc3_set_mac_address(dev); 951cbe7d517SThomas Bogendoerfer writel(ip->ehar_h, ®s->ehar_h); 952cbe7d517SThomas Bogendoerfer writel(ip->ehar_l, ®s->ehar_l); 953cbe7d517SThomas Bogendoerfer writel(42, ®s->ersr); /* XXX should be random */ 9548862bf1eSJeff Kirsher 9558862bf1eSJeff Kirsher ioc3_init_rings(dev); 9568862bf1eSJeff Kirsher 9578862bf1eSJeff Kirsher ip->emcr |= ((RX_OFFSET / 2) << EMCR_RXOFF_SHIFT) | EMCR_TXDMAEN | 9588862bf1eSJeff Kirsher EMCR_TXEN | EMCR_RXDMAEN | EMCR_RXEN | EMCR_PADEN; 959cbe7d517SThomas Bogendoerfer writel(ip->emcr, ®s->emcr); 960cbe7d517SThomas Bogendoerfer writel(EISR_RXTIMERINT | EISR_RXOFLO | EISR_RXBUFOFLO | 9618862bf1eSJeff Kirsher EISR_RXMEMERR | EISR_RXPARERR | EISR_TXBUFUFLO | 962cbe7d517SThomas Bogendoerfer EISR_TXEXPLICIT | EISR_TXMEMERR, ®s->eier); 963cbe7d517SThomas Bogendoerfer readl(®s->eier); 9648862bf1eSJeff Kirsher } 9658862bf1eSJeff Kirsher 9668862bf1eSJeff Kirsher static inline void ioc3_stop(struct ioc3_private *ip) 9678862bf1eSJeff Kirsher { 968cbe7d517SThomas Bogendoerfer struct ioc3_ethregs *regs = ip->regs; 9698862bf1eSJeff Kirsher 970cbe7d517SThomas Bogendoerfer writel(0, ®s->emcr); /* Shutup */ 971cbe7d517SThomas Bogendoerfer writel(0, ®s->eier); /* Disable interrupts */ 972cbe7d517SThomas Bogendoerfer readl(®s->eier); /* Flush */ 9738862bf1eSJeff Kirsher } 9748862bf1eSJeff Kirsher 9758862bf1eSJeff Kirsher static int ioc3_open(struct net_device *dev) 9768862bf1eSJeff Kirsher { 9778862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 9788862bf1eSJeff Kirsher 9798862bf1eSJeff Kirsher if (request_irq(dev->irq, ioc3_interrupt, IRQF_SHARED, ioc3_str, dev)) { 980c1b6a3d8SThomas Bogendoerfer netdev_err(dev, "Can't get irq %d\n", dev->irq); 9818862bf1eSJeff Kirsher 9828862bf1eSJeff Kirsher return -EAGAIN; 9838862bf1eSJeff Kirsher } 9848862bf1eSJeff Kirsher 9858862bf1eSJeff Kirsher ip->ehar_h = 0; 9868862bf1eSJeff Kirsher ip->ehar_l = 0; 9878862bf1eSJeff Kirsher ioc3_init(dev); 9888862bf1eSJeff Kirsher ioc3_mii_start(ip); 9898862bf1eSJeff Kirsher 9908862bf1eSJeff Kirsher netif_start_queue(dev); 9918862bf1eSJeff Kirsher return 0; 9928862bf1eSJeff Kirsher } 9938862bf1eSJeff Kirsher 9948862bf1eSJeff Kirsher static int ioc3_close(struct net_device *dev) 9958862bf1eSJeff Kirsher { 9968862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 9978862bf1eSJeff Kirsher 9988862bf1eSJeff Kirsher del_timer_sync(&ip->ioc3_timer); 9998862bf1eSJeff Kirsher 10008862bf1eSJeff Kirsher netif_stop_queue(dev); 10018862bf1eSJeff Kirsher 10028862bf1eSJeff Kirsher ioc3_stop(ip); 10038862bf1eSJeff Kirsher free_irq(dev->irq, dev); 10048862bf1eSJeff Kirsher 10058862bf1eSJeff Kirsher ioc3_free_rings(ip); 10068862bf1eSJeff Kirsher return 0; 10078862bf1eSJeff Kirsher } 10088862bf1eSJeff Kirsher 1009c1b6a3d8SThomas Bogendoerfer /* MENET cards have four IOC3 chips, which are attached to two sets of 10108862bf1eSJeff Kirsher * PCI slot resources each: the primary connections are on slots 10118862bf1eSJeff Kirsher * 0..3 and the secondaries are on 4..7 10128862bf1eSJeff Kirsher * 10138862bf1eSJeff Kirsher * All four ethernets are brought out to connectors; six serial ports 10148862bf1eSJeff Kirsher * (a pair from each of the first three IOC3s) are brought out to 10158862bf1eSJeff Kirsher * MiniDINs; all other subdevices are left swinging in the wind, leave 10168862bf1eSJeff Kirsher * them disabled. 10178862bf1eSJeff Kirsher */ 10188862bf1eSJeff Kirsher 10198862bf1eSJeff Kirsher static int ioc3_adjacent_is_ioc3(struct pci_dev *pdev, int slot) 10208862bf1eSJeff Kirsher { 10218862bf1eSJeff Kirsher struct pci_dev *dev = pci_get_slot(pdev->bus, PCI_DEVFN(slot, 0)); 10228862bf1eSJeff Kirsher int ret = 0; 10238862bf1eSJeff Kirsher 10248862bf1eSJeff Kirsher if (dev) { 10258862bf1eSJeff Kirsher if (dev->vendor == PCI_VENDOR_ID_SGI && 10268862bf1eSJeff Kirsher dev->device == PCI_DEVICE_ID_SGI_IOC3) 10278862bf1eSJeff Kirsher ret = 1; 10288862bf1eSJeff Kirsher pci_dev_put(dev); 10298862bf1eSJeff Kirsher } 10308862bf1eSJeff Kirsher 10318862bf1eSJeff Kirsher return ret; 10328862bf1eSJeff Kirsher } 10338862bf1eSJeff Kirsher 10348862bf1eSJeff Kirsher static int ioc3_is_menet(struct pci_dev *pdev) 10358862bf1eSJeff Kirsher { 1036c1b6a3d8SThomas Bogendoerfer return !pdev->bus->parent && 10378862bf1eSJeff Kirsher ioc3_adjacent_is_ioc3(pdev, 0) && 10388862bf1eSJeff Kirsher ioc3_adjacent_is_ioc3(pdev, 1) && 10398862bf1eSJeff Kirsher ioc3_adjacent_is_ioc3(pdev, 2); 10408862bf1eSJeff Kirsher } 10418862bf1eSJeff Kirsher 10428862bf1eSJeff Kirsher #ifdef CONFIG_SERIAL_8250 1043c1b6a3d8SThomas Bogendoerfer /* Note about serial ports and consoles: 10448862bf1eSJeff Kirsher * For console output, everyone uses the IOC3 UARTA (offset 0x178) 10458862bf1eSJeff Kirsher * connected to the master node (look in ip27_setup_console() and 10468862bf1eSJeff Kirsher * ip27prom_console_write()). 10478862bf1eSJeff Kirsher * 10488862bf1eSJeff Kirsher * For serial (/dev/ttyS0 etc), we can not have hardcoded serial port 10498862bf1eSJeff Kirsher * addresses on a partitioned machine. Since we currently use the ioc3 10508862bf1eSJeff Kirsher * serial ports, we use dynamic serial port discovery that the serial.c 10518862bf1eSJeff Kirsher * driver uses for pci/pnp ports (there is an entry for the SGI ioc3 10528862bf1eSJeff Kirsher * boards in pci_boards[]). Unfortunately, UARTA's pio address is greater 10538862bf1eSJeff Kirsher * than UARTB's, although UARTA on o200s has traditionally been known as 10548862bf1eSJeff Kirsher * port 0. So, we just use one serial port from each ioc3 (since the 10558862bf1eSJeff Kirsher * serial driver adds addresses to get to higher ports). 10568862bf1eSJeff Kirsher * 10578862bf1eSJeff Kirsher * The first one to do a register_console becomes the preferred console 10588862bf1eSJeff Kirsher * (if there is no kernel command line console= directive). /dev/console 10598862bf1eSJeff Kirsher * (ie 5, 1) is then "aliased" into the device number returned by the 10608862bf1eSJeff Kirsher * "device" routine referred to in this console structure 10618862bf1eSJeff Kirsher * (ip27prom_console_dev). 10628862bf1eSJeff Kirsher * 10638862bf1eSJeff Kirsher * Also look in ip27-pci.c:pci_fixup_ioc3() for some comments on working 10648862bf1eSJeff Kirsher * around ioc3 oddities in this respect. 10658862bf1eSJeff Kirsher * 10668862bf1eSJeff Kirsher * The IOC3 serials use a 22MHz clock rate with an additional divider which 10678862bf1eSJeff Kirsher * can be programmed in the SCR register if the DLAB bit is set. 10688862bf1eSJeff Kirsher * 10698862bf1eSJeff Kirsher * Register to interrupt zero because we share the interrupt with 10708862bf1eSJeff Kirsher * the serial driver which we don't properly support yet. 10718862bf1eSJeff Kirsher * 10728862bf1eSJeff Kirsher * Can't use UPF_IOREMAP as the whole of IOC3 resources have already been 10738862bf1eSJeff Kirsher * registered. 10748862bf1eSJeff Kirsher */ 1075f48a3c2aSBill Pemberton static void ioc3_8250_register(struct ioc3_uartregs __iomem *uart) 10768862bf1eSJeff Kirsher { 10778862bf1eSJeff Kirsher #define COSMISC_CONSTANT 6 10788862bf1eSJeff Kirsher 1079ce7240e4SAlan Cox struct uart_8250_port port = { 1080ce7240e4SAlan Cox .port = { 10818862bf1eSJeff Kirsher .irq = 0, 10828862bf1eSJeff Kirsher .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, 10838862bf1eSJeff Kirsher .iotype = UPIO_MEM, 10848862bf1eSJeff Kirsher .regshift = 0, 10858862bf1eSJeff Kirsher .uartclk = (22000000 << 1) / COSMISC_CONSTANT, 10868862bf1eSJeff Kirsher 10878862bf1eSJeff Kirsher .membase = (unsigned char __iomem *)uart, 10888862bf1eSJeff Kirsher .mapbase = (unsigned long)uart, 1089ce7240e4SAlan Cox } 10908862bf1eSJeff Kirsher }; 10918862bf1eSJeff Kirsher unsigned char lcr; 10928862bf1eSJeff Kirsher 1093cbe7d517SThomas Bogendoerfer lcr = readb(&uart->iu_lcr); 1094cbe7d517SThomas Bogendoerfer writeb(lcr | UART_LCR_DLAB, &uart->iu_lcr); 1095cbe7d517SThomas Bogendoerfer writeb(COSMISC_CONSTANT, &uart->iu_scr); 1096cbe7d517SThomas Bogendoerfer writeb(lcr, &uart->iu_lcr); 1097cbe7d517SThomas Bogendoerfer readb(&uart->iu_lcr); 1098ce7240e4SAlan Cox serial8250_register_8250_port(&port); 10998862bf1eSJeff Kirsher } 11008862bf1eSJeff Kirsher 1101f48a3c2aSBill Pemberton static void ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3) 11028862bf1eSJeff Kirsher { 1103cbe7d517SThomas Bogendoerfer u32 sio_iec; 1104cbe7d517SThomas Bogendoerfer 1105c1b6a3d8SThomas Bogendoerfer /* We need to recognice and treat the fourth MENET serial as it 11068862bf1eSJeff Kirsher * does not have an SuperIO chip attached to it, therefore attempting 11078862bf1eSJeff Kirsher * to access it will result in bus errors. We call something an 11088862bf1eSJeff Kirsher * MENET if PCI slot 0, 1, 2 and 3 of a master PCI bus all have an IOC3 11098862bf1eSJeff Kirsher * in it. This is paranoid but we want to avoid blowing up on a 11108862bf1eSJeff Kirsher * showhorn PCI box that happens to have 4 IOC3 cards in it so it's 11118862bf1eSJeff Kirsher * not paranoid enough ... 11128862bf1eSJeff Kirsher */ 11138862bf1eSJeff Kirsher if (ioc3_is_menet(pdev) && PCI_SLOT(pdev->devfn) == 3) 11148862bf1eSJeff Kirsher return; 11158862bf1eSJeff Kirsher 1116c1b6a3d8SThomas Bogendoerfer /* Switch IOC3 to PIO mode. It probably already was but let's be 11178862bf1eSJeff Kirsher * paranoid 11188862bf1eSJeff Kirsher */ 1119cbe7d517SThomas Bogendoerfer writel(GPCR_UARTA_MODESEL | GPCR_UARTB_MODESEL, &ioc3->gpcr_s); 1120cbe7d517SThomas Bogendoerfer readl(&ioc3->gpcr_s); 1121cbe7d517SThomas Bogendoerfer writel(0, &ioc3->gppr[6]); 1122cbe7d517SThomas Bogendoerfer readl(&ioc3->gppr[6]); 1123cbe7d517SThomas Bogendoerfer writel(0, &ioc3->gppr[7]); 1124cbe7d517SThomas Bogendoerfer readl(&ioc3->gppr[7]); 1125cbe7d517SThomas Bogendoerfer writel(readl(&ioc3->port_a.sscr) & ~SSCR_DMA_EN, &ioc3->port_a.sscr); 1126cbe7d517SThomas Bogendoerfer readl(&ioc3->port_a.sscr); 1127cbe7d517SThomas Bogendoerfer writel(readl(&ioc3->port_b.sscr) & ~SSCR_DMA_EN, &ioc3->port_b.sscr); 1128cbe7d517SThomas Bogendoerfer readl(&ioc3->port_b.sscr); 11298862bf1eSJeff Kirsher /* Disable all SA/B interrupts except for SA/B_INT in SIO_IEC. */ 1130cbe7d517SThomas Bogendoerfer sio_iec = readl(&ioc3->sio_iec); 1131cbe7d517SThomas Bogendoerfer sio_iec &= ~(SIO_IR_SA_TX_MT | SIO_IR_SA_RX_FULL | 11328862bf1eSJeff Kirsher SIO_IR_SA_RX_HIGH | SIO_IR_SA_RX_TIMER | 11338862bf1eSJeff Kirsher SIO_IR_SA_DELTA_DCD | SIO_IR_SA_DELTA_CTS | 11348862bf1eSJeff Kirsher SIO_IR_SA_TX_EXPLICIT | SIO_IR_SA_MEMERR); 1135cbe7d517SThomas Bogendoerfer sio_iec |= SIO_IR_SA_INT; 1136cbe7d517SThomas Bogendoerfer sio_iec &= ~(SIO_IR_SB_TX_MT | SIO_IR_SB_RX_FULL | 11378862bf1eSJeff Kirsher SIO_IR_SB_RX_HIGH | SIO_IR_SB_RX_TIMER | 11388862bf1eSJeff Kirsher SIO_IR_SB_DELTA_DCD | SIO_IR_SB_DELTA_CTS | 11398862bf1eSJeff Kirsher SIO_IR_SB_TX_EXPLICIT | SIO_IR_SB_MEMERR); 1140cbe7d517SThomas Bogendoerfer sio_iec |= SIO_IR_SB_INT; 1141cbe7d517SThomas Bogendoerfer writel(sio_iec, &ioc3->sio_iec); 1142cbe7d517SThomas Bogendoerfer writel(0, &ioc3->port_a.sscr); 1143cbe7d517SThomas Bogendoerfer writel(0, &ioc3->port_b.sscr); 11448862bf1eSJeff Kirsher 11458862bf1eSJeff Kirsher ioc3_8250_register(&ioc3->sregs.uarta); 11468862bf1eSJeff Kirsher ioc3_8250_register(&ioc3->sregs.uartb); 11478862bf1eSJeff Kirsher } 11488862bf1eSJeff Kirsher #endif 11498862bf1eSJeff Kirsher 11508862bf1eSJeff Kirsher static const struct net_device_ops ioc3_netdev_ops = { 11518862bf1eSJeff Kirsher .ndo_open = ioc3_open, 11528862bf1eSJeff Kirsher .ndo_stop = ioc3_close, 11538862bf1eSJeff Kirsher .ndo_start_xmit = ioc3_start_xmit, 11548862bf1eSJeff Kirsher .ndo_tx_timeout = ioc3_timeout, 11558862bf1eSJeff Kirsher .ndo_get_stats = ioc3_get_stats, 1156afc4b13dSJiri Pirko .ndo_set_rx_mode = ioc3_set_multicast_list, 11578862bf1eSJeff Kirsher .ndo_do_ioctl = ioc3_ioctl, 11588862bf1eSJeff Kirsher .ndo_validate_addr = eth_validate_addr, 11598862bf1eSJeff Kirsher .ndo_set_mac_address = ioc3_set_mac_address, 11608862bf1eSJeff Kirsher }; 11618862bf1eSJeff Kirsher 11621dd06ae8SGreg Kroah-Hartman static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 11638862bf1eSJeff Kirsher { 11648862bf1eSJeff Kirsher unsigned int sw_physid1, sw_physid2; 11658862bf1eSJeff Kirsher struct net_device *dev = NULL; 11668862bf1eSJeff Kirsher struct ioc3_private *ip; 11678862bf1eSJeff Kirsher struct ioc3 *ioc3; 11688862bf1eSJeff Kirsher unsigned long ioc3_base, ioc3_size; 11698862bf1eSJeff Kirsher u32 vendor, model, rev; 11708862bf1eSJeff Kirsher int err, pci_using_dac; 11718862bf1eSJeff Kirsher 11728862bf1eSJeff Kirsher /* Configure DMA attributes. */ 11738862bf1eSJeff Kirsher err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); 11748862bf1eSJeff Kirsher if (!err) { 11758862bf1eSJeff Kirsher pci_using_dac = 1; 11768862bf1eSJeff Kirsher err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); 11778862bf1eSJeff Kirsher if (err < 0) { 1178c1b6a3d8SThomas Bogendoerfer pr_err("%s: Unable to obtain 64 bit DMA for consistent allocations\n", 1179c1b6a3d8SThomas Bogendoerfer pci_name(pdev)); 11808862bf1eSJeff Kirsher goto out; 11818862bf1eSJeff Kirsher } 11828862bf1eSJeff Kirsher } else { 11838862bf1eSJeff Kirsher err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); 11848862bf1eSJeff Kirsher if (err) { 1185c1b6a3d8SThomas Bogendoerfer pr_err("%s: No usable DMA configuration, aborting.\n", 1186c1b6a3d8SThomas Bogendoerfer pci_name(pdev)); 11878862bf1eSJeff Kirsher goto out; 11888862bf1eSJeff Kirsher } 11898862bf1eSJeff Kirsher pci_using_dac = 0; 11908862bf1eSJeff Kirsher } 11918862bf1eSJeff Kirsher 11928862bf1eSJeff Kirsher if (pci_enable_device(pdev)) 11938862bf1eSJeff Kirsher return -ENODEV; 11948862bf1eSJeff Kirsher 11958862bf1eSJeff Kirsher dev = alloc_etherdev(sizeof(struct ioc3_private)); 11968862bf1eSJeff Kirsher if (!dev) { 11978862bf1eSJeff Kirsher err = -ENOMEM; 11988862bf1eSJeff Kirsher goto out_disable; 11998862bf1eSJeff Kirsher } 12008862bf1eSJeff Kirsher 12018862bf1eSJeff Kirsher if (pci_using_dac) 12028862bf1eSJeff Kirsher dev->features |= NETIF_F_HIGHDMA; 12038862bf1eSJeff Kirsher 12048862bf1eSJeff Kirsher err = pci_request_regions(pdev, "ioc3"); 12058862bf1eSJeff Kirsher if (err) 12068862bf1eSJeff Kirsher goto out_free; 12078862bf1eSJeff Kirsher 12088862bf1eSJeff Kirsher SET_NETDEV_DEV(dev, &pdev->dev); 12098862bf1eSJeff Kirsher 12108862bf1eSJeff Kirsher ip = netdev_priv(dev); 1211dfcc16c9SJason A. Donenfeld ip->dev = dev; 12128862bf1eSJeff Kirsher 12138862bf1eSJeff Kirsher dev->irq = pdev->irq; 12148862bf1eSJeff Kirsher 12158862bf1eSJeff Kirsher ioc3_base = pci_resource_start(pdev, 0); 12168862bf1eSJeff Kirsher ioc3_size = pci_resource_len(pdev, 0); 12178862bf1eSJeff Kirsher ioc3 = (struct ioc3 *)ioremap(ioc3_base, ioc3_size); 12188862bf1eSJeff Kirsher if (!ioc3) { 1219c1b6a3d8SThomas Bogendoerfer pr_err("ioc3eth(%s): ioremap failed, goodbye.\n", 12208862bf1eSJeff Kirsher pci_name(pdev)); 12218862bf1eSJeff Kirsher err = -ENOMEM; 12228862bf1eSJeff Kirsher goto out_res; 12238862bf1eSJeff Kirsher } 1224cbe7d517SThomas Bogendoerfer ip->regs = &ioc3->eth; 1225cbe7d517SThomas Bogendoerfer ip->ssram = ioc3->ssram; 1226cbe7d517SThomas Bogendoerfer ip->all_regs = ioc3; 12278862bf1eSJeff Kirsher 12288862bf1eSJeff Kirsher #ifdef CONFIG_SERIAL_8250 12298862bf1eSJeff Kirsher ioc3_serial_probe(pdev, ioc3); 12308862bf1eSJeff Kirsher #endif 12318862bf1eSJeff Kirsher 12328862bf1eSJeff Kirsher spin_lock_init(&ip->ioc3_lock); 1233dfc57004SKees Cook timer_setup(&ip->ioc3_timer, ioc3_timer, 0); 12348862bf1eSJeff Kirsher 12358862bf1eSJeff Kirsher ioc3_stop(ip); 12368862bf1eSJeff Kirsher ioc3_init(dev); 12378862bf1eSJeff Kirsher 12388862bf1eSJeff Kirsher ip->pdev = pdev; 12398862bf1eSJeff Kirsher 12408862bf1eSJeff Kirsher ip->mii.phy_id_mask = 0x1f; 12418862bf1eSJeff Kirsher ip->mii.reg_num_mask = 0x1f; 12428862bf1eSJeff Kirsher ip->mii.dev = dev; 12438862bf1eSJeff Kirsher ip->mii.mdio_read = ioc3_mdio_read; 12448862bf1eSJeff Kirsher ip->mii.mdio_write = ioc3_mdio_write; 12458862bf1eSJeff Kirsher 12468862bf1eSJeff Kirsher ioc3_mii_init(ip); 12478862bf1eSJeff Kirsher 12488862bf1eSJeff Kirsher if (ip->mii.phy_id == -1) { 1249c1b6a3d8SThomas Bogendoerfer pr_err("ioc3-eth(%s): Didn't find a PHY, goodbye.\n", 12508862bf1eSJeff Kirsher pci_name(pdev)); 12518862bf1eSJeff Kirsher err = -ENODEV; 12528862bf1eSJeff Kirsher goto out_stop; 12538862bf1eSJeff Kirsher } 12548862bf1eSJeff Kirsher 12558862bf1eSJeff Kirsher ioc3_mii_start(ip); 12568862bf1eSJeff Kirsher ioc3_ssram_disc(ip); 12578862bf1eSJeff Kirsher ioc3_get_eaddr(ip); 12588862bf1eSJeff Kirsher 12598862bf1eSJeff Kirsher /* The IOC3-specific entries in the device structure. */ 12608862bf1eSJeff Kirsher dev->watchdog_timeo = 5 * HZ; 12618862bf1eSJeff Kirsher dev->netdev_ops = &ioc3_netdev_ops; 12628862bf1eSJeff Kirsher dev->ethtool_ops = &ioc3_ethtool_ops; 12638862bf1eSJeff Kirsher dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM; 12648862bf1eSJeff Kirsher dev->features = NETIF_F_IP_CSUM; 12658862bf1eSJeff Kirsher 12668862bf1eSJeff Kirsher sw_physid1 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID1); 12678862bf1eSJeff Kirsher sw_physid2 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID2); 12688862bf1eSJeff Kirsher 12698862bf1eSJeff Kirsher err = register_netdev(dev); 12708862bf1eSJeff Kirsher if (err) 12718862bf1eSJeff Kirsher goto out_stop; 12728862bf1eSJeff Kirsher 12738862bf1eSJeff Kirsher mii_check_media(&ip->mii, 1, 1); 12748862bf1eSJeff Kirsher ioc3_setup_duplex(ip); 12758862bf1eSJeff Kirsher 12768862bf1eSJeff Kirsher vendor = (sw_physid1 << 12) | (sw_physid2 >> 4); 12778862bf1eSJeff Kirsher model = (sw_physid2 >> 4) & 0x3f; 12788862bf1eSJeff Kirsher rev = sw_physid2 & 0xf; 1279c1b6a3d8SThomas Bogendoerfer netdev_info(dev, "Using PHY %d, vendor 0x%x, model %d, rev %d.\n", 1280c1b6a3d8SThomas Bogendoerfer ip->mii.phy_id, vendor, model, rev); 1281c1b6a3d8SThomas Bogendoerfer netdev_info(dev, "IOC3 SSRAM has %d kbyte.\n", 12828862bf1eSJeff Kirsher ip->emcr & EMCR_BUFSIZ ? 128 : 64); 12838862bf1eSJeff Kirsher 12848862bf1eSJeff Kirsher return 0; 12858862bf1eSJeff Kirsher 12868862bf1eSJeff Kirsher out_stop: 12878862bf1eSJeff Kirsher ioc3_stop(ip); 12888862bf1eSJeff Kirsher del_timer_sync(&ip->ioc3_timer); 12898862bf1eSJeff Kirsher ioc3_free_rings(ip); 12908862bf1eSJeff Kirsher out_res: 12918862bf1eSJeff Kirsher pci_release_regions(pdev); 12928862bf1eSJeff Kirsher out_free: 12938862bf1eSJeff Kirsher free_netdev(dev); 12948862bf1eSJeff Kirsher out_disable: 1295c1b6a3d8SThomas Bogendoerfer /* We should call pci_disable_device(pdev); here if the IOC3 wasn't 12968862bf1eSJeff Kirsher * such a weird device ... 12978862bf1eSJeff Kirsher */ 12988862bf1eSJeff Kirsher out: 12998862bf1eSJeff Kirsher return err; 13008862bf1eSJeff Kirsher } 13018862bf1eSJeff Kirsher 1302f48a3c2aSBill Pemberton static void ioc3_remove_one(struct pci_dev *pdev) 13038862bf1eSJeff Kirsher { 13048862bf1eSJeff Kirsher struct net_device *dev = pci_get_drvdata(pdev); 13058862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 13068862bf1eSJeff Kirsher 13078862bf1eSJeff Kirsher unregister_netdev(dev); 13088862bf1eSJeff Kirsher del_timer_sync(&ip->ioc3_timer); 13098862bf1eSJeff Kirsher 1310cbe7d517SThomas Bogendoerfer iounmap(ip->all_regs); 13118862bf1eSJeff Kirsher pci_release_regions(pdev); 13128862bf1eSJeff Kirsher free_netdev(dev); 1313c1b6a3d8SThomas Bogendoerfer /* We should call pci_disable_device(pdev); here if the IOC3 wasn't 13148862bf1eSJeff Kirsher * such a weird device ... 13158862bf1eSJeff Kirsher */ 13168862bf1eSJeff Kirsher } 13178862bf1eSJeff Kirsher 13189baa3c34SBenoit Taine static const struct pci_device_id ioc3_pci_tbl[] = { 13198862bf1eSJeff Kirsher { PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, PCI_ANY_ID, PCI_ANY_ID }, 13208862bf1eSJeff Kirsher { 0 } 13218862bf1eSJeff Kirsher }; 13228862bf1eSJeff Kirsher MODULE_DEVICE_TABLE(pci, ioc3_pci_tbl); 13238862bf1eSJeff Kirsher 13248862bf1eSJeff Kirsher static struct pci_driver ioc3_driver = { 13258862bf1eSJeff Kirsher .name = "ioc3-eth", 13268862bf1eSJeff Kirsher .id_table = ioc3_pci_tbl, 13278862bf1eSJeff Kirsher .probe = ioc3_probe, 1328f48a3c2aSBill Pemberton .remove = ioc3_remove_one, 13298862bf1eSJeff Kirsher }; 13308862bf1eSJeff Kirsher 133128d304efSYueHaibing static netdev_tx_t ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev) 13328862bf1eSJeff Kirsher { 13338862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 13348862bf1eSJeff Kirsher struct ioc3_etxd *desc; 1335cbe7d517SThomas Bogendoerfer unsigned long data; 1336cbe7d517SThomas Bogendoerfer unsigned int len; 13378862bf1eSJeff Kirsher int produce; 1338c1b6a3d8SThomas Bogendoerfer u32 w0 = 0; 13398862bf1eSJeff Kirsher 1340c1b6a3d8SThomas Bogendoerfer /* IOC3 has a fairly simple minded checksumming hardware which simply 13418862bf1eSJeff Kirsher * adds up the 1's complement checksum for the entire packet and 13428862bf1eSJeff Kirsher * inserts it at an offset which can be specified in the descriptor 13438862bf1eSJeff Kirsher * into the transmit packet. This means we have to compensate for the 13448862bf1eSJeff Kirsher * MAC header which should not be summed and the TCP/UDP pseudo headers 13458862bf1eSJeff Kirsher * manually. 13468862bf1eSJeff Kirsher */ 13478862bf1eSJeff Kirsher if (skb->ip_summed == CHECKSUM_PARTIAL) { 13488862bf1eSJeff Kirsher const struct iphdr *ih = ip_hdr(skb); 13498862bf1eSJeff Kirsher const int proto = ntohs(ih->protocol); 13508862bf1eSJeff Kirsher unsigned int csoff; 1351c1b6a3d8SThomas Bogendoerfer u32 csum, ehsum; 1352c1b6a3d8SThomas Bogendoerfer u16 *eh; 13538862bf1eSJeff Kirsher 13548862bf1eSJeff Kirsher /* The MAC header. skb->mac seem the logic approach 1355c1b6a3d8SThomas Bogendoerfer * to find the MAC header - except it's a NULL pointer ... 1356c1b6a3d8SThomas Bogendoerfer */ 1357c1b6a3d8SThomas Bogendoerfer eh = (u16 *)skb->data; 13588862bf1eSJeff Kirsher 13598862bf1eSJeff Kirsher /* Sum up dest addr, src addr and protocol */ 13608862bf1eSJeff Kirsher ehsum = eh[0] + eh[1] + eh[2] + eh[3] + eh[4] + eh[5] + eh[6]; 13618862bf1eSJeff Kirsher 13628862bf1eSJeff Kirsher /* Fold ehsum. can't use csum_fold which negates also ... */ 13638862bf1eSJeff Kirsher ehsum = (ehsum & 0xffff) + (ehsum >> 16); 13648862bf1eSJeff Kirsher ehsum = (ehsum & 0xffff) + (ehsum >> 16); 13658862bf1eSJeff Kirsher 13668862bf1eSJeff Kirsher /* Skip IP header; it's sum is always zero and was 1367c1b6a3d8SThomas Bogendoerfer * already filled in by ip_output.c 1368c1b6a3d8SThomas Bogendoerfer */ 13698862bf1eSJeff Kirsher csum = csum_tcpudp_nofold(ih->saddr, ih->daddr, 13708862bf1eSJeff Kirsher ih->tot_len - (ih->ihl << 2), 13718862bf1eSJeff Kirsher proto, 0xffff ^ ehsum); 13728862bf1eSJeff Kirsher 13738862bf1eSJeff Kirsher csum = (csum & 0xffff) + (csum >> 16); /* Fold again */ 13748862bf1eSJeff Kirsher csum = (csum & 0xffff) + (csum >> 16); 13758862bf1eSJeff Kirsher 13768862bf1eSJeff Kirsher csoff = ETH_HLEN + (ih->ihl << 2); 13778862bf1eSJeff Kirsher if (proto == IPPROTO_UDP) { 13788862bf1eSJeff Kirsher csoff += offsetof(struct udphdr, check); 13798862bf1eSJeff Kirsher udp_hdr(skb)->check = csum; 13808862bf1eSJeff Kirsher } 13818862bf1eSJeff Kirsher if (proto == IPPROTO_TCP) { 13828862bf1eSJeff Kirsher csoff += offsetof(struct tcphdr, check); 13838862bf1eSJeff Kirsher tcp_hdr(skb)->check = csum; 13848862bf1eSJeff Kirsher } 13858862bf1eSJeff Kirsher 13868862bf1eSJeff Kirsher w0 = ETXD_DOCHECKSUM | (csoff << ETXD_CHKOFF_SHIFT); 13878862bf1eSJeff Kirsher } 13888862bf1eSJeff Kirsher 13898862bf1eSJeff Kirsher spin_lock_irq(&ip->ioc3_lock); 13908862bf1eSJeff Kirsher 13918862bf1eSJeff Kirsher data = (unsigned long)skb->data; 13928862bf1eSJeff Kirsher len = skb->len; 13938862bf1eSJeff Kirsher 13948862bf1eSJeff Kirsher produce = ip->tx_pi; 13958862bf1eSJeff Kirsher desc = &ip->txr[produce]; 13968862bf1eSJeff Kirsher 13978862bf1eSJeff Kirsher if (len <= 104) { 13988862bf1eSJeff Kirsher /* Short packet, let's copy it directly into the ring. */ 13998862bf1eSJeff Kirsher skb_copy_from_linear_data(skb, desc->data, skb->len); 14008862bf1eSJeff Kirsher if (len < ETH_ZLEN) { 14018862bf1eSJeff Kirsher /* Very short packet, pad with zeros at the end. */ 14028862bf1eSJeff Kirsher memset(desc->data + len, 0, ETH_ZLEN - len); 14038862bf1eSJeff Kirsher len = ETH_ZLEN; 14048862bf1eSJeff Kirsher } 14058862bf1eSJeff Kirsher desc->cmd = cpu_to_be32(len | ETXD_INTWHENDONE | ETXD_D0V | w0); 14068862bf1eSJeff Kirsher desc->bufcnt = cpu_to_be32(len); 14078862bf1eSJeff Kirsher } else if ((data ^ (data + len - 1)) & 0x4000) { 14088862bf1eSJeff Kirsher unsigned long b2 = (data | 0x3fffUL) + 1UL; 14098862bf1eSJeff Kirsher unsigned long s1 = b2 - data; 14108862bf1eSJeff Kirsher unsigned long s2 = data + len - b2; 14118862bf1eSJeff Kirsher 14128862bf1eSJeff Kirsher desc->cmd = cpu_to_be32(len | ETXD_INTWHENDONE | 14138862bf1eSJeff Kirsher ETXD_B1V | ETXD_B2V | w0); 14148862bf1eSJeff Kirsher desc->bufcnt = cpu_to_be32((s1 << ETXD_B1CNT_SHIFT) | 14158862bf1eSJeff Kirsher (s2 << ETXD_B2CNT_SHIFT)); 14168862bf1eSJeff Kirsher desc->p1 = cpu_to_be64(ioc3_map(skb->data, 1)); 14178862bf1eSJeff Kirsher desc->p2 = cpu_to_be64(ioc3_map((void *)b2, 1)); 14188862bf1eSJeff Kirsher } else { 14198862bf1eSJeff Kirsher /* Normal sized packet that doesn't cross a page boundary. */ 14208862bf1eSJeff Kirsher desc->cmd = cpu_to_be32(len | ETXD_INTWHENDONE | ETXD_B1V | w0); 14218862bf1eSJeff Kirsher desc->bufcnt = cpu_to_be32(len << ETXD_B1CNT_SHIFT); 14228862bf1eSJeff Kirsher desc->p1 = cpu_to_be64(ioc3_map(skb->data, 1)); 14238862bf1eSJeff Kirsher } 14248862bf1eSJeff Kirsher 1425c1b6a3d8SThomas Bogendoerfer mb(); /* make sure all descriptor changes are visible */ 14268862bf1eSJeff Kirsher 14278862bf1eSJeff Kirsher ip->tx_skbs[produce] = skb; /* Remember skb */ 14288862bf1eSJeff Kirsher produce = (produce + 1) & 127; 14298862bf1eSJeff Kirsher ip->tx_pi = produce; 1430cbe7d517SThomas Bogendoerfer writel(produce << 7, &ip->regs->etpir); /* Fire ... */ 14318862bf1eSJeff Kirsher 14328862bf1eSJeff Kirsher ip->txqlen++; 14338862bf1eSJeff Kirsher 14348862bf1eSJeff Kirsher if (ip->txqlen >= 127) 14358862bf1eSJeff Kirsher netif_stop_queue(dev); 14368862bf1eSJeff Kirsher 14378862bf1eSJeff Kirsher spin_unlock_irq(&ip->ioc3_lock); 14388862bf1eSJeff Kirsher 14398862bf1eSJeff Kirsher return NETDEV_TX_OK; 14408862bf1eSJeff Kirsher } 14418862bf1eSJeff Kirsher 14428862bf1eSJeff Kirsher static void ioc3_timeout(struct net_device *dev) 14438862bf1eSJeff Kirsher { 14448862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 14458862bf1eSJeff Kirsher 1446c1b6a3d8SThomas Bogendoerfer netdev_err(dev, "transmit timed out, resetting\n"); 14478862bf1eSJeff Kirsher 14488862bf1eSJeff Kirsher spin_lock_irq(&ip->ioc3_lock); 14498862bf1eSJeff Kirsher 14508862bf1eSJeff Kirsher ioc3_stop(ip); 14518862bf1eSJeff Kirsher ioc3_init(dev); 14528862bf1eSJeff Kirsher ioc3_mii_init(ip); 14538862bf1eSJeff Kirsher ioc3_mii_start(ip); 14548862bf1eSJeff Kirsher 14558862bf1eSJeff Kirsher spin_unlock_irq(&ip->ioc3_lock); 14568862bf1eSJeff Kirsher 14578862bf1eSJeff Kirsher netif_wake_queue(dev); 14588862bf1eSJeff Kirsher } 14598862bf1eSJeff Kirsher 1460c1b6a3d8SThomas Bogendoerfer /* Given a multicast ethernet address, this routine calculates the 14618862bf1eSJeff Kirsher * address's bit index in the logical address filter mask 14628862bf1eSJeff Kirsher */ 14638862bf1eSJeff Kirsher static inline unsigned int ioc3_hash(const unsigned char *addr) 14648862bf1eSJeff Kirsher { 14658862bf1eSJeff Kirsher unsigned int temp = 0; 14668862bf1eSJeff Kirsher int bits; 1467c1b6a3d8SThomas Bogendoerfer u32 crc; 14688862bf1eSJeff Kirsher 14698862bf1eSJeff Kirsher crc = ether_crc_le(ETH_ALEN, addr); 14708862bf1eSJeff Kirsher 14718862bf1eSJeff Kirsher crc &= 0x3f; /* bit reverse lowest 6 bits for hash index */ 14728862bf1eSJeff Kirsher for (bits = 6; --bits >= 0; ) { 14738862bf1eSJeff Kirsher temp <<= 1; 14748862bf1eSJeff Kirsher temp |= (crc & 0x1); 14758862bf1eSJeff Kirsher crc >>= 1; 14768862bf1eSJeff Kirsher } 14778862bf1eSJeff Kirsher 14788862bf1eSJeff Kirsher return temp; 14798862bf1eSJeff Kirsher } 14808862bf1eSJeff Kirsher 14818862bf1eSJeff Kirsher static void ioc3_get_drvinfo(struct net_device *dev, 14828862bf1eSJeff Kirsher struct ethtool_drvinfo *info) 14838862bf1eSJeff Kirsher { 14848862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 14858862bf1eSJeff Kirsher 14867826d43fSJiri Pirko strlcpy(info->driver, IOC3_NAME, sizeof(info->driver)); 14877826d43fSJiri Pirko strlcpy(info->version, IOC3_VERSION, sizeof(info->version)); 14887826d43fSJiri Pirko strlcpy(info->bus_info, pci_name(ip->pdev), sizeof(info->bus_info)); 14898862bf1eSJeff Kirsher } 14908862bf1eSJeff Kirsher 1491b61a26f8SPhilippe Reynes static int ioc3_get_link_ksettings(struct net_device *dev, 1492b61a26f8SPhilippe Reynes struct ethtool_link_ksettings *cmd) 14938862bf1eSJeff Kirsher { 14948862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 14958862bf1eSJeff Kirsher 14968862bf1eSJeff Kirsher spin_lock_irq(&ip->ioc3_lock); 149782c01a84Syuval.shaia@oracle.com mii_ethtool_get_link_ksettings(&ip->mii, cmd); 14988862bf1eSJeff Kirsher spin_unlock_irq(&ip->ioc3_lock); 14998862bf1eSJeff Kirsher 150082c01a84Syuval.shaia@oracle.com return 0; 15018862bf1eSJeff Kirsher } 15028862bf1eSJeff Kirsher 1503b61a26f8SPhilippe Reynes static int ioc3_set_link_ksettings(struct net_device *dev, 1504b61a26f8SPhilippe Reynes const struct ethtool_link_ksettings *cmd) 15058862bf1eSJeff Kirsher { 15068862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 15078862bf1eSJeff Kirsher int rc; 15088862bf1eSJeff Kirsher 15098862bf1eSJeff Kirsher spin_lock_irq(&ip->ioc3_lock); 1510b61a26f8SPhilippe Reynes rc = mii_ethtool_set_link_ksettings(&ip->mii, cmd); 15118862bf1eSJeff Kirsher spin_unlock_irq(&ip->ioc3_lock); 15128862bf1eSJeff Kirsher 15138862bf1eSJeff Kirsher return rc; 15148862bf1eSJeff Kirsher } 15158862bf1eSJeff Kirsher 15168862bf1eSJeff Kirsher static int ioc3_nway_reset(struct net_device *dev) 15178862bf1eSJeff Kirsher { 15188862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 15198862bf1eSJeff Kirsher int rc; 15208862bf1eSJeff Kirsher 15218862bf1eSJeff Kirsher spin_lock_irq(&ip->ioc3_lock); 15228862bf1eSJeff Kirsher rc = mii_nway_restart(&ip->mii); 15238862bf1eSJeff Kirsher spin_unlock_irq(&ip->ioc3_lock); 15248862bf1eSJeff Kirsher 15258862bf1eSJeff Kirsher return rc; 15268862bf1eSJeff Kirsher } 15278862bf1eSJeff Kirsher 15288862bf1eSJeff Kirsher static u32 ioc3_get_link(struct net_device *dev) 15298862bf1eSJeff Kirsher { 15308862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 15318862bf1eSJeff Kirsher int rc; 15328862bf1eSJeff Kirsher 15338862bf1eSJeff Kirsher spin_lock_irq(&ip->ioc3_lock); 15348862bf1eSJeff Kirsher rc = mii_link_ok(&ip->mii); 15358862bf1eSJeff Kirsher spin_unlock_irq(&ip->ioc3_lock); 15368862bf1eSJeff Kirsher 15378862bf1eSJeff Kirsher return rc; 15388862bf1eSJeff Kirsher } 15398862bf1eSJeff Kirsher 15408862bf1eSJeff Kirsher static const struct ethtool_ops ioc3_ethtool_ops = { 15418862bf1eSJeff Kirsher .get_drvinfo = ioc3_get_drvinfo, 15428862bf1eSJeff Kirsher .nway_reset = ioc3_nway_reset, 15438862bf1eSJeff Kirsher .get_link = ioc3_get_link, 1544b61a26f8SPhilippe Reynes .get_link_ksettings = ioc3_get_link_ksettings, 1545b61a26f8SPhilippe Reynes .set_link_ksettings = ioc3_set_link_ksettings, 15468862bf1eSJeff Kirsher }; 15478862bf1eSJeff Kirsher 15488862bf1eSJeff Kirsher static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 15498862bf1eSJeff Kirsher { 15508862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 15518862bf1eSJeff Kirsher int rc; 15528862bf1eSJeff Kirsher 15538862bf1eSJeff Kirsher spin_lock_irq(&ip->ioc3_lock); 15548862bf1eSJeff Kirsher rc = generic_mii_ioctl(&ip->mii, if_mii(rq), cmd, NULL); 15558862bf1eSJeff Kirsher spin_unlock_irq(&ip->ioc3_lock); 15568862bf1eSJeff Kirsher 15578862bf1eSJeff Kirsher return rc; 15588862bf1eSJeff Kirsher } 15598862bf1eSJeff Kirsher 15608862bf1eSJeff Kirsher static void ioc3_set_multicast_list(struct net_device *dev) 15618862bf1eSJeff Kirsher { 15628862bf1eSJeff Kirsher struct ioc3_private *ip = netdev_priv(dev); 1563cbe7d517SThomas Bogendoerfer struct ioc3_ethregs *regs = ip->regs; 1564cbe7d517SThomas Bogendoerfer struct netdev_hw_addr *ha; 15658862bf1eSJeff Kirsher u64 ehar = 0; 15668862bf1eSJeff Kirsher 15678862bf1eSJeff Kirsher netif_stop_queue(dev); /* Lock out others. */ 15688862bf1eSJeff Kirsher 15698862bf1eSJeff Kirsher if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ 15708862bf1eSJeff Kirsher ip->emcr |= EMCR_PROMISC; 1571cbe7d517SThomas Bogendoerfer writel(ip->emcr, ®s->emcr); 1572cbe7d517SThomas Bogendoerfer readl(®s->emcr); 15738862bf1eSJeff Kirsher } else { 15748862bf1eSJeff Kirsher ip->emcr &= ~EMCR_PROMISC; 1575cbe7d517SThomas Bogendoerfer writel(ip->emcr, ®s->emcr); /* Clear promiscuous. */ 1576cbe7d517SThomas Bogendoerfer readl(®s->emcr); 15778862bf1eSJeff Kirsher 15788862bf1eSJeff Kirsher if ((dev->flags & IFF_ALLMULTI) || 15798862bf1eSJeff Kirsher (netdev_mc_count(dev) > 64)) { 15808862bf1eSJeff Kirsher /* Too many for hashing to make sense or we want all 1581c1b6a3d8SThomas Bogendoerfer * multicast packets anyway, so skip computing all the 1582c1b6a3d8SThomas Bogendoerfer * hashes and just accept all packets. 1583c1b6a3d8SThomas Bogendoerfer */ 15848862bf1eSJeff Kirsher ip->ehar_h = 0xffffffff; 15858862bf1eSJeff Kirsher ip->ehar_l = 0xffffffff; 15868862bf1eSJeff Kirsher } else { 15878862bf1eSJeff Kirsher netdev_for_each_mc_addr(ha, dev) { 15888862bf1eSJeff Kirsher ehar |= (1UL << ioc3_hash(ha->addr)); 15898862bf1eSJeff Kirsher } 15908862bf1eSJeff Kirsher ip->ehar_h = ehar >> 32; 15918862bf1eSJeff Kirsher ip->ehar_l = ehar & 0xffffffff; 15928862bf1eSJeff Kirsher } 1593cbe7d517SThomas Bogendoerfer writel(ip->ehar_h, ®s->ehar_h); 1594cbe7d517SThomas Bogendoerfer writel(ip->ehar_l, ®s->ehar_l); 15958862bf1eSJeff Kirsher } 15968862bf1eSJeff Kirsher 15978862bf1eSJeff Kirsher netif_wake_queue(dev); /* Let us get going again. */ 15988862bf1eSJeff Kirsher } 15998862bf1eSJeff Kirsher 1600e0fc4441SPeter Hüwe module_pci_driver(ioc3_driver); 16018862bf1eSJeff Kirsher MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>"); 16028862bf1eSJeff Kirsher MODULE_DESCRIPTION("SGI IOC3 Ethernet driver"); 16038862bf1eSJeff Kirsher MODULE_LICENSE("GPL"); 1604