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(&regs->micr) & MICR_BUSY)
409cbe7d517SThomas Bogendoerfer 		;
410cbe7d517SThomas Bogendoerfer 	writel((phy << MICR_PHYADDR_SHIFT) | reg | MICR_READTRIG,
411cbe7d517SThomas Bogendoerfer 	       &regs->micr);
412cbe7d517SThomas Bogendoerfer 	while (readl(&regs->micr) & MICR_BUSY)
413cbe7d517SThomas Bogendoerfer 		;
4148862bf1eSJeff Kirsher 
415cbe7d517SThomas Bogendoerfer 	return readl(&regs->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(&regs->micr) & MICR_BUSY)
424cbe7d517SThomas Bogendoerfer 		;
425cbe7d517SThomas Bogendoerfer 	writel(data, &regs->midr_w);
426cbe7d517SThomas Bogendoerfer 	writel((phy << MICR_PHYADDR_SHIFT) | reg, &regs->micr);
427cbe7d517SThomas Bogendoerfer 	while (readl(&regs->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(&regs->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(&regs->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(&regs->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(&regs->eisr);
674cbe7d517SThomas Bogendoerfer 	writel(eisr, &regs->eisr);
675cbe7d517SThomas Bogendoerfer 	readl(&regs->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, &regs->etcsr);
6948862bf1eSJeff Kirsher 		ip->emcr |= EMCR_DUPLEX;
6958862bf1eSJeff Kirsher 	} else {
696cbe7d517SThomas Bogendoerfer 		writel(ETCSR_HD, &regs->etcsr);
6978862bf1eSJeff Kirsher 		ip->emcr &= ~EMCR_DUPLEX;
6988862bf1eSJeff Kirsher 	}
699cbe7d517SThomas Bogendoerfer 	writel(ip->emcr, &regs->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, &regs->erbr_h);
886cbe7d517SThomas Bogendoerfer 	writel(ring & 0xffffffff, &regs->erbr_l);
887cbe7d517SThomas Bogendoerfer 	writel(ip->rx_ci << 3, &regs->ercir);
888cbe7d517SThomas Bogendoerfer 	writel((ip->rx_pi << 3) | ERPIR_ARM, &regs->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, &regs->etbr_h);
896cbe7d517SThomas Bogendoerfer 	writel(ring & 0xffffffff, &regs->etbr_l);
897cbe7d517SThomas Bogendoerfer 	writel(ip->tx_pi << 7, &regs->etpir);
898cbe7d517SThomas Bogendoerfer 	writel(ip->tx_ci << 7, &regs->etcir);
899cbe7d517SThomas Bogendoerfer 	readl(&regs->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(&regs->emcr) | (EMCR_BUFSIZ | EMCR_RAMPAR), &regs->emcr);
911cbe7d517SThomas Bogendoerfer 	readl(&regs->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(&regs->emcr) & ~EMCR_BUFSIZ, &regs->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, &regs->emcr);		/* Reset		*/
934cbe7d517SThomas Bogendoerfer 	readl(&regs->emcr);			/* Flush WB		*/
9358862bf1eSJeff Kirsher 	udelay(4);				/* Give it time ...	*/
936cbe7d517SThomas Bogendoerfer 	writel(0, &regs->emcr);
937cbe7d517SThomas Bogendoerfer 	readl(&regs->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, &regs->erbar);
9438862bf1eSJeff Kirsher #else
944cbe7d517SThomas Bogendoerfer 	/* Let PCI API get it right */
945cbe7d517SThomas Bogendoerfer 	writel(0, &regs->erbar);
9468862bf1eSJeff Kirsher #endif
947cbe7d517SThomas Bogendoerfer 	readl(&regs->etcdc);			/* Clear on read */
948cbe7d517SThomas Bogendoerfer 	writel(15, &regs->ercsr);		/* RX low watermark  */
949cbe7d517SThomas Bogendoerfer 	writel(0, &regs->ertr);			/* Interrupt immediately */
9508862bf1eSJeff Kirsher 	__ioc3_set_mac_address(dev);
951cbe7d517SThomas Bogendoerfer 	writel(ip->ehar_h, &regs->ehar_h);
952cbe7d517SThomas Bogendoerfer 	writel(ip->ehar_l, &regs->ehar_l);
953cbe7d517SThomas Bogendoerfer 	writel(42, &regs->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, &regs->emcr);
960cbe7d517SThomas Bogendoerfer 	writel(EISR_RXTIMERINT | EISR_RXOFLO | EISR_RXBUFOFLO |
9618862bf1eSJeff Kirsher 	       EISR_RXMEMERR | EISR_RXPARERR | EISR_TXBUFUFLO |
962cbe7d517SThomas Bogendoerfer 	       EISR_TXEXPLICIT | EISR_TXMEMERR, &regs->eier);
963cbe7d517SThomas Bogendoerfer 	readl(&regs->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, &regs->emcr);			/* Shutup */
971cbe7d517SThomas Bogendoerfer 	writel(0, &regs->eier);			/* Disable interrupts */
972cbe7d517SThomas Bogendoerfer 	readl(&regs->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, &regs->emcr);
1572cbe7d517SThomas Bogendoerfer 		readl(&regs->emcr);
15738862bf1eSJeff Kirsher 	} else {
15748862bf1eSJeff Kirsher 		ip->emcr &= ~EMCR_PROMISC;
1575cbe7d517SThomas Bogendoerfer 		writel(ip->emcr, &regs->emcr);		/* Clear promiscuous. */
1576cbe7d517SThomas Bogendoerfer 		readl(&regs->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, &regs->ehar_h);
1594cbe7d517SThomas Bogendoerfer 		writel(ip->ehar_l, &regs->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