1ca7a8e85SJeff Kirsher /* typhoon.c: A Linux Ethernet device driver for 3Com 3CR990 family of NICs */
2ca7a8e85SJeff Kirsher /*
3ca7a8e85SJeff Kirsher 	Written 2002-2004 by David Dillow <dave@thedillows.org>
4ca7a8e85SJeff Kirsher 	Based on code written 1998-2000 by Donald Becker <becker@scyld.com> and
5ca7a8e85SJeff Kirsher 	Linux 2.2.x driver by David P. McLean <davidpmclean@yahoo.com>.
6ca7a8e85SJeff Kirsher 
7ca7a8e85SJeff Kirsher 	This software may be used and distributed according to the terms of
8ca7a8e85SJeff Kirsher 	the GNU General Public License (GPL), incorporated herein by reference.
9ca7a8e85SJeff Kirsher 	Drivers based on or derived from this code fall under the GPL and must
10ca7a8e85SJeff Kirsher 	retain the authorship, copyright and license notice.  This file is not
11ca7a8e85SJeff Kirsher 	a complete program and may only be used when the entire operating
12ca7a8e85SJeff Kirsher 	system is licensed under the GPL.
13ca7a8e85SJeff Kirsher 
14ca7a8e85SJeff Kirsher 	This software is available on a public web site. It may enable
15ca7a8e85SJeff Kirsher 	cryptographic capabilities of the 3Com hardware, and may be
16ca7a8e85SJeff Kirsher 	exported from the United States under License Exception "TSU"
17ca7a8e85SJeff Kirsher 	pursuant to 15 C.F.R. Section 740.13(e).
18ca7a8e85SJeff Kirsher 
19ca7a8e85SJeff Kirsher 	This work was funded by the National Library of Medicine under
20ca7a8e85SJeff Kirsher 	the Department of Energy project number 0274DD06D1 and NLM project
21ca7a8e85SJeff Kirsher 	number Y1-LM-2015-01.
22ca7a8e85SJeff Kirsher 
23ca7a8e85SJeff Kirsher 	This driver is designed for the 3Com 3CR990 Family of cards with the
24ca7a8e85SJeff Kirsher 	3XP Processor. It has been tested on x86 and sparc64.
25ca7a8e85SJeff Kirsher 
26ca7a8e85SJeff Kirsher 	KNOWN ISSUES:
27ca7a8e85SJeff Kirsher 	*) Cannot DMA Rx packets to a 2 byte aligned address. Also firmware
28ca7a8e85SJeff Kirsher 		issue. Hopefully 3Com will fix it.
29ca7a8e85SJeff Kirsher 	*) Waiting for a command response takes 8ms due to non-preemptable
30ca7a8e85SJeff Kirsher 		polling. Only significant for getting stats and creating
31ca7a8e85SJeff Kirsher 		SAs, but an ugly wart never the less.
32ca7a8e85SJeff Kirsher 
33ca7a8e85SJeff Kirsher 	TODO:
34ca7a8e85SJeff Kirsher 	*) Doesn't do IPSEC offloading. Yet. Keep yer pants on, it's coming.
35ca7a8e85SJeff Kirsher 	*) Add more support for ethtool (especially for NIC stats)
36ca7a8e85SJeff Kirsher 	*) Allow disabling of RX checksum offloading
37ca7a8e85SJeff Kirsher 	*) Fix MAC changing to work while the interface is up
38ca7a8e85SJeff Kirsher 		(Need to put commands on the TX ring, which changes
39ca7a8e85SJeff Kirsher 		the locking)
40ca7a8e85SJeff Kirsher 	*) Add in FCS to {rx,tx}_bytes, since the hardware doesn't. See
41ca7a8e85SJeff Kirsher 		http://oss.sgi.com/cgi-bin/mesg.cgi?a=netdev&i=20031215152211.7003fe8e.rddunlap%40osdl.org
42ca7a8e85SJeff Kirsher */
43ca7a8e85SJeff Kirsher 
44ca7a8e85SJeff Kirsher /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
45ca7a8e85SJeff Kirsher  * Setting to > 1518 effectively disables this feature.
46ca7a8e85SJeff Kirsher  */
47ca7a8e85SJeff Kirsher static int rx_copybreak = 200;
48ca7a8e85SJeff Kirsher 
49ca7a8e85SJeff Kirsher /* Should we use MMIO or Port IO?
50ca7a8e85SJeff Kirsher  * 0: Port IO
51ca7a8e85SJeff Kirsher  * 1: MMIO
52ca7a8e85SJeff Kirsher  * 2: Try MMIO, fallback to Port IO
53ca7a8e85SJeff Kirsher  */
54ca7a8e85SJeff Kirsher static unsigned int use_mmio = 2;
55ca7a8e85SJeff Kirsher 
56ca7a8e85SJeff Kirsher /* end user-configurable values */
57ca7a8e85SJeff Kirsher 
58ca7a8e85SJeff Kirsher /* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
59ca7a8e85SJeff Kirsher  */
60ca7a8e85SJeff Kirsher static const int multicast_filter_limit = 32;
61ca7a8e85SJeff Kirsher 
62ca7a8e85SJeff Kirsher /* Operational parameters that are set at compile time. */
63ca7a8e85SJeff Kirsher 
64ca7a8e85SJeff Kirsher /* Keep the ring sizes a power of two for compile efficiency.
65ca7a8e85SJeff Kirsher  * The compiler will convert <unsigned>'%'<2^N> into a bit mask.
66ca7a8e85SJeff Kirsher  * Making the Tx ring too large decreases the effectiveness of channel
67ca7a8e85SJeff Kirsher  * bonding and packet priority.
68ca7a8e85SJeff Kirsher  * There are no ill effects from too-large receive rings.
69ca7a8e85SJeff Kirsher  *
70ca7a8e85SJeff Kirsher  * We don't currently use the Hi Tx ring so, don't make it very big.
71ca7a8e85SJeff Kirsher  *
72ca7a8e85SJeff Kirsher  * Beware that if we start using the Hi Tx ring, we will need to change
73ca7a8e85SJeff Kirsher  * typhoon_num_free_tx() and typhoon_tx_complete() to account for that.
74ca7a8e85SJeff Kirsher  */
75ca7a8e85SJeff Kirsher #define TXHI_ENTRIES		2
76ca7a8e85SJeff Kirsher #define TXLO_ENTRIES		128
77ca7a8e85SJeff Kirsher #define RX_ENTRIES		32
78ca7a8e85SJeff Kirsher #define COMMAND_ENTRIES		16
79ca7a8e85SJeff Kirsher #define RESPONSE_ENTRIES	32
80ca7a8e85SJeff Kirsher 
81ca7a8e85SJeff Kirsher #define COMMAND_RING_SIZE	(COMMAND_ENTRIES * sizeof(struct cmd_desc))
82ca7a8e85SJeff Kirsher #define RESPONSE_RING_SIZE	(RESPONSE_ENTRIES * sizeof(struct resp_desc))
83ca7a8e85SJeff Kirsher 
84ca7a8e85SJeff Kirsher /* The 3XP will preload and remove 64 entries from the free buffer
85ca7a8e85SJeff Kirsher  * list, and we need one entry to keep the ring from wrapping, so
86ca7a8e85SJeff Kirsher  * to keep this a power of two, we use 128 entries.
87ca7a8e85SJeff Kirsher  */
88ca7a8e85SJeff Kirsher #define RXFREE_ENTRIES		128
89ca7a8e85SJeff Kirsher #define RXENT_ENTRIES		(RXFREE_ENTRIES - 1)
90ca7a8e85SJeff Kirsher 
91ca7a8e85SJeff Kirsher /* Operational parameters that usually are not changed. */
92ca7a8e85SJeff Kirsher 
93ca7a8e85SJeff Kirsher /* Time in jiffies before concluding the transmitter is hung. */
94ca7a8e85SJeff Kirsher #define TX_TIMEOUT  (2*HZ)
95ca7a8e85SJeff Kirsher 
96ca7a8e85SJeff Kirsher #define PKT_BUF_SZ		1536
97ca7a8e85SJeff Kirsher #define FIRMWARE_NAME		"3com/typhoon.bin"
98ca7a8e85SJeff Kirsher 
99ca7a8e85SJeff Kirsher #define pr_fmt(fmt)		KBUILD_MODNAME " " fmt
100ca7a8e85SJeff Kirsher 
101ca7a8e85SJeff Kirsher #include <linux/module.h>
102ca7a8e85SJeff Kirsher #include <linux/kernel.h>
103ca7a8e85SJeff Kirsher #include <linux/sched.h>
104ca7a8e85SJeff Kirsher #include <linux/string.h>
105ca7a8e85SJeff Kirsher #include <linux/timer.h>
106ca7a8e85SJeff Kirsher #include <linux/errno.h>
107ca7a8e85SJeff Kirsher #include <linux/ioport.h>
108ca7a8e85SJeff Kirsher #include <linux/interrupt.h>
109ca7a8e85SJeff Kirsher #include <linux/pci.h>
110ca7a8e85SJeff Kirsher #include <linux/netdevice.h>
111ca7a8e85SJeff Kirsher #include <linux/etherdevice.h>
112ca7a8e85SJeff Kirsher #include <linux/skbuff.h>
113ca7a8e85SJeff Kirsher #include <linux/mm.h>
114ca7a8e85SJeff Kirsher #include <linux/init.h>
115ca7a8e85SJeff Kirsher #include <linux/delay.h>
116ca7a8e85SJeff Kirsher #include <linux/ethtool.h>
117ca7a8e85SJeff Kirsher #include <linux/if_vlan.h>
118ca7a8e85SJeff Kirsher #include <linux/crc32.h>
119ca7a8e85SJeff Kirsher #include <linux/bitops.h>
120ca7a8e85SJeff Kirsher #include <asm/processor.h>
121ca7a8e85SJeff Kirsher #include <asm/io.h>
122ca7a8e85SJeff Kirsher #include <asm/uaccess.h>
123ca7a8e85SJeff Kirsher #include <linux/in6.h>
124ca7a8e85SJeff Kirsher #include <linux/dma-mapping.h>
125ca7a8e85SJeff Kirsher #include <linux/firmware.h>
126ca7a8e85SJeff Kirsher 
127ca7a8e85SJeff Kirsher #include "typhoon.h"
128ca7a8e85SJeff Kirsher 
129ca7a8e85SJeff Kirsher MODULE_AUTHOR("David Dillow <dave@thedillows.org>");
130ca7a8e85SJeff Kirsher MODULE_VERSION("1.0");
131ca7a8e85SJeff Kirsher MODULE_LICENSE("GPL");
132ca7a8e85SJeff Kirsher MODULE_FIRMWARE(FIRMWARE_NAME);
133ca7a8e85SJeff Kirsher MODULE_DESCRIPTION("3Com Typhoon Family (3C990, 3CR990, and variants)");
134ca7a8e85SJeff Kirsher MODULE_PARM_DESC(rx_copybreak, "Packets smaller than this are copied and "
135ca7a8e85SJeff Kirsher 			       "the buffer given back to the NIC. Default "
136ca7a8e85SJeff Kirsher 			       "is 200.");
137ca7a8e85SJeff Kirsher MODULE_PARM_DESC(use_mmio, "Use MMIO (1) or PIO(0) to access the NIC. "
138ca7a8e85SJeff Kirsher 			   "Default is to try MMIO and fallback to PIO.");
139ca7a8e85SJeff Kirsher module_param(rx_copybreak, int, 0);
140ca7a8e85SJeff Kirsher module_param(use_mmio, int, 0);
141ca7a8e85SJeff Kirsher 
142ca7a8e85SJeff Kirsher #if defined(NETIF_F_TSO) && MAX_SKB_FRAGS > 32
143ca7a8e85SJeff Kirsher #warning Typhoon only supports 32 entries in its SG list for TSO, disabling TSO
144ca7a8e85SJeff Kirsher #undef NETIF_F_TSO
145ca7a8e85SJeff Kirsher #endif
146ca7a8e85SJeff Kirsher 
147ca7a8e85SJeff Kirsher #if TXLO_ENTRIES <= (2 * MAX_SKB_FRAGS)
148ca7a8e85SJeff Kirsher #error TX ring too small!
149ca7a8e85SJeff Kirsher #endif
150ca7a8e85SJeff Kirsher 
151ca7a8e85SJeff Kirsher struct typhoon_card_info {
152ca7a8e85SJeff Kirsher 	const char *name;
153ca7a8e85SJeff Kirsher 	const int capabilities;
154ca7a8e85SJeff Kirsher };
155ca7a8e85SJeff Kirsher 
156ca7a8e85SJeff Kirsher #define TYPHOON_CRYPTO_NONE		0x00
157ca7a8e85SJeff Kirsher #define TYPHOON_CRYPTO_DES		0x01
158ca7a8e85SJeff Kirsher #define TYPHOON_CRYPTO_3DES		0x02
159ca7a8e85SJeff Kirsher #define	TYPHOON_CRYPTO_VARIABLE		0x04
160ca7a8e85SJeff Kirsher #define TYPHOON_FIBER			0x08
161ca7a8e85SJeff Kirsher #define TYPHOON_WAKEUP_NEEDS_RESET	0x10
162ca7a8e85SJeff Kirsher 
163ca7a8e85SJeff Kirsher enum typhoon_cards {
164ca7a8e85SJeff Kirsher 	TYPHOON_TX = 0, TYPHOON_TX95, TYPHOON_TX97, TYPHOON_SVR,
165ca7a8e85SJeff Kirsher 	TYPHOON_SVR95, TYPHOON_SVR97, TYPHOON_TXM, TYPHOON_BSVR,
166ca7a8e85SJeff Kirsher 	TYPHOON_FX95, TYPHOON_FX97, TYPHOON_FX95SVR, TYPHOON_FX97SVR,
167ca7a8e85SJeff Kirsher 	TYPHOON_FXM,
168ca7a8e85SJeff Kirsher };
169ca7a8e85SJeff Kirsher 
170ca7a8e85SJeff Kirsher /* directly indexed by enum typhoon_cards, above */
171ca7a8e85SJeff Kirsher static struct typhoon_card_info typhoon_card_info[] __devinitdata = {
172ca7a8e85SJeff Kirsher 	{ "3Com Typhoon (3C990-TX)",
173ca7a8e85SJeff Kirsher 		TYPHOON_CRYPTO_NONE},
174ca7a8e85SJeff Kirsher 	{ "3Com Typhoon (3CR990-TX-95)",
175ca7a8e85SJeff Kirsher 		TYPHOON_CRYPTO_DES},
176ca7a8e85SJeff Kirsher 	{ "3Com Typhoon (3CR990-TX-97)",
177ca7a8e85SJeff Kirsher 	 	TYPHOON_CRYPTO_DES | TYPHOON_CRYPTO_3DES},
178ca7a8e85SJeff Kirsher 	{ "3Com Typhoon (3C990SVR)",
179ca7a8e85SJeff Kirsher 		TYPHOON_CRYPTO_NONE},
180ca7a8e85SJeff Kirsher 	{ "3Com Typhoon (3CR990SVR95)",
181ca7a8e85SJeff Kirsher 		TYPHOON_CRYPTO_DES},
182ca7a8e85SJeff Kirsher 	{ "3Com Typhoon (3CR990SVR97)",
183ca7a8e85SJeff Kirsher 	 	TYPHOON_CRYPTO_DES | TYPHOON_CRYPTO_3DES},
184ca7a8e85SJeff Kirsher 	{ "3Com Typhoon2 (3C990B-TX-M)",
185ca7a8e85SJeff Kirsher 		TYPHOON_CRYPTO_VARIABLE},
186ca7a8e85SJeff Kirsher 	{ "3Com Typhoon2 (3C990BSVR)",
187ca7a8e85SJeff Kirsher 		TYPHOON_CRYPTO_VARIABLE},
188ca7a8e85SJeff Kirsher 	{ "3Com Typhoon (3CR990-FX-95)",
189ca7a8e85SJeff Kirsher 		TYPHOON_CRYPTO_DES | TYPHOON_FIBER},
190ca7a8e85SJeff Kirsher 	{ "3Com Typhoon (3CR990-FX-97)",
191ca7a8e85SJeff Kirsher 	 	TYPHOON_CRYPTO_DES | TYPHOON_CRYPTO_3DES | TYPHOON_FIBER},
192ca7a8e85SJeff Kirsher 	{ "3Com Typhoon (3CR990-FX-95 Server)",
193ca7a8e85SJeff Kirsher 	 	TYPHOON_CRYPTO_DES | TYPHOON_FIBER},
194ca7a8e85SJeff Kirsher 	{ "3Com Typhoon (3CR990-FX-97 Server)",
195ca7a8e85SJeff Kirsher 	 	TYPHOON_CRYPTO_DES | TYPHOON_CRYPTO_3DES | TYPHOON_FIBER},
196ca7a8e85SJeff Kirsher 	{ "3Com Typhoon2 (3C990B-FX-97)",
197ca7a8e85SJeff Kirsher 		TYPHOON_CRYPTO_VARIABLE | TYPHOON_FIBER},
198ca7a8e85SJeff Kirsher };
199ca7a8e85SJeff Kirsher 
200ca7a8e85SJeff Kirsher /* Notes on the new subsystem numbering scheme:
201ca7a8e85SJeff Kirsher  * bits 0-1 indicate crypto capabilities: (0) variable, (1) DES, or (2) 3DES
202ca7a8e85SJeff Kirsher  * bit 4 indicates if this card has secured firmware (we don't support it)
203ca7a8e85SJeff Kirsher  * bit 8 indicates if this is a (0) copper or (1) fiber card
204ca7a8e85SJeff Kirsher  * bits 12-16 indicate card type: (0) client and (1) server
205ca7a8e85SJeff Kirsher  */
206ca7a8e85SJeff Kirsher static DEFINE_PCI_DEVICE_TABLE(typhoon_pci_tbl) = {
207ca7a8e85SJeff Kirsher 	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990,
208ca7a8e85SJeff Kirsher 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0,TYPHOON_TX },
209ca7a8e85SJeff Kirsher 	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_TX_95,
210ca7a8e85SJeff Kirsher 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPHOON_TX95 },
211ca7a8e85SJeff Kirsher 	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_TX_97,
212ca7a8e85SJeff Kirsher 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPHOON_TX97 },
213ca7a8e85SJeff Kirsher 	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990B,
214ca7a8e85SJeff Kirsher 	  PCI_ANY_ID, 0x1000, 0, 0, TYPHOON_TXM },
215ca7a8e85SJeff Kirsher 	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990B,
216ca7a8e85SJeff Kirsher 	  PCI_ANY_ID, 0x1102, 0, 0, TYPHOON_FXM },
217ca7a8e85SJeff Kirsher 	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990B,
218ca7a8e85SJeff Kirsher 	  PCI_ANY_ID, 0x2000, 0, 0, TYPHOON_BSVR },
219ca7a8e85SJeff Kirsher 	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_FX,
220ca7a8e85SJeff Kirsher 	  PCI_ANY_ID, 0x1101, 0, 0, TYPHOON_FX95 },
221ca7a8e85SJeff Kirsher 	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_FX,
222ca7a8e85SJeff Kirsher 	  PCI_ANY_ID, 0x1102, 0, 0, TYPHOON_FX97 },
223ca7a8e85SJeff Kirsher 	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_FX,
224ca7a8e85SJeff Kirsher 	  PCI_ANY_ID, 0x2101, 0, 0, TYPHOON_FX95SVR },
225ca7a8e85SJeff Kirsher 	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_FX,
226ca7a8e85SJeff Kirsher 	  PCI_ANY_ID, 0x2102, 0, 0, TYPHOON_FX97SVR },
227ca7a8e85SJeff Kirsher 	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990SVR95,
228ca7a8e85SJeff Kirsher 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPHOON_SVR95 },
229ca7a8e85SJeff Kirsher 	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990SVR97,
230ca7a8e85SJeff Kirsher 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPHOON_SVR97 },
231ca7a8e85SJeff Kirsher 	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990SVR,
232ca7a8e85SJeff Kirsher 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPHOON_SVR },
233ca7a8e85SJeff Kirsher 	{ 0, }
234ca7a8e85SJeff Kirsher };
235ca7a8e85SJeff Kirsher MODULE_DEVICE_TABLE(pci, typhoon_pci_tbl);
236ca7a8e85SJeff Kirsher 
237ca7a8e85SJeff Kirsher /* Define the shared memory area
238ca7a8e85SJeff Kirsher  * Align everything the 3XP will normally be using.
239ca7a8e85SJeff Kirsher  * We'll need to move/align txHi if we start using that ring.
240ca7a8e85SJeff Kirsher  */
241ca7a8e85SJeff Kirsher #define __3xp_aligned	____cacheline_aligned
242ca7a8e85SJeff Kirsher struct typhoon_shared {
243ca7a8e85SJeff Kirsher 	struct typhoon_interface	iface;
244ca7a8e85SJeff Kirsher 	struct typhoon_indexes		indexes			__3xp_aligned;
245ca7a8e85SJeff Kirsher 	struct tx_desc			txLo[TXLO_ENTRIES] 	__3xp_aligned;
246ca7a8e85SJeff Kirsher 	struct rx_desc			rxLo[RX_ENTRIES]	__3xp_aligned;
247ca7a8e85SJeff Kirsher 	struct rx_desc			rxHi[RX_ENTRIES]	__3xp_aligned;
248ca7a8e85SJeff Kirsher 	struct cmd_desc			cmd[COMMAND_ENTRIES]	__3xp_aligned;
249ca7a8e85SJeff Kirsher 	struct resp_desc		resp[RESPONSE_ENTRIES]	__3xp_aligned;
250ca7a8e85SJeff Kirsher 	struct rx_free			rxBuff[RXFREE_ENTRIES]	__3xp_aligned;
251ca7a8e85SJeff Kirsher 	u32				zeroWord;
252ca7a8e85SJeff Kirsher 	struct tx_desc			txHi[TXHI_ENTRIES];
253ca7a8e85SJeff Kirsher } __packed;
254ca7a8e85SJeff Kirsher 
255ca7a8e85SJeff Kirsher struct rxbuff_ent {
256ca7a8e85SJeff Kirsher 	struct sk_buff *skb;
257ca7a8e85SJeff Kirsher 	dma_addr_t	dma_addr;
258ca7a8e85SJeff Kirsher };
259ca7a8e85SJeff Kirsher 
260ca7a8e85SJeff Kirsher struct typhoon {
261ca7a8e85SJeff Kirsher 	/* Tx cache line section */
262ca7a8e85SJeff Kirsher 	struct transmit_ring 	txLoRing	____cacheline_aligned;
263ca7a8e85SJeff Kirsher 	struct pci_dev *	tx_pdev;
264ca7a8e85SJeff Kirsher 	void __iomem		*tx_ioaddr;
265ca7a8e85SJeff Kirsher 	u32			txlo_dma_addr;
266ca7a8e85SJeff Kirsher 
267ca7a8e85SJeff Kirsher 	/* Irq/Rx cache line section */
268ca7a8e85SJeff Kirsher 	void __iomem		*ioaddr		____cacheline_aligned;
269ca7a8e85SJeff Kirsher 	struct typhoon_indexes *indexes;
270ca7a8e85SJeff Kirsher 	u8			awaiting_resp;
271ca7a8e85SJeff Kirsher 	u8			duplex;
272ca7a8e85SJeff Kirsher 	u8			speed;
273ca7a8e85SJeff Kirsher 	u8			card_state;
274ca7a8e85SJeff Kirsher 	struct basic_ring	rxLoRing;
275ca7a8e85SJeff Kirsher 	struct pci_dev *	pdev;
276ca7a8e85SJeff Kirsher 	struct net_device *	dev;
277ca7a8e85SJeff Kirsher 	struct napi_struct	napi;
278ca7a8e85SJeff Kirsher 	struct basic_ring	rxHiRing;
279ca7a8e85SJeff Kirsher 	struct basic_ring	rxBuffRing;
280ca7a8e85SJeff Kirsher 	struct rxbuff_ent	rxbuffers[RXENT_ENTRIES];
281ca7a8e85SJeff Kirsher 
282ca7a8e85SJeff Kirsher 	/* general section */
283ca7a8e85SJeff Kirsher 	spinlock_t		command_lock	____cacheline_aligned;
284ca7a8e85SJeff Kirsher 	struct basic_ring	cmdRing;
285ca7a8e85SJeff Kirsher 	struct basic_ring	respRing;
286ca7a8e85SJeff Kirsher 	struct net_device_stats	stats;
287ca7a8e85SJeff Kirsher 	struct net_device_stats	stats_saved;
288ca7a8e85SJeff Kirsher 	struct typhoon_shared *	shared;
289ca7a8e85SJeff Kirsher 	dma_addr_t		shared_dma;
290ca7a8e85SJeff Kirsher 	__le16			xcvr_select;
291ca7a8e85SJeff Kirsher 	__le16			wol_events;
292ca7a8e85SJeff Kirsher 	__le32			offload;
293ca7a8e85SJeff Kirsher 
294ca7a8e85SJeff Kirsher 	/* unused stuff (future use) */
295ca7a8e85SJeff Kirsher 	int			capabilities;
296ca7a8e85SJeff Kirsher 	struct transmit_ring 	txHiRing;
297ca7a8e85SJeff Kirsher };
298ca7a8e85SJeff Kirsher 
299ca7a8e85SJeff Kirsher enum completion_wait_values {
300ca7a8e85SJeff Kirsher 	NoWait = 0, WaitNoSleep, WaitSleep,
301ca7a8e85SJeff Kirsher };
302ca7a8e85SJeff Kirsher 
303ca7a8e85SJeff Kirsher /* These are the values for the typhoon.card_state variable.
304ca7a8e85SJeff Kirsher  * These determine where the statistics will come from in get_stats().
305ca7a8e85SJeff Kirsher  * The sleep image does not support the statistics we need.
306ca7a8e85SJeff Kirsher  */
307ca7a8e85SJeff Kirsher enum state_values {
308ca7a8e85SJeff Kirsher 	Sleeping = 0, Running,
309ca7a8e85SJeff Kirsher };
310ca7a8e85SJeff Kirsher 
311ca7a8e85SJeff Kirsher /* PCI writes are not guaranteed to be posted in order, but outstanding writes
312ca7a8e85SJeff Kirsher  * cannot pass a read, so this forces current writes to post.
313ca7a8e85SJeff Kirsher  */
314ca7a8e85SJeff Kirsher #define typhoon_post_pci_writes(x) \
315ca7a8e85SJeff Kirsher 	do { if(likely(use_mmio)) ioread32(x+TYPHOON_REG_HEARTBEAT); } while(0)
316ca7a8e85SJeff Kirsher 
317ca7a8e85SJeff Kirsher /* We'll wait up to six seconds for a reset, and half a second normally.
318ca7a8e85SJeff Kirsher  */
319ca7a8e85SJeff Kirsher #define TYPHOON_UDELAY			50
320ca7a8e85SJeff Kirsher #define TYPHOON_RESET_TIMEOUT_SLEEP	(6 * HZ)
321ca7a8e85SJeff Kirsher #define TYPHOON_RESET_TIMEOUT_NOSLEEP	((6 * 1000000) / TYPHOON_UDELAY)
322ca7a8e85SJeff Kirsher #define TYPHOON_WAIT_TIMEOUT		((1000000 / 2) / TYPHOON_UDELAY)
323ca7a8e85SJeff Kirsher 
324ca7a8e85SJeff Kirsher #if defined(NETIF_F_TSO)
325ca7a8e85SJeff Kirsher #define skb_tso_size(x)		(skb_shinfo(x)->gso_size)
326ca7a8e85SJeff Kirsher #define TSO_NUM_DESCRIPTORS	2
327ca7a8e85SJeff Kirsher #define TSO_OFFLOAD_ON		TYPHOON_OFFLOAD_TCP_SEGMENT
328ca7a8e85SJeff Kirsher #else
329ca7a8e85SJeff Kirsher #define NETIF_F_TSO 		0
330ca7a8e85SJeff Kirsher #define skb_tso_size(x) 	0
331ca7a8e85SJeff Kirsher #define TSO_NUM_DESCRIPTORS	0
332ca7a8e85SJeff Kirsher #define TSO_OFFLOAD_ON		0
333ca7a8e85SJeff Kirsher #endif
334ca7a8e85SJeff Kirsher 
335ca7a8e85SJeff Kirsher static inline void
336ca7a8e85SJeff Kirsher typhoon_inc_index(u32 *index, const int count, const int num_entries)
337ca7a8e85SJeff Kirsher {
338ca7a8e85SJeff Kirsher 	/* Increment a ring index -- we can use this for all rings execept
339ca7a8e85SJeff Kirsher 	 * the Rx rings, as they use different size descriptors
340ca7a8e85SJeff Kirsher 	 * otherwise, everything is the same size as a cmd_desc
341ca7a8e85SJeff Kirsher 	 */
342ca7a8e85SJeff Kirsher 	*index += count * sizeof(struct cmd_desc);
343ca7a8e85SJeff Kirsher 	*index %= num_entries * sizeof(struct cmd_desc);
344ca7a8e85SJeff Kirsher }
345ca7a8e85SJeff Kirsher 
346ca7a8e85SJeff Kirsher static inline void
347ca7a8e85SJeff Kirsher typhoon_inc_cmd_index(u32 *index, const int count)
348ca7a8e85SJeff Kirsher {
349ca7a8e85SJeff Kirsher 	typhoon_inc_index(index, count, COMMAND_ENTRIES);
350ca7a8e85SJeff Kirsher }
351ca7a8e85SJeff Kirsher 
352ca7a8e85SJeff Kirsher static inline void
353ca7a8e85SJeff Kirsher typhoon_inc_resp_index(u32 *index, const int count)
354ca7a8e85SJeff Kirsher {
355ca7a8e85SJeff Kirsher 	typhoon_inc_index(index, count, RESPONSE_ENTRIES);
356ca7a8e85SJeff Kirsher }
357ca7a8e85SJeff Kirsher 
358ca7a8e85SJeff Kirsher static inline void
359ca7a8e85SJeff Kirsher typhoon_inc_rxfree_index(u32 *index, const int count)
360ca7a8e85SJeff Kirsher {
361ca7a8e85SJeff Kirsher 	typhoon_inc_index(index, count, RXFREE_ENTRIES);
362ca7a8e85SJeff Kirsher }
363ca7a8e85SJeff Kirsher 
364ca7a8e85SJeff Kirsher static inline void
365ca7a8e85SJeff Kirsher typhoon_inc_tx_index(u32 *index, const int count)
366ca7a8e85SJeff Kirsher {
367ca7a8e85SJeff Kirsher 	/* if we start using the Hi Tx ring, this needs updateing */
368ca7a8e85SJeff Kirsher 	typhoon_inc_index(index, count, TXLO_ENTRIES);
369ca7a8e85SJeff Kirsher }
370ca7a8e85SJeff Kirsher 
371ca7a8e85SJeff Kirsher static inline void
372ca7a8e85SJeff Kirsher typhoon_inc_rx_index(u32 *index, const int count)
373ca7a8e85SJeff Kirsher {
374ca7a8e85SJeff Kirsher 	/* sizeof(struct rx_desc) != sizeof(struct cmd_desc) */
375ca7a8e85SJeff Kirsher 	*index += count * sizeof(struct rx_desc);
376ca7a8e85SJeff Kirsher 	*index %= RX_ENTRIES * sizeof(struct rx_desc);
377ca7a8e85SJeff Kirsher }
378ca7a8e85SJeff Kirsher 
379ca7a8e85SJeff Kirsher static int
380ca7a8e85SJeff Kirsher typhoon_reset(void __iomem *ioaddr, int wait_type)
381ca7a8e85SJeff Kirsher {
382ca7a8e85SJeff Kirsher 	int i, err = 0;
383ca7a8e85SJeff Kirsher 	int timeout;
384ca7a8e85SJeff Kirsher 
385ca7a8e85SJeff Kirsher 	if(wait_type == WaitNoSleep)
386ca7a8e85SJeff Kirsher 		timeout = TYPHOON_RESET_TIMEOUT_NOSLEEP;
387ca7a8e85SJeff Kirsher 	else
388ca7a8e85SJeff Kirsher 		timeout = TYPHOON_RESET_TIMEOUT_SLEEP;
389ca7a8e85SJeff Kirsher 
390ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK);
391ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_STATUS);
392ca7a8e85SJeff Kirsher 
393ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_RESET_ALL, ioaddr + TYPHOON_REG_SOFT_RESET);
394ca7a8e85SJeff Kirsher 	typhoon_post_pci_writes(ioaddr);
395ca7a8e85SJeff Kirsher 	udelay(1);
396ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_RESET_NONE, ioaddr + TYPHOON_REG_SOFT_RESET);
397ca7a8e85SJeff Kirsher 
398ca7a8e85SJeff Kirsher 	if(wait_type != NoWait) {
399ca7a8e85SJeff Kirsher 		for(i = 0; i < timeout; i++) {
400ca7a8e85SJeff Kirsher 			if(ioread32(ioaddr + TYPHOON_REG_STATUS) ==
401ca7a8e85SJeff Kirsher 			   TYPHOON_STATUS_WAITING_FOR_HOST)
402ca7a8e85SJeff Kirsher 				goto out;
403ca7a8e85SJeff Kirsher 
404ca7a8e85SJeff Kirsher 			if(wait_type == WaitSleep)
405ca7a8e85SJeff Kirsher 				schedule_timeout_uninterruptible(1);
406ca7a8e85SJeff Kirsher 			else
407ca7a8e85SJeff Kirsher 				udelay(TYPHOON_UDELAY);
408ca7a8e85SJeff Kirsher 		}
409ca7a8e85SJeff Kirsher 
410ca7a8e85SJeff Kirsher 		err = -ETIMEDOUT;
411ca7a8e85SJeff Kirsher 	}
412ca7a8e85SJeff Kirsher 
413ca7a8e85SJeff Kirsher out:
414ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK);
415ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_STATUS);
416ca7a8e85SJeff Kirsher 
417ca7a8e85SJeff Kirsher 	/* The 3XP seems to need a little extra time to complete the load
418ca7a8e85SJeff Kirsher 	 * of the sleep image before we can reliably boot it. Failure to
419ca7a8e85SJeff Kirsher 	 * do this occasionally results in a hung adapter after boot in
420ca7a8e85SJeff Kirsher 	 * typhoon_init_one() while trying to read the MAC address or
421ca7a8e85SJeff Kirsher 	 * putting the card to sleep. 3Com's driver waits 5ms, but
422ca7a8e85SJeff Kirsher 	 * that seems to be overkill. However, if we can sleep, we might
423ca7a8e85SJeff Kirsher 	 * as well give it that much time. Otherwise, we'll give it 500us,
424ca7a8e85SJeff Kirsher 	 * which should be enough (I've see it work well at 100us, but still
425ca7a8e85SJeff Kirsher 	 * saw occasional problems.)
426ca7a8e85SJeff Kirsher 	 */
427ca7a8e85SJeff Kirsher 	if(wait_type == WaitSleep)
428ca7a8e85SJeff Kirsher 		msleep(5);
429ca7a8e85SJeff Kirsher 	else
430ca7a8e85SJeff Kirsher 		udelay(500);
431ca7a8e85SJeff Kirsher 	return err;
432ca7a8e85SJeff Kirsher }
433ca7a8e85SJeff Kirsher 
434ca7a8e85SJeff Kirsher static int
435ca7a8e85SJeff Kirsher typhoon_wait_status(void __iomem *ioaddr, u32 wait_value)
436ca7a8e85SJeff Kirsher {
437ca7a8e85SJeff Kirsher 	int i, err = 0;
438ca7a8e85SJeff Kirsher 
439ca7a8e85SJeff Kirsher 	for(i = 0; i < TYPHOON_WAIT_TIMEOUT; i++) {
440ca7a8e85SJeff Kirsher 		if(ioread32(ioaddr + TYPHOON_REG_STATUS) == wait_value)
441ca7a8e85SJeff Kirsher 			goto out;
442ca7a8e85SJeff Kirsher 		udelay(TYPHOON_UDELAY);
443ca7a8e85SJeff Kirsher 	}
444ca7a8e85SJeff Kirsher 
445ca7a8e85SJeff Kirsher 	err = -ETIMEDOUT;
446ca7a8e85SJeff Kirsher 
447ca7a8e85SJeff Kirsher out:
448ca7a8e85SJeff Kirsher 	return err;
449ca7a8e85SJeff Kirsher }
450ca7a8e85SJeff Kirsher 
451ca7a8e85SJeff Kirsher static inline void
452ca7a8e85SJeff Kirsher typhoon_media_status(struct net_device *dev, struct resp_desc *resp)
453ca7a8e85SJeff Kirsher {
454ca7a8e85SJeff Kirsher 	if(resp->parm1 & TYPHOON_MEDIA_STAT_NO_LINK)
455ca7a8e85SJeff Kirsher 		netif_carrier_off(dev);
456ca7a8e85SJeff Kirsher 	else
457ca7a8e85SJeff Kirsher 		netif_carrier_on(dev);
458ca7a8e85SJeff Kirsher }
459ca7a8e85SJeff Kirsher 
460ca7a8e85SJeff Kirsher static inline void
461ca7a8e85SJeff Kirsher typhoon_hello(struct typhoon *tp)
462ca7a8e85SJeff Kirsher {
463ca7a8e85SJeff Kirsher 	struct basic_ring *ring = &tp->cmdRing;
464ca7a8e85SJeff Kirsher 	struct cmd_desc *cmd;
465ca7a8e85SJeff Kirsher 
466ca7a8e85SJeff Kirsher 	/* We only get a hello request if we've not sent anything to the
467ca7a8e85SJeff Kirsher 	 * card in a long while. If the lock is held, then we're in the
468ca7a8e85SJeff Kirsher 	 * process of issuing a command, so we don't need to respond.
469ca7a8e85SJeff Kirsher 	 */
470ca7a8e85SJeff Kirsher 	if(spin_trylock(&tp->command_lock)) {
471ca7a8e85SJeff Kirsher 		cmd = (struct cmd_desc *)(ring->ringBase + ring->lastWrite);
472ca7a8e85SJeff Kirsher 		typhoon_inc_cmd_index(&ring->lastWrite, 1);
473ca7a8e85SJeff Kirsher 
474ca7a8e85SJeff Kirsher 		INIT_COMMAND_NO_RESPONSE(cmd, TYPHOON_CMD_HELLO_RESP);
475ca7a8e85SJeff Kirsher 		wmb();
476ca7a8e85SJeff Kirsher 		iowrite32(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY);
477ca7a8e85SJeff Kirsher 		spin_unlock(&tp->command_lock);
478ca7a8e85SJeff Kirsher 	}
479ca7a8e85SJeff Kirsher }
480ca7a8e85SJeff Kirsher 
481ca7a8e85SJeff Kirsher static int
482ca7a8e85SJeff Kirsher typhoon_process_response(struct typhoon *tp, int resp_size,
483ca7a8e85SJeff Kirsher 				struct resp_desc *resp_save)
484ca7a8e85SJeff Kirsher {
485ca7a8e85SJeff Kirsher 	struct typhoon_indexes *indexes = tp->indexes;
486ca7a8e85SJeff Kirsher 	struct resp_desc *resp;
487ca7a8e85SJeff Kirsher 	u8 *base = tp->respRing.ringBase;
488ca7a8e85SJeff Kirsher 	int count, len, wrap_len;
489ca7a8e85SJeff Kirsher 	u32 cleared;
490ca7a8e85SJeff Kirsher 	u32 ready;
491ca7a8e85SJeff Kirsher 
492ca7a8e85SJeff Kirsher 	cleared = le32_to_cpu(indexes->respCleared);
493ca7a8e85SJeff Kirsher 	ready = le32_to_cpu(indexes->respReady);
494ca7a8e85SJeff Kirsher 	while(cleared != ready) {
495ca7a8e85SJeff Kirsher 		resp = (struct resp_desc *)(base + cleared);
496ca7a8e85SJeff Kirsher 		count = resp->numDesc + 1;
497ca7a8e85SJeff Kirsher 		if(resp_save && resp->seqNo) {
498ca7a8e85SJeff Kirsher 			if(count > resp_size) {
499ca7a8e85SJeff Kirsher 				resp_save->flags = TYPHOON_RESP_ERROR;
500ca7a8e85SJeff Kirsher 				goto cleanup;
501ca7a8e85SJeff Kirsher 			}
502ca7a8e85SJeff Kirsher 
503ca7a8e85SJeff Kirsher 			wrap_len = 0;
504ca7a8e85SJeff Kirsher 			len = count * sizeof(*resp);
505ca7a8e85SJeff Kirsher 			if(unlikely(cleared + len > RESPONSE_RING_SIZE)) {
506ca7a8e85SJeff Kirsher 				wrap_len = cleared + len - RESPONSE_RING_SIZE;
507ca7a8e85SJeff Kirsher 				len = RESPONSE_RING_SIZE - cleared;
508ca7a8e85SJeff Kirsher 			}
509ca7a8e85SJeff Kirsher 
510ca7a8e85SJeff Kirsher 			memcpy(resp_save, resp, len);
511ca7a8e85SJeff Kirsher 			if(unlikely(wrap_len)) {
512ca7a8e85SJeff Kirsher 				resp_save += len / sizeof(*resp);
513ca7a8e85SJeff Kirsher 				memcpy(resp_save, base, wrap_len);
514ca7a8e85SJeff Kirsher 			}
515ca7a8e85SJeff Kirsher 
516ca7a8e85SJeff Kirsher 			resp_save = NULL;
517ca7a8e85SJeff Kirsher 		} else if(resp->cmd == TYPHOON_CMD_READ_MEDIA_STATUS) {
518ca7a8e85SJeff Kirsher 			typhoon_media_status(tp->dev, resp);
519ca7a8e85SJeff Kirsher 		} else if(resp->cmd == TYPHOON_CMD_HELLO_RESP) {
520ca7a8e85SJeff Kirsher 			typhoon_hello(tp);
521ca7a8e85SJeff Kirsher 		} else {
522ca7a8e85SJeff Kirsher 			netdev_err(tp->dev,
523ca7a8e85SJeff Kirsher 				   "dumping unexpected response 0x%04x:%d:0x%02x:0x%04x:%08x:%08x\n",
524ca7a8e85SJeff Kirsher 				   le16_to_cpu(resp->cmd),
525ca7a8e85SJeff Kirsher 				   resp->numDesc, resp->flags,
526ca7a8e85SJeff Kirsher 				   le16_to_cpu(resp->parm1),
527ca7a8e85SJeff Kirsher 				   le32_to_cpu(resp->parm2),
528ca7a8e85SJeff Kirsher 				   le32_to_cpu(resp->parm3));
529ca7a8e85SJeff Kirsher 		}
530ca7a8e85SJeff Kirsher 
531ca7a8e85SJeff Kirsher cleanup:
532ca7a8e85SJeff Kirsher 		typhoon_inc_resp_index(&cleared, count);
533ca7a8e85SJeff Kirsher 	}
534ca7a8e85SJeff Kirsher 
535ca7a8e85SJeff Kirsher 	indexes->respCleared = cpu_to_le32(cleared);
536ca7a8e85SJeff Kirsher 	wmb();
537ca7a8e85SJeff Kirsher 	return resp_save == NULL;
538ca7a8e85SJeff Kirsher }
539ca7a8e85SJeff Kirsher 
540ca7a8e85SJeff Kirsher static inline int
541ca7a8e85SJeff Kirsher typhoon_num_free(int lastWrite, int lastRead, int ringSize)
542ca7a8e85SJeff Kirsher {
543ca7a8e85SJeff Kirsher 	/* this works for all descriptors but rx_desc, as they are a
544ca7a8e85SJeff Kirsher 	 * different size than the cmd_desc -- everyone else is the same
545ca7a8e85SJeff Kirsher 	 */
546ca7a8e85SJeff Kirsher 	lastWrite /= sizeof(struct cmd_desc);
547ca7a8e85SJeff Kirsher 	lastRead /= sizeof(struct cmd_desc);
548ca7a8e85SJeff Kirsher 	return (ringSize + lastRead - lastWrite - 1) % ringSize;
549ca7a8e85SJeff Kirsher }
550ca7a8e85SJeff Kirsher 
551ca7a8e85SJeff Kirsher static inline int
552ca7a8e85SJeff Kirsher typhoon_num_free_cmd(struct typhoon *tp)
553ca7a8e85SJeff Kirsher {
554ca7a8e85SJeff Kirsher 	int lastWrite = tp->cmdRing.lastWrite;
555ca7a8e85SJeff Kirsher 	int cmdCleared = le32_to_cpu(tp->indexes->cmdCleared);
556ca7a8e85SJeff Kirsher 
557ca7a8e85SJeff Kirsher 	return typhoon_num_free(lastWrite, cmdCleared, COMMAND_ENTRIES);
558ca7a8e85SJeff Kirsher }
559ca7a8e85SJeff Kirsher 
560ca7a8e85SJeff Kirsher static inline int
561ca7a8e85SJeff Kirsher typhoon_num_free_resp(struct typhoon *tp)
562ca7a8e85SJeff Kirsher {
563ca7a8e85SJeff Kirsher 	int respReady = le32_to_cpu(tp->indexes->respReady);
564ca7a8e85SJeff Kirsher 	int respCleared = le32_to_cpu(tp->indexes->respCleared);
565ca7a8e85SJeff Kirsher 
566ca7a8e85SJeff Kirsher 	return typhoon_num_free(respReady, respCleared, RESPONSE_ENTRIES);
567ca7a8e85SJeff Kirsher }
568ca7a8e85SJeff Kirsher 
569ca7a8e85SJeff Kirsher static inline int
570ca7a8e85SJeff Kirsher typhoon_num_free_tx(struct transmit_ring *ring)
571ca7a8e85SJeff Kirsher {
572ca7a8e85SJeff Kirsher 	/* if we start using the Hi Tx ring, this needs updating */
573ca7a8e85SJeff Kirsher 	return typhoon_num_free(ring->lastWrite, ring->lastRead, TXLO_ENTRIES);
574ca7a8e85SJeff Kirsher }
575ca7a8e85SJeff Kirsher 
576ca7a8e85SJeff Kirsher static int
577ca7a8e85SJeff Kirsher typhoon_issue_command(struct typhoon *tp, int num_cmd, struct cmd_desc *cmd,
578ca7a8e85SJeff Kirsher 		      int num_resp, struct resp_desc *resp)
579ca7a8e85SJeff Kirsher {
580ca7a8e85SJeff Kirsher 	struct typhoon_indexes *indexes = tp->indexes;
581ca7a8e85SJeff Kirsher 	struct basic_ring *ring = &tp->cmdRing;
582ca7a8e85SJeff Kirsher 	struct resp_desc local_resp;
583ca7a8e85SJeff Kirsher 	int i, err = 0;
584ca7a8e85SJeff Kirsher 	int got_resp;
585ca7a8e85SJeff Kirsher 	int freeCmd, freeResp;
586ca7a8e85SJeff Kirsher 	int len, wrap_len;
587ca7a8e85SJeff Kirsher 
588ca7a8e85SJeff Kirsher 	spin_lock(&tp->command_lock);
589ca7a8e85SJeff Kirsher 
590ca7a8e85SJeff Kirsher 	freeCmd = typhoon_num_free_cmd(tp);
591ca7a8e85SJeff Kirsher 	freeResp = typhoon_num_free_resp(tp);
592ca7a8e85SJeff Kirsher 
593ca7a8e85SJeff Kirsher 	if(freeCmd < num_cmd || freeResp < num_resp) {
594ca7a8e85SJeff Kirsher 		netdev_err(tp->dev, "no descs for cmd, had (needed) %d (%d) cmd, %d (%d) resp\n",
595ca7a8e85SJeff Kirsher 			   freeCmd, num_cmd, freeResp, num_resp);
596ca7a8e85SJeff Kirsher 		err = -ENOMEM;
597ca7a8e85SJeff Kirsher 		goto out;
598ca7a8e85SJeff Kirsher 	}
599ca7a8e85SJeff Kirsher 
600ca7a8e85SJeff Kirsher 	if(cmd->flags & TYPHOON_CMD_RESPOND) {
601ca7a8e85SJeff Kirsher 		/* If we're expecting a response, but the caller hasn't given
602ca7a8e85SJeff Kirsher 		 * us a place to put it, we'll provide one.
603ca7a8e85SJeff Kirsher 		 */
604ca7a8e85SJeff Kirsher 		tp->awaiting_resp = 1;
605ca7a8e85SJeff Kirsher 		if(resp == NULL) {
606ca7a8e85SJeff Kirsher 			resp = &local_resp;
607ca7a8e85SJeff Kirsher 			num_resp = 1;
608ca7a8e85SJeff Kirsher 		}
609ca7a8e85SJeff Kirsher 	}
610ca7a8e85SJeff Kirsher 
611ca7a8e85SJeff Kirsher 	wrap_len = 0;
612ca7a8e85SJeff Kirsher 	len = num_cmd * sizeof(*cmd);
613ca7a8e85SJeff Kirsher 	if(unlikely(ring->lastWrite + len > COMMAND_RING_SIZE)) {
614ca7a8e85SJeff Kirsher 		wrap_len = ring->lastWrite + len - COMMAND_RING_SIZE;
615ca7a8e85SJeff Kirsher 		len = COMMAND_RING_SIZE - ring->lastWrite;
616ca7a8e85SJeff Kirsher 	}
617ca7a8e85SJeff Kirsher 
618ca7a8e85SJeff Kirsher 	memcpy(ring->ringBase + ring->lastWrite, cmd, len);
619ca7a8e85SJeff Kirsher 	if(unlikely(wrap_len)) {
620ca7a8e85SJeff Kirsher 		struct cmd_desc *wrap_ptr = cmd;
621ca7a8e85SJeff Kirsher 		wrap_ptr += len / sizeof(*cmd);
622ca7a8e85SJeff Kirsher 		memcpy(ring->ringBase, wrap_ptr, wrap_len);
623ca7a8e85SJeff Kirsher 	}
624ca7a8e85SJeff Kirsher 
625ca7a8e85SJeff Kirsher 	typhoon_inc_cmd_index(&ring->lastWrite, num_cmd);
626ca7a8e85SJeff Kirsher 
627ca7a8e85SJeff Kirsher 	/* "I feel a presence... another warrior is on the mesa."
628ca7a8e85SJeff Kirsher 	 */
629ca7a8e85SJeff Kirsher 	wmb();
630ca7a8e85SJeff Kirsher 	iowrite32(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY);
631ca7a8e85SJeff Kirsher 	typhoon_post_pci_writes(tp->ioaddr);
632ca7a8e85SJeff Kirsher 
633ca7a8e85SJeff Kirsher 	if((cmd->flags & TYPHOON_CMD_RESPOND) == 0)
634ca7a8e85SJeff Kirsher 		goto out;
635ca7a8e85SJeff Kirsher 
636ca7a8e85SJeff Kirsher 	/* Ugh. We'll be here about 8ms, spinning our thumbs, unable to
637ca7a8e85SJeff Kirsher 	 * preempt or do anything other than take interrupts. So, don't
638ca7a8e85SJeff Kirsher 	 * wait for a response unless you have to.
639ca7a8e85SJeff Kirsher 	 *
640ca7a8e85SJeff Kirsher 	 * I've thought about trying to sleep here, but we're called
641ca7a8e85SJeff Kirsher 	 * from many contexts that don't allow that. Also, given the way
642ca7a8e85SJeff Kirsher 	 * 3Com has implemented irq coalescing, we would likely timeout --
643ca7a8e85SJeff Kirsher 	 * this has been observed in real life!
644ca7a8e85SJeff Kirsher 	 *
645ca7a8e85SJeff Kirsher 	 * The big killer is we have to wait to get stats from the card,
646ca7a8e85SJeff Kirsher 	 * though we could go to a periodic refresh of those if we don't
647ca7a8e85SJeff Kirsher 	 * mind them getting somewhat stale. The rest of the waiting
648ca7a8e85SJeff Kirsher 	 * commands occur during open/close/suspend/resume, so they aren't
649ca7a8e85SJeff Kirsher 	 * time critical. Creating SAs in the future will also have to
650ca7a8e85SJeff Kirsher 	 * wait here.
651ca7a8e85SJeff Kirsher 	 */
652ca7a8e85SJeff Kirsher 	got_resp = 0;
653ca7a8e85SJeff Kirsher 	for(i = 0; i < TYPHOON_WAIT_TIMEOUT && !got_resp; i++) {
654ca7a8e85SJeff Kirsher 		if(indexes->respCleared != indexes->respReady)
655ca7a8e85SJeff Kirsher 			got_resp = typhoon_process_response(tp, num_resp,
656ca7a8e85SJeff Kirsher 								resp);
657ca7a8e85SJeff Kirsher 		udelay(TYPHOON_UDELAY);
658ca7a8e85SJeff Kirsher 	}
659ca7a8e85SJeff Kirsher 
660ca7a8e85SJeff Kirsher 	if(!got_resp) {
661ca7a8e85SJeff Kirsher 		err = -ETIMEDOUT;
662ca7a8e85SJeff Kirsher 		goto out;
663ca7a8e85SJeff Kirsher 	}
664ca7a8e85SJeff Kirsher 
665ca7a8e85SJeff Kirsher 	/* Collect the error response even if we don't care about the
666ca7a8e85SJeff Kirsher 	 * rest of the response
667ca7a8e85SJeff Kirsher 	 */
668ca7a8e85SJeff Kirsher 	if(resp->flags & TYPHOON_RESP_ERROR)
669ca7a8e85SJeff Kirsher 		err = -EIO;
670ca7a8e85SJeff Kirsher 
671ca7a8e85SJeff Kirsher out:
672ca7a8e85SJeff Kirsher 	if(tp->awaiting_resp) {
673ca7a8e85SJeff Kirsher 		tp->awaiting_resp = 0;
674ca7a8e85SJeff Kirsher 		smp_wmb();
675ca7a8e85SJeff Kirsher 
676ca7a8e85SJeff Kirsher 		/* Ugh. If a response was added to the ring between
677ca7a8e85SJeff Kirsher 		 * the call to typhoon_process_response() and the clearing
678ca7a8e85SJeff Kirsher 		 * of tp->awaiting_resp, we could have missed the interrupt
679ca7a8e85SJeff Kirsher 		 * and it could hang in the ring an indeterminate amount of
680ca7a8e85SJeff Kirsher 		 * time. So, check for it, and interrupt ourselves if this
681ca7a8e85SJeff Kirsher 		 * is the case.
682ca7a8e85SJeff Kirsher 		 */
683ca7a8e85SJeff Kirsher 		if(indexes->respCleared != indexes->respReady)
684ca7a8e85SJeff Kirsher 			iowrite32(1, tp->ioaddr + TYPHOON_REG_SELF_INTERRUPT);
685ca7a8e85SJeff Kirsher 	}
686ca7a8e85SJeff Kirsher 
687ca7a8e85SJeff Kirsher 	spin_unlock(&tp->command_lock);
688ca7a8e85SJeff Kirsher 	return err;
689ca7a8e85SJeff Kirsher }
690ca7a8e85SJeff Kirsher 
691ca7a8e85SJeff Kirsher static inline void
692ca7a8e85SJeff Kirsher typhoon_tso_fill(struct sk_buff *skb, struct transmit_ring *txRing,
693ca7a8e85SJeff Kirsher 			u32 ring_dma)
694ca7a8e85SJeff Kirsher {
695ca7a8e85SJeff Kirsher 	struct tcpopt_desc *tcpd;
696ca7a8e85SJeff Kirsher 	u32 tcpd_offset = ring_dma;
697ca7a8e85SJeff Kirsher 
698ca7a8e85SJeff Kirsher 	tcpd = (struct tcpopt_desc *) (txRing->ringBase + txRing->lastWrite);
699ca7a8e85SJeff Kirsher 	tcpd_offset += txRing->lastWrite;
700ca7a8e85SJeff Kirsher 	tcpd_offset += offsetof(struct tcpopt_desc, bytesTx);
701ca7a8e85SJeff Kirsher 	typhoon_inc_tx_index(&txRing->lastWrite, 1);
702ca7a8e85SJeff Kirsher 
703ca7a8e85SJeff Kirsher 	tcpd->flags = TYPHOON_OPT_DESC | TYPHOON_OPT_TCP_SEG;
704ca7a8e85SJeff Kirsher 	tcpd->numDesc = 1;
705ca7a8e85SJeff Kirsher 	tcpd->mss_flags = cpu_to_le16(skb_tso_size(skb));
706ca7a8e85SJeff Kirsher 	tcpd->mss_flags |= TYPHOON_TSO_FIRST | TYPHOON_TSO_LAST;
707ca7a8e85SJeff Kirsher 	tcpd->respAddrLo = cpu_to_le32(tcpd_offset);
708ca7a8e85SJeff Kirsher 	tcpd->bytesTx = cpu_to_le32(skb->len);
709ca7a8e85SJeff Kirsher 	tcpd->status = 0;
710ca7a8e85SJeff Kirsher }
711ca7a8e85SJeff Kirsher 
712ca7a8e85SJeff Kirsher static netdev_tx_t
713ca7a8e85SJeff Kirsher typhoon_start_tx(struct sk_buff *skb, struct net_device *dev)
714ca7a8e85SJeff Kirsher {
715ca7a8e85SJeff Kirsher 	struct typhoon *tp = netdev_priv(dev);
716ca7a8e85SJeff Kirsher 	struct transmit_ring *txRing;
717ca7a8e85SJeff Kirsher 	struct tx_desc *txd, *first_txd;
718ca7a8e85SJeff Kirsher 	dma_addr_t skb_dma;
719ca7a8e85SJeff Kirsher 	int numDesc;
720ca7a8e85SJeff Kirsher 
721ca7a8e85SJeff Kirsher 	/* we have two rings to choose from, but we only use txLo for now
722ca7a8e85SJeff Kirsher 	 * If we start using the Hi ring as well, we'll need to update
723ca7a8e85SJeff Kirsher 	 * typhoon_stop_runtime(), typhoon_interrupt(), typhoon_num_free_tx(),
724ca7a8e85SJeff Kirsher 	 * and TXHI_ENTRIES to match, as well as update the TSO code below
725ca7a8e85SJeff Kirsher 	 * to get the right DMA address
726ca7a8e85SJeff Kirsher 	 */
727ca7a8e85SJeff Kirsher 	txRing = &tp->txLoRing;
728ca7a8e85SJeff Kirsher 
729ca7a8e85SJeff Kirsher 	/* We need one descriptor for each fragment of the sk_buff, plus the
730ca7a8e85SJeff Kirsher 	 * one for the ->data area of it.
731ca7a8e85SJeff Kirsher 	 *
732ca7a8e85SJeff Kirsher 	 * The docs say a maximum of 16 fragment descriptors per TCP option
733ca7a8e85SJeff Kirsher 	 * descriptor, then make a new packet descriptor and option descriptor
734ca7a8e85SJeff Kirsher 	 * for the next 16 fragments. The engineers say just an option
735ca7a8e85SJeff Kirsher 	 * descriptor is needed. I've tested up to 26 fragments with a single
736ca7a8e85SJeff Kirsher 	 * packet descriptor/option descriptor combo, so I use that for now.
737ca7a8e85SJeff Kirsher 	 *
738ca7a8e85SJeff Kirsher 	 * If problems develop with TSO, check this first.
739ca7a8e85SJeff Kirsher 	 */
740ca7a8e85SJeff Kirsher 	numDesc = skb_shinfo(skb)->nr_frags + 1;
741ca7a8e85SJeff Kirsher 	if (skb_is_gso(skb))
742ca7a8e85SJeff Kirsher 		numDesc++;
743ca7a8e85SJeff Kirsher 
744ca7a8e85SJeff Kirsher 	/* When checking for free space in the ring, we need to also
745ca7a8e85SJeff Kirsher 	 * account for the initial Tx descriptor, and we always must leave
746ca7a8e85SJeff Kirsher 	 * at least one descriptor unused in the ring so that it doesn't
747ca7a8e85SJeff Kirsher 	 * wrap and look empty.
748ca7a8e85SJeff Kirsher 	 *
749ca7a8e85SJeff Kirsher 	 * The only time we should loop here is when we hit the race
750ca7a8e85SJeff Kirsher 	 * between marking the queue awake and updating the cleared index.
751ca7a8e85SJeff Kirsher 	 * Just loop and it will appear. This comes from the acenic driver.
752ca7a8e85SJeff Kirsher 	 */
753ca7a8e85SJeff Kirsher 	while(unlikely(typhoon_num_free_tx(txRing) < (numDesc + 2)))
754ca7a8e85SJeff Kirsher 		smp_rmb();
755ca7a8e85SJeff Kirsher 
756ca7a8e85SJeff Kirsher 	first_txd = (struct tx_desc *) (txRing->ringBase + txRing->lastWrite);
757ca7a8e85SJeff Kirsher 	typhoon_inc_tx_index(&txRing->lastWrite, 1);
758ca7a8e85SJeff Kirsher 
759ca7a8e85SJeff Kirsher 	first_txd->flags = TYPHOON_TX_DESC | TYPHOON_DESC_VALID;
760ca7a8e85SJeff Kirsher 	first_txd->numDesc = 0;
761ca7a8e85SJeff Kirsher 	first_txd->len = 0;
762ca7a8e85SJeff Kirsher 	first_txd->tx_addr = (u64)((unsigned long) skb);
763ca7a8e85SJeff Kirsher 	first_txd->processFlags = 0;
764ca7a8e85SJeff Kirsher 
765ca7a8e85SJeff Kirsher 	if(skb->ip_summed == CHECKSUM_PARTIAL) {
766ca7a8e85SJeff Kirsher 		/* The 3XP will figure out if this is UDP/TCP */
767ca7a8e85SJeff Kirsher 		first_txd->processFlags |= TYPHOON_TX_PF_TCP_CHKSUM;
768ca7a8e85SJeff Kirsher 		first_txd->processFlags |= TYPHOON_TX_PF_UDP_CHKSUM;
769ca7a8e85SJeff Kirsher 		first_txd->processFlags |= TYPHOON_TX_PF_IP_CHKSUM;
770ca7a8e85SJeff Kirsher 	}
771ca7a8e85SJeff Kirsher 
772ca7a8e85SJeff Kirsher 	if(vlan_tx_tag_present(skb)) {
773ca7a8e85SJeff Kirsher 		first_txd->processFlags |=
774ca7a8e85SJeff Kirsher 		    TYPHOON_TX_PF_INSERT_VLAN | TYPHOON_TX_PF_VLAN_PRIORITY;
775ca7a8e85SJeff Kirsher 		first_txd->processFlags |=
776ca7a8e85SJeff Kirsher 		    cpu_to_le32(htons(vlan_tx_tag_get(skb)) <<
777ca7a8e85SJeff Kirsher 				TYPHOON_TX_PF_VLAN_TAG_SHIFT);
778ca7a8e85SJeff Kirsher 	}
779ca7a8e85SJeff Kirsher 
780ca7a8e85SJeff Kirsher 	if (skb_is_gso(skb)) {
781ca7a8e85SJeff Kirsher 		first_txd->processFlags |= TYPHOON_TX_PF_TCP_SEGMENT;
782ca7a8e85SJeff Kirsher 		first_txd->numDesc++;
783ca7a8e85SJeff Kirsher 
784ca7a8e85SJeff Kirsher 		typhoon_tso_fill(skb, txRing, tp->txlo_dma_addr);
785ca7a8e85SJeff Kirsher 	}
786ca7a8e85SJeff Kirsher 
787ca7a8e85SJeff Kirsher 	txd = (struct tx_desc *) (txRing->ringBase + txRing->lastWrite);
788ca7a8e85SJeff Kirsher 	typhoon_inc_tx_index(&txRing->lastWrite, 1);
789ca7a8e85SJeff Kirsher 
790ca7a8e85SJeff Kirsher 	/* No need to worry about padding packet -- the firmware pads
791ca7a8e85SJeff Kirsher 	 * it with zeros to ETH_ZLEN for us.
792ca7a8e85SJeff Kirsher 	 */
793ca7a8e85SJeff Kirsher 	if(skb_shinfo(skb)->nr_frags == 0) {
794ca7a8e85SJeff Kirsher 		skb_dma = pci_map_single(tp->tx_pdev, skb->data, skb->len,
795ca7a8e85SJeff Kirsher 				       PCI_DMA_TODEVICE);
796ca7a8e85SJeff Kirsher 		txd->flags = TYPHOON_FRAG_DESC | TYPHOON_DESC_VALID;
797ca7a8e85SJeff Kirsher 		txd->len = cpu_to_le16(skb->len);
798ca7a8e85SJeff Kirsher 		txd->frag.addr = cpu_to_le32(skb_dma);
799ca7a8e85SJeff Kirsher 		txd->frag.addrHi = 0;
800ca7a8e85SJeff Kirsher 		first_txd->numDesc++;
801ca7a8e85SJeff Kirsher 	} else {
802ca7a8e85SJeff Kirsher 		int i, len;
803ca7a8e85SJeff Kirsher 
804ca7a8e85SJeff Kirsher 		len = skb_headlen(skb);
805ca7a8e85SJeff Kirsher 		skb_dma = pci_map_single(tp->tx_pdev, skb->data, len,
806ca7a8e85SJeff Kirsher 				         PCI_DMA_TODEVICE);
807ca7a8e85SJeff Kirsher 		txd->flags = TYPHOON_FRAG_DESC | TYPHOON_DESC_VALID;
808ca7a8e85SJeff Kirsher 		txd->len = cpu_to_le16(len);
809ca7a8e85SJeff Kirsher 		txd->frag.addr = cpu_to_le32(skb_dma);
810ca7a8e85SJeff Kirsher 		txd->frag.addrHi = 0;
811ca7a8e85SJeff Kirsher 		first_txd->numDesc++;
812ca7a8e85SJeff Kirsher 
813ca7a8e85SJeff Kirsher 		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
8149e903e08SEric Dumazet 			const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
815ca7a8e85SJeff Kirsher 			void *frag_addr;
816ca7a8e85SJeff Kirsher 
817ca7a8e85SJeff Kirsher 			txd = (struct tx_desc *) (txRing->ringBase +
818ca7a8e85SJeff Kirsher 						txRing->lastWrite);
819ca7a8e85SJeff Kirsher 			typhoon_inc_tx_index(&txRing->lastWrite, 1);
820ca7a8e85SJeff Kirsher 
8219e903e08SEric Dumazet 			len = skb_frag_size(frag);
8222098401cSIan Campbell 			frag_addr = skb_frag_address(frag);
823ca7a8e85SJeff Kirsher 			skb_dma = pci_map_single(tp->tx_pdev, frag_addr, len,
824ca7a8e85SJeff Kirsher 					 PCI_DMA_TODEVICE);
825ca7a8e85SJeff Kirsher 			txd->flags = TYPHOON_FRAG_DESC | TYPHOON_DESC_VALID;
826ca7a8e85SJeff Kirsher 			txd->len = cpu_to_le16(len);
827ca7a8e85SJeff Kirsher 			txd->frag.addr = cpu_to_le32(skb_dma);
828ca7a8e85SJeff Kirsher 			txd->frag.addrHi = 0;
829ca7a8e85SJeff Kirsher 			first_txd->numDesc++;
830ca7a8e85SJeff Kirsher 		}
831ca7a8e85SJeff Kirsher 	}
832ca7a8e85SJeff Kirsher 
833ca7a8e85SJeff Kirsher 	/* Kick the 3XP
834ca7a8e85SJeff Kirsher 	 */
835ca7a8e85SJeff Kirsher 	wmb();
836ca7a8e85SJeff Kirsher 	iowrite32(txRing->lastWrite, tp->tx_ioaddr + txRing->writeRegister);
837ca7a8e85SJeff Kirsher 
838ca7a8e85SJeff Kirsher 	/* If we don't have room to put the worst case packet on the
839ca7a8e85SJeff Kirsher 	 * queue, then we must stop the queue. We need 2 extra
840ca7a8e85SJeff Kirsher 	 * descriptors -- one to prevent ring wrap, and one for the
841ca7a8e85SJeff Kirsher 	 * Tx header.
842ca7a8e85SJeff Kirsher 	 */
843ca7a8e85SJeff Kirsher 	numDesc = MAX_SKB_FRAGS + TSO_NUM_DESCRIPTORS + 1;
844ca7a8e85SJeff Kirsher 
845ca7a8e85SJeff Kirsher 	if(typhoon_num_free_tx(txRing) < (numDesc + 2)) {
846ca7a8e85SJeff Kirsher 		netif_stop_queue(dev);
847ca7a8e85SJeff Kirsher 
848ca7a8e85SJeff Kirsher 		/* A Tx complete IRQ could have gotten between, making
849ca7a8e85SJeff Kirsher 		 * the ring free again. Only need to recheck here, since
850ca7a8e85SJeff Kirsher 		 * Tx is serialized.
851ca7a8e85SJeff Kirsher 		 */
852ca7a8e85SJeff Kirsher 		if(typhoon_num_free_tx(txRing) >= (numDesc + 2))
853ca7a8e85SJeff Kirsher 			netif_wake_queue(dev);
854ca7a8e85SJeff Kirsher 	}
855ca7a8e85SJeff Kirsher 
856ca7a8e85SJeff Kirsher 	return NETDEV_TX_OK;
857ca7a8e85SJeff Kirsher }
858ca7a8e85SJeff Kirsher 
859ca7a8e85SJeff Kirsher static void
860ca7a8e85SJeff Kirsher typhoon_set_rx_mode(struct net_device *dev)
861ca7a8e85SJeff Kirsher {
862ca7a8e85SJeff Kirsher 	struct typhoon *tp = netdev_priv(dev);
863ca7a8e85SJeff Kirsher 	struct cmd_desc xp_cmd;
864ca7a8e85SJeff Kirsher 	u32 mc_filter[2];
865ca7a8e85SJeff Kirsher 	__le16 filter;
866ca7a8e85SJeff Kirsher 
867ca7a8e85SJeff Kirsher 	filter = TYPHOON_RX_FILTER_DIRECTED | TYPHOON_RX_FILTER_BROADCAST;
868ca7a8e85SJeff Kirsher 	if(dev->flags & IFF_PROMISC) {
869ca7a8e85SJeff Kirsher 		filter |= TYPHOON_RX_FILTER_PROMISCOUS;
870ca7a8e85SJeff Kirsher 	} else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
871ca7a8e85SJeff Kirsher 		  (dev->flags & IFF_ALLMULTI)) {
872ca7a8e85SJeff Kirsher 		/* Too many to match, or accept all multicasts. */
873ca7a8e85SJeff Kirsher 		filter |= TYPHOON_RX_FILTER_ALL_MCAST;
874ca7a8e85SJeff Kirsher 	} else if (!netdev_mc_empty(dev)) {
875ca7a8e85SJeff Kirsher 		struct netdev_hw_addr *ha;
876ca7a8e85SJeff Kirsher 
877ca7a8e85SJeff Kirsher 		memset(mc_filter, 0, sizeof(mc_filter));
878ca7a8e85SJeff Kirsher 		netdev_for_each_mc_addr(ha, dev) {
879ca7a8e85SJeff Kirsher 			int bit = ether_crc(ETH_ALEN, ha->addr) & 0x3f;
880ca7a8e85SJeff Kirsher 			mc_filter[bit >> 5] |= 1 << (bit & 0x1f);
881ca7a8e85SJeff Kirsher 		}
882ca7a8e85SJeff Kirsher 
883ca7a8e85SJeff Kirsher 		INIT_COMMAND_NO_RESPONSE(&xp_cmd,
884ca7a8e85SJeff Kirsher 					 TYPHOON_CMD_SET_MULTICAST_HASH);
885ca7a8e85SJeff Kirsher 		xp_cmd.parm1 = TYPHOON_MCAST_HASH_SET;
886ca7a8e85SJeff Kirsher 		xp_cmd.parm2 = cpu_to_le32(mc_filter[0]);
887ca7a8e85SJeff Kirsher 		xp_cmd.parm3 = cpu_to_le32(mc_filter[1]);
888ca7a8e85SJeff Kirsher 		typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
889ca7a8e85SJeff Kirsher 
890ca7a8e85SJeff Kirsher 		filter |= TYPHOON_RX_FILTER_MCAST_HASH;
891ca7a8e85SJeff Kirsher 	}
892ca7a8e85SJeff Kirsher 
893ca7a8e85SJeff Kirsher 	INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_RX_FILTER);
894ca7a8e85SJeff Kirsher 	xp_cmd.parm1 = filter;
895ca7a8e85SJeff Kirsher 	typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
896ca7a8e85SJeff Kirsher }
897ca7a8e85SJeff Kirsher 
898ca7a8e85SJeff Kirsher static int
899ca7a8e85SJeff Kirsher typhoon_do_get_stats(struct typhoon *tp)
900ca7a8e85SJeff Kirsher {
901ca7a8e85SJeff Kirsher 	struct net_device_stats *stats = &tp->stats;
902ca7a8e85SJeff Kirsher 	struct net_device_stats *saved = &tp->stats_saved;
903ca7a8e85SJeff Kirsher 	struct cmd_desc xp_cmd;
904ca7a8e85SJeff Kirsher 	struct resp_desc xp_resp[7];
905ca7a8e85SJeff Kirsher 	struct stats_resp *s = (struct stats_resp *) xp_resp;
906ca7a8e85SJeff Kirsher 	int err;
907ca7a8e85SJeff Kirsher 
908ca7a8e85SJeff Kirsher 	INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_STATS);
909ca7a8e85SJeff Kirsher 	err = typhoon_issue_command(tp, 1, &xp_cmd, 7, xp_resp);
910ca7a8e85SJeff Kirsher 	if(err < 0)
911ca7a8e85SJeff Kirsher 		return err;
912ca7a8e85SJeff Kirsher 
913ca7a8e85SJeff Kirsher 	/* 3Com's Linux driver uses txMultipleCollisions as it's
914ca7a8e85SJeff Kirsher 	 * collisions value, but there is some other collision info as well...
915ca7a8e85SJeff Kirsher 	 *
916ca7a8e85SJeff Kirsher 	 * The extra status reported would be a good candidate for
917ca7a8e85SJeff Kirsher 	 * ethtool_ops->get_{strings,stats}()
918ca7a8e85SJeff Kirsher 	 */
919ca7a8e85SJeff Kirsher 	stats->tx_packets = le32_to_cpu(s->txPackets) +
920ca7a8e85SJeff Kirsher 			saved->tx_packets;
921ca7a8e85SJeff Kirsher 	stats->tx_bytes = le64_to_cpu(s->txBytes) +
922ca7a8e85SJeff Kirsher 			saved->tx_bytes;
923ca7a8e85SJeff Kirsher 	stats->tx_errors = le32_to_cpu(s->txCarrierLost) +
924ca7a8e85SJeff Kirsher 			saved->tx_errors;
925ca7a8e85SJeff Kirsher 	stats->tx_carrier_errors = le32_to_cpu(s->txCarrierLost) +
926ca7a8e85SJeff Kirsher 			saved->tx_carrier_errors;
927ca7a8e85SJeff Kirsher 	stats->collisions = le32_to_cpu(s->txMultipleCollisions) +
928ca7a8e85SJeff Kirsher 			saved->collisions;
929ca7a8e85SJeff Kirsher 	stats->rx_packets = le32_to_cpu(s->rxPacketsGood) +
930ca7a8e85SJeff Kirsher 			saved->rx_packets;
931ca7a8e85SJeff Kirsher 	stats->rx_bytes = le64_to_cpu(s->rxBytesGood) +
932ca7a8e85SJeff Kirsher 			saved->rx_bytes;
933ca7a8e85SJeff Kirsher 	stats->rx_fifo_errors = le32_to_cpu(s->rxFifoOverruns) +
934ca7a8e85SJeff Kirsher 			saved->rx_fifo_errors;
935ca7a8e85SJeff Kirsher 	stats->rx_errors = le32_to_cpu(s->rxFifoOverruns) +
936ca7a8e85SJeff Kirsher 			le32_to_cpu(s->BadSSD) + le32_to_cpu(s->rxCrcErrors) +
937ca7a8e85SJeff Kirsher 			saved->rx_errors;
938ca7a8e85SJeff Kirsher 	stats->rx_crc_errors = le32_to_cpu(s->rxCrcErrors) +
939ca7a8e85SJeff Kirsher 			saved->rx_crc_errors;
940ca7a8e85SJeff Kirsher 	stats->rx_length_errors = le32_to_cpu(s->rxOversized) +
941ca7a8e85SJeff Kirsher 			saved->rx_length_errors;
942ca7a8e85SJeff Kirsher 	tp->speed = (s->linkStatus & TYPHOON_LINK_100MBPS) ?
943ca7a8e85SJeff Kirsher 			SPEED_100 : SPEED_10;
944ca7a8e85SJeff Kirsher 	tp->duplex = (s->linkStatus & TYPHOON_LINK_FULL_DUPLEX) ?
945ca7a8e85SJeff Kirsher 			DUPLEX_FULL : DUPLEX_HALF;
946ca7a8e85SJeff Kirsher 
947ca7a8e85SJeff Kirsher 	return 0;
948ca7a8e85SJeff Kirsher }
949ca7a8e85SJeff Kirsher 
950ca7a8e85SJeff Kirsher static struct net_device_stats *
951ca7a8e85SJeff Kirsher typhoon_get_stats(struct net_device *dev)
952ca7a8e85SJeff Kirsher {
953ca7a8e85SJeff Kirsher 	struct typhoon *tp = netdev_priv(dev);
954ca7a8e85SJeff Kirsher 	struct net_device_stats *stats = &tp->stats;
955ca7a8e85SJeff Kirsher 	struct net_device_stats *saved = &tp->stats_saved;
956ca7a8e85SJeff Kirsher 
957ca7a8e85SJeff Kirsher 	smp_rmb();
958ca7a8e85SJeff Kirsher 	if(tp->card_state == Sleeping)
959ca7a8e85SJeff Kirsher 		return saved;
960ca7a8e85SJeff Kirsher 
961ca7a8e85SJeff Kirsher 	if(typhoon_do_get_stats(tp) < 0) {
962ca7a8e85SJeff Kirsher 		netdev_err(dev, "error getting stats\n");
963ca7a8e85SJeff Kirsher 		return saved;
964ca7a8e85SJeff Kirsher 	}
965ca7a8e85SJeff Kirsher 
966ca7a8e85SJeff Kirsher 	return stats;
967ca7a8e85SJeff Kirsher }
968ca7a8e85SJeff Kirsher 
969ca7a8e85SJeff Kirsher static int
970ca7a8e85SJeff Kirsher typhoon_set_mac_address(struct net_device *dev, void *addr)
971ca7a8e85SJeff Kirsher {
972ca7a8e85SJeff Kirsher 	struct sockaddr *saddr = (struct sockaddr *) addr;
973ca7a8e85SJeff Kirsher 
974ca7a8e85SJeff Kirsher 	if(netif_running(dev))
975ca7a8e85SJeff Kirsher 		return -EBUSY;
976ca7a8e85SJeff Kirsher 
977ca7a8e85SJeff Kirsher 	memcpy(dev->dev_addr, saddr->sa_data, dev->addr_len);
978ca7a8e85SJeff Kirsher 	return 0;
979ca7a8e85SJeff Kirsher }
980ca7a8e85SJeff Kirsher 
981ca7a8e85SJeff Kirsher static void
982ca7a8e85SJeff Kirsher typhoon_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
983ca7a8e85SJeff Kirsher {
984ca7a8e85SJeff Kirsher 	struct typhoon *tp = netdev_priv(dev);
985ca7a8e85SJeff Kirsher 	struct pci_dev *pci_dev = tp->pdev;
986ca7a8e85SJeff Kirsher 	struct cmd_desc xp_cmd;
987ca7a8e85SJeff Kirsher 	struct resp_desc xp_resp[3];
988ca7a8e85SJeff Kirsher 
989ca7a8e85SJeff Kirsher 	smp_rmb();
990ca7a8e85SJeff Kirsher 	if(tp->card_state == Sleeping) {
99168aad78cSRick Jones 		strlcpy(info->fw_version, "Sleep image",
99268aad78cSRick Jones 			sizeof(info->fw_version));
993ca7a8e85SJeff Kirsher 	} else {
994ca7a8e85SJeff Kirsher 		INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_VERSIONS);
995ca7a8e85SJeff Kirsher 		if(typhoon_issue_command(tp, 1, &xp_cmd, 3, xp_resp) < 0) {
99668aad78cSRick Jones 			strlcpy(info->fw_version, "Unknown runtime",
99768aad78cSRick Jones 				sizeof(info->fw_version));
998ca7a8e85SJeff Kirsher 		} else {
999ca7a8e85SJeff Kirsher 			u32 sleep_ver = le32_to_cpu(xp_resp[0].parm2);
100068aad78cSRick Jones 			snprintf(info->fw_version, sizeof(info->fw_version),
100168aad78cSRick Jones 				"%02x.%03x.%03x", sleep_ver >> 24,
100268aad78cSRick Jones 				(sleep_ver >> 12) & 0xfff, sleep_ver & 0xfff);
1003ca7a8e85SJeff Kirsher 		}
1004ca7a8e85SJeff Kirsher 	}
1005ca7a8e85SJeff Kirsher 
100668aad78cSRick Jones 	strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
100768aad78cSRick Jones 	strlcpy(info->bus_info, pci_name(pci_dev), sizeof(info->bus_info));
1008ca7a8e85SJeff Kirsher }
1009ca7a8e85SJeff Kirsher 
1010ca7a8e85SJeff Kirsher static int
1011ca7a8e85SJeff Kirsher typhoon_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1012ca7a8e85SJeff Kirsher {
1013ca7a8e85SJeff Kirsher 	struct typhoon *tp = netdev_priv(dev);
1014ca7a8e85SJeff Kirsher 
1015ca7a8e85SJeff Kirsher 	cmd->supported = SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
1016ca7a8e85SJeff Kirsher 				SUPPORTED_Autoneg;
1017ca7a8e85SJeff Kirsher 
1018ca7a8e85SJeff Kirsher 	switch (tp->xcvr_select) {
1019ca7a8e85SJeff Kirsher 	case TYPHOON_XCVR_10HALF:
1020ca7a8e85SJeff Kirsher 		cmd->advertising = ADVERTISED_10baseT_Half;
1021ca7a8e85SJeff Kirsher 		break;
1022ca7a8e85SJeff Kirsher 	case TYPHOON_XCVR_10FULL:
1023ca7a8e85SJeff Kirsher 		cmd->advertising = ADVERTISED_10baseT_Full;
1024ca7a8e85SJeff Kirsher 		break;
1025ca7a8e85SJeff Kirsher 	case TYPHOON_XCVR_100HALF:
1026ca7a8e85SJeff Kirsher 		cmd->advertising = ADVERTISED_100baseT_Half;
1027ca7a8e85SJeff Kirsher 		break;
1028ca7a8e85SJeff Kirsher 	case TYPHOON_XCVR_100FULL:
1029ca7a8e85SJeff Kirsher 		cmd->advertising = ADVERTISED_100baseT_Full;
1030ca7a8e85SJeff Kirsher 		break;
1031ca7a8e85SJeff Kirsher 	case TYPHOON_XCVR_AUTONEG:
1032ca7a8e85SJeff Kirsher 		cmd->advertising = ADVERTISED_10baseT_Half |
1033ca7a8e85SJeff Kirsher 					    ADVERTISED_10baseT_Full |
1034ca7a8e85SJeff Kirsher 					    ADVERTISED_100baseT_Half |
1035ca7a8e85SJeff Kirsher 					    ADVERTISED_100baseT_Full |
1036ca7a8e85SJeff Kirsher 					    ADVERTISED_Autoneg;
1037ca7a8e85SJeff Kirsher 		break;
1038ca7a8e85SJeff Kirsher 	}
1039ca7a8e85SJeff Kirsher 
1040ca7a8e85SJeff Kirsher 	if(tp->capabilities & TYPHOON_FIBER) {
1041ca7a8e85SJeff Kirsher 		cmd->supported |= SUPPORTED_FIBRE;
1042ca7a8e85SJeff Kirsher 		cmd->advertising |= ADVERTISED_FIBRE;
1043ca7a8e85SJeff Kirsher 		cmd->port = PORT_FIBRE;
1044ca7a8e85SJeff Kirsher 	} else {
1045ca7a8e85SJeff Kirsher 		cmd->supported |= SUPPORTED_10baseT_Half |
1046ca7a8e85SJeff Kirsher 		    			SUPPORTED_10baseT_Full |
1047ca7a8e85SJeff Kirsher 					SUPPORTED_TP;
1048ca7a8e85SJeff Kirsher 		cmd->advertising |= ADVERTISED_TP;
1049ca7a8e85SJeff Kirsher 		cmd->port = PORT_TP;
1050ca7a8e85SJeff Kirsher 	}
1051ca7a8e85SJeff Kirsher 
1052ca7a8e85SJeff Kirsher 	/* need to get stats to make these link speed/duplex valid */
1053ca7a8e85SJeff Kirsher 	typhoon_do_get_stats(tp);
1054ca7a8e85SJeff Kirsher 	ethtool_cmd_speed_set(cmd, tp->speed);
1055ca7a8e85SJeff Kirsher 	cmd->duplex = tp->duplex;
1056ca7a8e85SJeff Kirsher 	cmd->phy_address = 0;
1057ca7a8e85SJeff Kirsher 	cmd->transceiver = XCVR_INTERNAL;
1058ca7a8e85SJeff Kirsher 	if(tp->xcvr_select == TYPHOON_XCVR_AUTONEG)
1059ca7a8e85SJeff Kirsher 		cmd->autoneg = AUTONEG_ENABLE;
1060ca7a8e85SJeff Kirsher 	else
1061ca7a8e85SJeff Kirsher 		cmd->autoneg = AUTONEG_DISABLE;
1062ca7a8e85SJeff Kirsher 	cmd->maxtxpkt = 1;
1063ca7a8e85SJeff Kirsher 	cmd->maxrxpkt = 1;
1064ca7a8e85SJeff Kirsher 
1065ca7a8e85SJeff Kirsher 	return 0;
1066ca7a8e85SJeff Kirsher }
1067ca7a8e85SJeff Kirsher 
1068ca7a8e85SJeff Kirsher static int
1069ca7a8e85SJeff Kirsher typhoon_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1070ca7a8e85SJeff Kirsher {
1071ca7a8e85SJeff Kirsher 	struct typhoon *tp = netdev_priv(dev);
1072ca7a8e85SJeff Kirsher 	u32 speed = ethtool_cmd_speed(cmd);
1073ca7a8e85SJeff Kirsher 	struct cmd_desc xp_cmd;
1074ca7a8e85SJeff Kirsher 	__le16 xcvr;
1075ca7a8e85SJeff Kirsher 	int err;
1076ca7a8e85SJeff Kirsher 
1077ca7a8e85SJeff Kirsher 	err = -EINVAL;
1078ca7a8e85SJeff Kirsher 	if (cmd->autoneg == AUTONEG_ENABLE) {
1079ca7a8e85SJeff Kirsher 		xcvr = TYPHOON_XCVR_AUTONEG;
1080ca7a8e85SJeff Kirsher 	} else {
1081ca7a8e85SJeff Kirsher 		if (cmd->duplex == DUPLEX_HALF) {
1082ca7a8e85SJeff Kirsher 			if (speed == SPEED_10)
1083ca7a8e85SJeff Kirsher 				xcvr = TYPHOON_XCVR_10HALF;
1084ca7a8e85SJeff Kirsher 			else if (speed == SPEED_100)
1085ca7a8e85SJeff Kirsher 				xcvr = TYPHOON_XCVR_100HALF;
1086ca7a8e85SJeff Kirsher 			else
1087ca7a8e85SJeff Kirsher 				goto out;
1088ca7a8e85SJeff Kirsher 		} else if (cmd->duplex == DUPLEX_FULL) {
1089ca7a8e85SJeff Kirsher 			if (speed == SPEED_10)
1090ca7a8e85SJeff Kirsher 				xcvr = TYPHOON_XCVR_10FULL;
1091ca7a8e85SJeff Kirsher 			else if (speed == SPEED_100)
1092ca7a8e85SJeff Kirsher 				xcvr = TYPHOON_XCVR_100FULL;
1093ca7a8e85SJeff Kirsher 			else
1094ca7a8e85SJeff Kirsher 				goto out;
1095ca7a8e85SJeff Kirsher 		} else
1096ca7a8e85SJeff Kirsher 			goto out;
1097ca7a8e85SJeff Kirsher 	}
1098ca7a8e85SJeff Kirsher 
1099ca7a8e85SJeff Kirsher 	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_XCVR_SELECT);
1100ca7a8e85SJeff Kirsher 	xp_cmd.parm1 = xcvr;
1101ca7a8e85SJeff Kirsher 	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
1102ca7a8e85SJeff Kirsher 	if(err < 0)
1103ca7a8e85SJeff Kirsher 		goto out;
1104ca7a8e85SJeff Kirsher 
1105ca7a8e85SJeff Kirsher 	tp->xcvr_select = xcvr;
1106ca7a8e85SJeff Kirsher 	if(cmd->autoneg == AUTONEG_ENABLE) {
1107ca7a8e85SJeff Kirsher 		tp->speed = 0xff;	/* invalid */
1108ca7a8e85SJeff Kirsher 		tp->duplex = 0xff;	/* invalid */
1109ca7a8e85SJeff Kirsher 	} else {
1110ca7a8e85SJeff Kirsher 		tp->speed = speed;
1111ca7a8e85SJeff Kirsher 		tp->duplex = cmd->duplex;
1112ca7a8e85SJeff Kirsher 	}
1113ca7a8e85SJeff Kirsher 
1114ca7a8e85SJeff Kirsher out:
1115ca7a8e85SJeff Kirsher 	return err;
1116ca7a8e85SJeff Kirsher }
1117ca7a8e85SJeff Kirsher 
1118ca7a8e85SJeff Kirsher static void
1119ca7a8e85SJeff Kirsher typhoon_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1120ca7a8e85SJeff Kirsher {
1121ca7a8e85SJeff Kirsher 	struct typhoon *tp = netdev_priv(dev);
1122ca7a8e85SJeff Kirsher 
1123ca7a8e85SJeff Kirsher 	wol->supported = WAKE_PHY | WAKE_MAGIC;
1124ca7a8e85SJeff Kirsher 	wol->wolopts = 0;
1125ca7a8e85SJeff Kirsher 	if(tp->wol_events & TYPHOON_WAKE_LINK_EVENT)
1126ca7a8e85SJeff Kirsher 		wol->wolopts |= WAKE_PHY;
1127ca7a8e85SJeff Kirsher 	if(tp->wol_events & TYPHOON_WAKE_MAGIC_PKT)
1128ca7a8e85SJeff Kirsher 		wol->wolopts |= WAKE_MAGIC;
1129ca7a8e85SJeff Kirsher 	memset(&wol->sopass, 0, sizeof(wol->sopass));
1130ca7a8e85SJeff Kirsher }
1131ca7a8e85SJeff Kirsher 
1132ca7a8e85SJeff Kirsher static int
1133ca7a8e85SJeff Kirsher typhoon_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1134ca7a8e85SJeff Kirsher {
1135ca7a8e85SJeff Kirsher 	struct typhoon *tp = netdev_priv(dev);
1136ca7a8e85SJeff Kirsher 
1137ca7a8e85SJeff Kirsher 	if(wol->wolopts & ~(WAKE_PHY | WAKE_MAGIC))
1138ca7a8e85SJeff Kirsher 		return -EINVAL;
1139ca7a8e85SJeff Kirsher 
1140ca7a8e85SJeff Kirsher 	tp->wol_events = 0;
1141ca7a8e85SJeff Kirsher 	if(wol->wolopts & WAKE_PHY)
1142ca7a8e85SJeff Kirsher 		tp->wol_events |= TYPHOON_WAKE_LINK_EVENT;
1143ca7a8e85SJeff Kirsher 	if(wol->wolopts & WAKE_MAGIC)
1144ca7a8e85SJeff Kirsher 		tp->wol_events |= TYPHOON_WAKE_MAGIC_PKT;
1145ca7a8e85SJeff Kirsher 
1146ca7a8e85SJeff Kirsher 	return 0;
1147ca7a8e85SJeff Kirsher }
1148ca7a8e85SJeff Kirsher 
1149ca7a8e85SJeff Kirsher static void
1150ca7a8e85SJeff Kirsher typhoon_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
1151ca7a8e85SJeff Kirsher {
1152ca7a8e85SJeff Kirsher 	ering->rx_max_pending = RXENT_ENTRIES;
1153ca7a8e85SJeff Kirsher 	ering->tx_max_pending = TXLO_ENTRIES - 1;
1154ca7a8e85SJeff Kirsher 
1155ca7a8e85SJeff Kirsher 	ering->rx_pending = RXENT_ENTRIES;
1156ca7a8e85SJeff Kirsher 	ering->tx_pending = TXLO_ENTRIES - 1;
1157ca7a8e85SJeff Kirsher }
1158ca7a8e85SJeff Kirsher 
1159ca7a8e85SJeff Kirsher static const struct ethtool_ops typhoon_ethtool_ops = {
1160ca7a8e85SJeff Kirsher 	.get_settings		= typhoon_get_settings,
1161ca7a8e85SJeff Kirsher 	.set_settings		= typhoon_set_settings,
1162ca7a8e85SJeff Kirsher 	.get_drvinfo		= typhoon_get_drvinfo,
1163ca7a8e85SJeff Kirsher 	.get_wol		= typhoon_get_wol,
1164ca7a8e85SJeff Kirsher 	.set_wol		= typhoon_set_wol,
1165ca7a8e85SJeff Kirsher 	.get_link		= ethtool_op_get_link,
1166ca7a8e85SJeff Kirsher 	.get_ringparam		= typhoon_get_ringparam,
1167ca7a8e85SJeff Kirsher };
1168ca7a8e85SJeff Kirsher 
1169ca7a8e85SJeff Kirsher static int
1170ca7a8e85SJeff Kirsher typhoon_wait_interrupt(void __iomem *ioaddr)
1171ca7a8e85SJeff Kirsher {
1172ca7a8e85SJeff Kirsher 	int i, err = 0;
1173ca7a8e85SJeff Kirsher 
1174ca7a8e85SJeff Kirsher 	for(i = 0; i < TYPHOON_WAIT_TIMEOUT; i++) {
1175ca7a8e85SJeff Kirsher 		if(ioread32(ioaddr + TYPHOON_REG_INTR_STATUS) &
1176ca7a8e85SJeff Kirsher 		   TYPHOON_INTR_BOOTCMD)
1177ca7a8e85SJeff Kirsher 			goto out;
1178ca7a8e85SJeff Kirsher 		udelay(TYPHOON_UDELAY);
1179ca7a8e85SJeff Kirsher 	}
1180ca7a8e85SJeff Kirsher 
1181ca7a8e85SJeff Kirsher 	err = -ETIMEDOUT;
1182ca7a8e85SJeff Kirsher 
1183ca7a8e85SJeff Kirsher out:
1184ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_INTR_BOOTCMD, ioaddr + TYPHOON_REG_INTR_STATUS);
1185ca7a8e85SJeff Kirsher 	return err;
1186ca7a8e85SJeff Kirsher }
1187ca7a8e85SJeff Kirsher 
1188ca7a8e85SJeff Kirsher #define shared_offset(x)	offsetof(struct typhoon_shared, x)
1189ca7a8e85SJeff Kirsher 
1190ca7a8e85SJeff Kirsher static void
1191ca7a8e85SJeff Kirsher typhoon_init_interface(struct typhoon *tp)
1192ca7a8e85SJeff Kirsher {
1193ca7a8e85SJeff Kirsher 	struct typhoon_interface *iface = &tp->shared->iface;
1194ca7a8e85SJeff Kirsher 	dma_addr_t shared_dma;
1195ca7a8e85SJeff Kirsher 
1196ca7a8e85SJeff Kirsher 	memset(tp->shared, 0, sizeof(struct typhoon_shared));
1197ca7a8e85SJeff Kirsher 
1198ca7a8e85SJeff Kirsher 	/* The *Hi members of iface are all init'd to zero by the memset().
1199ca7a8e85SJeff Kirsher 	 */
1200ca7a8e85SJeff Kirsher 	shared_dma = tp->shared_dma + shared_offset(indexes);
1201ca7a8e85SJeff Kirsher 	iface->ringIndex = cpu_to_le32(shared_dma);
1202ca7a8e85SJeff Kirsher 
1203ca7a8e85SJeff Kirsher 	shared_dma = tp->shared_dma + shared_offset(txLo);
1204ca7a8e85SJeff Kirsher 	iface->txLoAddr = cpu_to_le32(shared_dma);
1205ca7a8e85SJeff Kirsher 	iface->txLoSize = cpu_to_le32(TXLO_ENTRIES * sizeof(struct tx_desc));
1206ca7a8e85SJeff Kirsher 
1207ca7a8e85SJeff Kirsher 	shared_dma = tp->shared_dma + shared_offset(txHi);
1208ca7a8e85SJeff Kirsher 	iface->txHiAddr = cpu_to_le32(shared_dma);
1209ca7a8e85SJeff Kirsher 	iface->txHiSize = cpu_to_le32(TXHI_ENTRIES * sizeof(struct tx_desc));
1210ca7a8e85SJeff Kirsher 
1211ca7a8e85SJeff Kirsher 	shared_dma = tp->shared_dma + shared_offset(rxBuff);
1212ca7a8e85SJeff Kirsher 	iface->rxBuffAddr = cpu_to_le32(shared_dma);
1213ca7a8e85SJeff Kirsher 	iface->rxBuffSize = cpu_to_le32(RXFREE_ENTRIES *
1214ca7a8e85SJeff Kirsher 					sizeof(struct rx_free));
1215ca7a8e85SJeff Kirsher 
1216ca7a8e85SJeff Kirsher 	shared_dma = tp->shared_dma + shared_offset(rxLo);
1217ca7a8e85SJeff Kirsher 	iface->rxLoAddr = cpu_to_le32(shared_dma);
1218ca7a8e85SJeff Kirsher 	iface->rxLoSize = cpu_to_le32(RX_ENTRIES * sizeof(struct rx_desc));
1219ca7a8e85SJeff Kirsher 
1220ca7a8e85SJeff Kirsher 	shared_dma = tp->shared_dma + shared_offset(rxHi);
1221ca7a8e85SJeff Kirsher 	iface->rxHiAddr = cpu_to_le32(shared_dma);
1222ca7a8e85SJeff Kirsher 	iface->rxHiSize = cpu_to_le32(RX_ENTRIES * sizeof(struct rx_desc));
1223ca7a8e85SJeff Kirsher 
1224ca7a8e85SJeff Kirsher 	shared_dma = tp->shared_dma + shared_offset(cmd);
1225ca7a8e85SJeff Kirsher 	iface->cmdAddr = cpu_to_le32(shared_dma);
1226ca7a8e85SJeff Kirsher 	iface->cmdSize = cpu_to_le32(COMMAND_RING_SIZE);
1227ca7a8e85SJeff Kirsher 
1228ca7a8e85SJeff Kirsher 	shared_dma = tp->shared_dma + shared_offset(resp);
1229ca7a8e85SJeff Kirsher 	iface->respAddr = cpu_to_le32(shared_dma);
1230ca7a8e85SJeff Kirsher 	iface->respSize = cpu_to_le32(RESPONSE_RING_SIZE);
1231ca7a8e85SJeff Kirsher 
1232ca7a8e85SJeff Kirsher 	shared_dma = tp->shared_dma + shared_offset(zeroWord);
1233ca7a8e85SJeff Kirsher 	iface->zeroAddr = cpu_to_le32(shared_dma);
1234ca7a8e85SJeff Kirsher 
1235ca7a8e85SJeff Kirsher 	tp->indexes = &tp->shared->indexes;
1236ca7a8e85SJeff Kirsher 	tp->txLoRing.ringBase = (u8 *) tp->shared->txLo;
1237ca7a8e85SJeff Kirsher 	tp->txHiRing.ringBase = (u8 *) tp->shared->txHi;
1238ca7a8e85SJeff Kirsher 	tp->rxLoRing.ringBase = (u8 *) tp->shared->rxLo;
1239ca7a8e85SJeff Kirsher 	tp->rxHiRing.ringBase = (u8 *) tp->shared->rxHi;
1240ca7a8e85SJeff Kirsher 	tp->rxBuffRing.ringBase = (u8 *) tp->shared->rxBuff;
1241ca7a8e85SJeff Kirsher 	tp->cmdRing.ringBase = (u8 *) tp->shared->cmd;
1242ca7a8e85SJeff Kirsher 	tp->respRing.ringBase = (u8 *) tp->shared->resp;
1243ca7a8e85SJeff Kirsher 
1244ca7a8e85SJeff Kirsher 	tp->txLoRing.writeRegister = TYPHOON_REG_TX_LO_READY;
1245ca7a8e85SJeff Kirsher 	tp->txHiRing.writeRegister = TYPHOON_REG_TX_HI_READY;
1246ca7a8e85SJeff Kirsher 
1247ca7a8e85SJeff Kirsher 	tp->txlo_dma_addr = le32_to_cpu(iface->txLoAddr);
1248ca7a8e85SJeff Kirsher 	tp->card_state = Sleeping;
1249ca7a8e85SJeff Kirsher 
1250ca7a8e85SJeff Kirsher 	tp->offload = TYPHOON_OFFLOAD_IP_CHKSUM | TYPHOON_OFFLOAD_TCP_CHKSUM;
1251ca7a8e85SJeff Kirsher 	tp->offload |= TYPHOON_OFFLOAD_UDP_CHKSUM | TSO_OFFLOAD_ON;
1252ca7a8e85SJeff Kirsher 	tp->offload |= TYPHOON_OFFLOAD_VLAN;
1253ca7a8e85SJeff Kirsher 
1254ca7a8e85SJeff Kirsher 	spin_lock_init(&tp->command_lock);
1255ca7a8e85SJeff Kirsher 
1256ca7a8e85SJeff Kirsher 	/* Force the writes to the shared memory area out before continuing. */
1257ca7a8e85SJeff Kirsher 	wmb();
1258ca7a8e85SJeff Kirsher }
1259ca7a8e85SJeff Kirsher 
1260ca7a8e85SJeff Kirsher static void
1261ca7a8e85SJeff Kirsher typhoon_init_rings(struct typhoon *tp)
1262ca7a8e85SJeff Kirsher {
1263ca7a8e85SJeff Kirsher 	memset(tp->indexes, 0, sizeof(struct typhoon_indexes));
1264ca7a8e85SJeff Kirsher 
1265ca7a8e85SJeff Kirsher 	tp->txLoRing.lastWrite = 0;
1266ca7a8e85SJeff Kirsher 	tp->txHiRing.lastWrite = 0;
1267ca7a8e85SJeff Kirsher 	tp->rxLoRing.lastWrite = 0;
1268ca7a8e85SJeff Kirsher 	tp->rxHiRing.lastWrite = 0;
1269ca7a8e85SJeff Kirsher 	tp->rxBuffRing.lastWrite = 0;
1270ca7a8e85SJeff Kirsher 	tp->cmdRing.lastWrite = 0;
1271ca7a8e85SJeff Kirsher 	tp->respRing.lastWrite = 0;
1272ca7a8e85SJeff Kirsher 
1273ca7a8e85SJeff Kirsher 	tp->txLoRing.lastRead = 0;
1274ca7a8e85SJeff Kirsher 	tp->txHiRing.lastRead = 0;
1275ca7a8e85SJeff Kirsher }
1276ca7a8e85SJeff Kirsher 
1277ca7a8e85SJeff Kirsher static const struct firmware *typhoon_fw;
1278ca7a8e85SJeff Kirsher 
1279ca7a8e85SJeff Kirsher static int
1280ca7a8e85SJeff Kirsher typhoon_request_firmware(struct typhoon *tp)
1281ca7a8e85SJeff Kirsher {
1282ca7a8e85SJeff Kirsher 	const struct typhoon_file_header *fHdr;
1283ca7a8e85SJeff Kirsher 	const struct typhoon_section_header *sHdr;
1284ca7a8e85SJeff Kirsher 	const u8 *image_data;
1285ca7a8e85SJeff Kirsher 	u32 numSections;
1286ca7a8e85SJeff Kirsher 	u32 section_len;
1287ca7a8e85SJeff Kirsher 	u32 remaining;
1288ca7a8e85SJeff Kirsher 	int err;
1289ca7a8e85SJeff Kirsher 
1290ca7a8e85SJeff Kirsher 	if (typhoon_fw)
1291ca7a8e85SJeff Kirsher 		return 0;
1292ca7a8e85SJeff Kirsher 
1293ca7a8e85SJeff Kirsher 	err = request_firmware(&typhoon_fw, FIRMWARE_NAME, &tp->pdev->dev);
1294ca7a8e85SJeff Kirsher 	if (err) {
1295ca7a8e85SJeff Kirsher 		netdev_err(tp->dev, "Failed to load firmware \"%s\"\n",
1296ca7a8e85SJeff Kirsher 			   FIRMWARE_NAME);
1297ca7a8e85SJeff Kirsher 		return err;
1298ca7a8e85SJeff Kirsher 	}
1299ca7a8e85SJeff Kirsher 
1300ca7a8e85SJeff Kirsher 	image_data = (u8 *) typhoon_fw->data;
1301ca7a8e85SJeff Kirsher 	remaining = typhoon_fw->size;
1302ca7a8e85SJeff Kirsher 	if (remaining < sizeof(struct typhoon_file_header))
1303ca7a8e85SJeff Kirsher 		goto invalid_fw;
1304ca7a8e85SJeff Kirsher 
1305ca7a8e85SJeff Kirsher 	fHdr = (struct typhoon_file_header *) image_data;
1306ca7a8e85SJeff Kirsher 	if (memcmp(fHdr->tag, "TYPHOON", 8))
1307ca7a8e85SJeff Kirsher 		goto invalid_fw;
1308ca7a8e85SJeff Kirsher 
1309ca7a8e85SJeff Kirsher 	numSections = le32_to_cpu(fHdr->numSections);
1310ca7a8e85SJeff Kirsher 	image_data += sizeof(struct typhoon_file_header);
1311ca7a8e85SJeff Kirsher 	remaining -= sizeof(struct typhoon_file_header);
1312ca7a8e85SJeff Kirsher 
1313ca7a8e85SJeff Kirsher 	while (numSections--) {
1314ca7a8e85SJeff Kirsher 		if (remaining < sizeof(struct typhoon_section_header))
1315ca7a8e85SJeff Kirsher 			goto invalid_fw;
1316ca7a8e85SJeff Kirsher 
1317ca7a8e85SJeff Kirsher 		sHdr = (struct typhoon_section_header *) image_data;
1318ca7a8e85SJeff Kirsher 		image_data += sizeof(struct typhoon_section_header);
1319ca7a8e85SJeff Kirsher 		section_len = le32_to_cpu(sHdr->len);
1320ca7a8e85SJeff Kirsher 
1321ca7a8e85SJeff Kirsher 		if (remaining < section_len)
1322ca7a8e85SJeff Kirsher 			goto invalid_fw;
1323ca7a8e85SJeff Kirsher 
1324ca7a8e85SJeff Kirsher 		image_data += section_len;
1325ca7a8e85SJeff Kirsher 		remaining -= section_len;
1326ca7a8e85SJeff Kirsher 	}
1327ca7a8e85SJeff Kirsher 
1328ca7a8e85SJeff Kirsher 	return 0;
1329ca7a8e85SJeff Kirsher 
1330ca7a8e85SJeff Kirsher invalid_fw:
1331ca7a8e85SJeff Kirsher 	netdev_err(tp->dev, "Invalid firmware image\n");
1332ca7a8e85SJeff Kirsher 	release_firmware(typhoon_fw);
1333ca7a8e85SJeff Kirsher 	typhoon_fw = NULL;
1334ca7a8e85SJeff Kirsher 	return -EINVAL;
1335ca7a8e85SJeff Kirsher }
1336ca7a8e85SJeff Kirsher 
1337ca7a8e85SJeff Kirsher static int
1338ca7a8e85SJeff Kirsher typhoon_download_firmware(struct typhoon *tp)
1339ca7a8e85SJeff Kirsher {
1340ca7a8e85SJeff Kirsher 	void __iomem *ioaddr = tp->ioaddr;
1341ca7a8e85SJeff Kirsher 	struct pci_dev *pdev = tp->pdev;
1342ca7a8e85SJeff Kirsher 	const struct typhoon_file_header *fHdr;
1343ca7a8e85SJeff Kirsher 	const struct typhoon_section_header *sHdr;
1344ca7a8e85SJeff Kirsher 	const u8 *image_data;
1345ca7a8e85SJeff Kirsher 	void *dpage;
1346ca7a8e85SJeff Kirsher 	dma_addr_t dpage_dma;
1347ca7a8e85SJeff Kirsher 	__sum16 csum;
1348ca7a8e85SJeff Kirsher 	u32 irqEnabled;
1349ca7a8e85SJeff Kirsher 	u32 irqMasked;
1350ca7a8e85SJeff Kirsher 	u32 numSections;
1351ca7a8e85SJeff Kirsher 	u32 section_len;
1352ca7a8e85SJeff Kirsher 	u32 len;
1353ca7a8e85SJeff Kirsher 	u32 load_addr;
1354ca7a8e85SJeff Kirsher 	u32 hmac;
1355ca7a8e85SJeff Kirsher 	int i;
1356ca7a8e85SJeff Kirsher 	int err;
1357ca7a8e85SJeff Kirsher 
1358ca7a8e85SJeff Kirsher 	image_data = (u8 *) typhoon_fw->data;
1359ca7a8e85SJeff Kirsher 	fHdr = (struct typhoon_file_header *) image_data;
1360ca7a8e85SJeff Kirsher 
1361ca7a8e85SJeff Kirsher 	/* Cannot just map the firmware image using pci_map_single() as
1362ca7a8e85SJeff Kirsher 	 * the firmware is vmalloc()'d and may not be physically contiguous,
1363ca7a8e85SJeff Kirsher 	 * so we allocate some consistent memory to copy the sections into.
1364ca7a8e85SJeff Kirsher 	 */
1365ca7a8e85SJeff Kirsher 	err = -ENOMEM;
1366ca7a8e85SJeff Kirsher 	dpage = pci_alloc_consistent(pdev, PAGE_SIZE, &dpage_dma);
1367ca7a8e85SJeff Kirsher 	if(!dpage) {
1368ca7a8e85SJeff Kirsher 		netdev_err(tp->dev, "no DMA mem for firmware\n");
1369ca7a8e85SJeff Kirsher 		goto err_out;
1370ca7a8e85SJeff Kirsher 	}
1371ca7a8e85SJeff Kirsher 
1372ca7a8e85SJeff Kirsher 	irqEnabled = ioread32(ioaddr + TYPHOON_REG_INTR_ENABLE);
1373ca7a8e85SJeff Kirsher 	iowrite32(irqEnabled | TYPHOON_INTR_BOOTCMD,
1374ca7a8e85SJeff Kirsher 	       ioaddr + TYPHOON_REG_INTR_ENABLE);
1375ca7a8e85SJeff Kirsher 	irqMasked = ioread32(ioaddr + TYPHOON_REG_INTR_MASK);
1376ca7a8e85SJeff Kirsher 	iowrite32(irqMasked | TYPHOON_INTR_BOOTCMD,
1377ca7a8e85SJeff Kirsher 	       ioaddr + TYPHOON_REG_INTR_MASK);
1378ca7a8e85SJeff Kirsher 
1379ca7a8e85SJeff Kirsher 	err = -ETIMEDOUT;
1380ca7a8e85SJeff Kirsher 	if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) {
1381ca7a8e85SJeff Kirsher 		netdev_err(tp->dev, "card ready timeout\n");
1382ca7a8e85SJeff Kirsher 		goto err_out_irq;
1383ca7a8e85SJeff Kirsher 	}
1384ca7a8e85SJeff Kirsher 
1385ca7a8e85SJeff Kirsher 	numSections = le32_to_cpu(fHdr->numSections);
1386ca7a8e85SJeff Kirsher 	load_addr = le32_to_cpu(fHdr->startAddr);
1387ca7a8e85SJeff Kirsher 
1388ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_INTR_BOOTCMD, ioaddr + TYPHOON_REG_INTR_STATUS);
1389ca7a8e85SJeff Kirsher 	iowrite32(load_addr, ioaddr + TYPHOON_REG_DOWNLOAD_BOOT_ADDR);
1390ca7a8e85SJeff Kirsher 	hmac = le32_to_cpu(fHdr->hmacDigest[0]);
1391ca7a8e85SJeff Kirsher 	iowrite32(hmac, ioaddr + TYPHOON_REG_DOWNLOAD_HMAC_0);
1392ca7a8e85SJeff Kirsher 	hmac = le32_to_cpu(fHdr->hmacDigest[1]);
1393ca7a8e85SJeff Kirsher 	iowrite32(hmac, ioaddr + TYPHOON_REG_DOWNLOAD_HMAC_1);
1394ca7a8e85SJeff Kirsher 	hmac = le32_to_cpu(fHdr->hmacDigest[2]);
1395ca7a8e85SJeff Kirsher 	iowrite32(hmac, ioaddr + TYPHOON_REG_DOWNLOAD_HMAC_2);
1396ca7a8e85SJeff Kirsher 	hmac = le32_to_cpu(fHdr->hmacDigest[3]);
1397ca7a8e85SJeff Kirsher 	iowrite32(hmac, ioaddr + TYPHOON_REG_DOWNLOAD_HMAC_3);
1398ca7a8e85SJeff Kirsher 	hmac = le32_to_cpu(fHdr->hmacDigest[4]);
1399ca7a8e85SJeff Kirsher 	iowrite32(hmac, ioaddr + TYPHOON_REG_DOWNLOAD_HMAC_4);
1400ca7a8e85SJeff Kirsher 	typhoon_post_pci_writes(ioaddr);
1401ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_BOOTCMD_RUNTIME_IMAGE, ioaddr + TYPHOON_REG_COMMAND);
1402ca7a8e85SJeff Kirsher 
1403ca7a8e85SJeff Kirsher 	image_data += sizeof(struct typhoon_file_header);
1404ca7a8e85SJeff Kirsher 
1405ca7a8e85SJeff Kirsher 	/* The ioread32() in typhoon_wait_interrupt() will force the
1406ca7a8e85SJeff Kirsher 	 * last write to the command register to post, so
1407ca7a8e85SJeff Kirsher 	 * we don't need a typhoon_post_pci_writes() after it.
1408ca7a8e85SJeff Kirsher 	 */
1409ca7a8e85SJeff Kirsher 	for(i = 0; i < numSections; i++) {
1410ca7a8e85SJeff Kirsher 		sHdr = (struct typhoon_section_header *) image_data;
1411ca7a8e85SJeff Kirsher 		image_data += sizeof(struct typhoon_section_header);
1412ca7a8e85SJeff Kirsher 		load_addr = le32_to_cpu(sHdr->startAddr);
1413ca7a8e85SJeff Kirsher 		section_len = le32_to_cpu(sHdr->len);
1414ca7a8e85SJeff Kirsher 
1415ca7a8e85SJeff Kirsher 		while(section_len) {
1416ca7a8e85SJeff Kirsher 			len = min_t(u32, section_len, PAGE_SIZE);
1417ca7a8e85SJeff Kirsher 
1418ca7a8e85SJeff Kirsher 			if(typhoon_wait_interrupt(ioaddr) < 0 ||
1419ca7a8e85SJeff Kirsher 			   ioread32(ioaddr + TYPHOON_REG_STATUS) !=
1420ca7a8e85SJeff Kirsher 			   TYPHOON_STATUS_WAITING_FOR_SEGMENT) {
1421ca7a8e85SJeff Kirsher 				netdev_err(tp->dev, "segment ready timeout\n");
1422ca7a8e85SJeff Kirsher 				goto err_out_irq;
1423ca7a8e85SJeff Kirsher 			}
1424ca7a8e85SJeff Kirsher 
1425ca7a8e85SJeff Kirsher 			/* Do an pseudo IPv4 checksum on the data -- first
1426ca7a8e85SJeff Kirsher 			 * need to convert each u16 to cpu order before
1427ca7a8e85SJeff Kirsher 			 * summing. Fortunately, due to the properties of
1428ca7a8e85SJeff Kirsher 			 * the checksum, we can do this once, at the end.
1429ca7a8e85SJeff Kirsher 			 */
1430ca7a8e85SJeff Kirsher 			csum = csum_fold(csum_partial_copy_nocheck(image_data,
1431ca7a8e85SJeff Kirsher 								   dpage, len,
1432ca7a8e85SJeff Kirsher 								   0));
1433ca7a8e85SJeff Kirsher 
1434ca7a8e85SJeff Kirsher 			iowrite32(len, ioaddr + TYPHOON_REG_BOOT_LENGTH);
1435ca7a8e85SJeff Kirsher 			iowrite32(le16_to_cpu((__force __le16)csum),
1436ca7a8e85SJeff Kirsher 					ioaddr + TYPHOON_REG_BOOT_CHECKSUM);
1437ca7a8e85SJeff Kirsher 			iowrite32(load_addr,
1438ca7a8e85SJeff Kirsher 					ioaddr + TYPHOON_REG_BOOT_DEST_ADDR);
1439ca7a8e85SJeff Kirsher 			iowrite32(0, ioaddr + TYPHOON_REG_BOOT_DATA_HI);
1440ca7a8e85SJeff Kirsher 			iowrite32(dpage_dma, ioaddr + TYPHOON_REG_BOOT_DATA_LO);
1441ca7a8e85SJeff Kirsher 			typhoon_post_pci_writes(ioaddr);
1442ca7a8e85SJeff Kirsher 			iowrite32(TYPHOON_BOOTCMD_SEG_AVAILABLE,
1443ca7a8e85SJeff Kirsher 					ioaddr + TYPHOON_REG_COMMAND);
1444ca7a8e85SJeff Kirsher 
1445ca7a8e85SJeff Kirsher 			image_data += len;
1446ca7a8e85SJeff Kirsher 			load_addr += len;
1447ca7a8e85SJeff Kirsher 			section_len -= len;
1448ca7a8e85SJeff Kirsher 		}
1449ca7a8e85SJeff Kirsher 	}
1450ca7a8e85SJeff Kirsher 
1451ca7a8e85SJeff Kirsher 	if(typhoon_wait_interrupt(ioaddr) < 0 ||
1452ca7a8e85SJeff Kirsher 	   ioread32(ioaddr + TYPHOON_REG_STATUS) !=
1453ca7a8e85SJeff Kirsher 	   TYPHOON_STATUS_WAITING_FOR_SEGMENT) {
1454ca7a8e85SJeff Kirsher 		netdev_err(tp->dev, "final segment ready timeout\n");
1455ca7a8e85SJeff Kirsher 		goto err_out_irq;
1456ca7a8e85SJeff Kirsher 	}
1457ca7a8e85SJeff Kirsher 
1458ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_BOOTCMD_DNLD_COMPLETE, ioaddr + TYPHOON_REG_COMMAND);
1459ca7a8e85SJeff Kirsher 
1460ca7a8e85SJeff Kirsher 	if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_BOOT) < 0) {
1461ca7a8e85SJeff Kirsher 		netdev_err(tp->dev, "boot ready timeout, status 0x%0x\n",
1462ca7a8e85SJeff Kirsher 			   ioread32(ioaddr + TYPHOON_REG_STATUS));
1463ca7a8e85SJeff Kirsher 		goto err_out_irq;
1464ca7a8e85SJeff Kirsher 	}
1465ca7a8e85SJeff Kirsher 
1466ca7a8e85SJeff Kirsher 	err = 0;
1467ca7a8e85SJeff Kirsher 
1468ca7a8e85SJeff Kirsher err_out_irq:
1469ca7a8e85SJeff Kirsher 	iowrite32(irqMasked, ioaddr + TYPHOON_REG_INTR_MASK);
1470ca7a8e85SJeff Kirsher 	iowrite32(irqEnabled, ioaddr + TYPHOON_REG_INTR_ENABLE);
1471ca7a8e85SJeff Kirsher 
1472ca7a8e85SJeff Kirsher 	pci_free_consistent(pdev, PAGE_SIZE, dpage, dpage_dma);
1473ca7a8e85SJeff Kirsher 
1474ca7a8e85SJeff Kirsher err_out:
1475ca7a8e85SJeff Kirsher 	return err;
1476ca7a8e85SJeff Kirsher }
1477ca7a8e85SJeff Kirsher 
1478ca7a8e85SJeff Kirsher static int
1479ca7a8e85SJeff Kirsher typhoon_boot_3XP(struct typhoon *tp, u32 initial_status)
1480ca7a8e85SJeff Kirsher {
1481ca7a8e85SJeff Kirsher 	void __iomem *ioaddr = tp->ioaddr;
1482ca7a8e85SJeff Kirsher 
1483ca7a8e85SJeff Kirsher 	if(typhoon_wait_status(ioaddr, initial_status) < 0) {
1484ca7a8e85SJeff Kirsher 		netdev_err(tp->dev, "boot ready timeout\n");
1485ca7a8e85SJeff Kirsher 		goto out_timeout;
1486ca7a8e85SJeff Kirsher 	}
1487ca7a8e85SJeff Kirsher 
1488ca7a8e85SJeff Kirsher 	iowrite32(0, ioaddr + TYPHOON_REG_BOOT_RECORD_ADDR_HI);
1489ca7a8e85SJeff Kirsher 	iowrite32(tp->shared_dma, ioaddr + TYPHOON_REG_BOOT_RECORD_ADDR_LO);
1490ca7a8e85SJeff Kirsher 	typhoon_post_pci_writes(ioaddr);
1491ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_BOOTCMD_REG_BOOT_RECORD,
1492ca7a8e85SJeff Kirsher 				ioaddr + TYPHOON_REG_COMMAND);
1493ca7a8e85SJeff Kirsher 
1494ca7a8e85SJeff Kirsher 	if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_RUNNING) < 0) {
1495ca7a8e85SJeff Kirsher 		netdev_err(tp->dev, "boot finish timeout (status 0x%x)\n",
1496ca7a8e85SJeff Kirsher 			   ioread32(ioaddr + TYPHOON_REG_STATUS));
1497ca7a8e85SJeff Kirsher 		goto out_timeout;
1498ca7a8e85SJeff Kirsher 	}
1499ca7a8e85SJeff Kirsher 
1500ca7a8e85SJeff Kirsher 	/* Clear the Transmit and Command ready registers
1501ca7a8e85SJeff Kirsher 	 */
1502ca7a8e85SJeff Kirsher 	iowrite32(0, ioaddr + TYPHOON_REG_TX_HI_READY);
1503ca7a8e85SJeff Kirsher 	iowrite32(0, ioaddr + TYPHOON_REG_CMD_READY);
1504ca7a8e85SJeff Kirsher 	iowrite32(0, ioaddr + TYPHOON_REG_TX_LO_READY);
1505ca7a8e85SJeff Kirsher 	typhoon_post_pci_writes(ioaddr);
1506ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_BOOTCMD_BOOT, ioaddr + TYPHOON_REG_COMMAND);
1507ca7a8e85SJeff Kirsher 
1508ca7a8e85SJeff Kirsher 	return 0;
1509ca7a8e85SJeff Kirsher 
1510ca7a8e85SJeff Kirsher out_timeout:
1511ca7a8e85SJeff Kirsher 	return -ETIMEDOUT;
1512ca7a8e85SJeff Kirsher }
1513ca7a8e85SJeff Kirsher 
1514ca7a8e85SJeff Kirsher static u32
1515ca7a8e85SJeff Kirsher typhoon_clean_tx(struct typhoon *tp, struct transmit_ring *txRing,
1516ca7a8e85SJeff Kirsher 			volatile __le32 * index)
1517ca7a8e85SJeff Kirsher {
1518ca7a8e85SJeff Kirsher 	u32 lastRead = txRing->lastRead;
1519ca7a8e85SJeff Kirsher 	struct tx_desc *tx;
1520ca7a8e85SJeff Kirsher 	dma_addr_t skb_dma;
1521ca7a8e85SJeff Kirsher 	int dma_len;
1522ca7a8e85SJeff Kirsher 	int type;
1523ca7a8e85SJeff Kirsher 
1524ca7a8e85SJeff Kirsher 	while(lastRead != le32_to_cpu(*index)) {
1525ca7a8e85SJeff Kirsher 		tx = (struct tx_desc *) (txRing->ringBase + lastRead);
1526ca7a8e85SJeff Kirsher 		type = tx->flags & TYPHOON_TYPE_MASK;
1527ca7a8e85SJeff Kirsher 
1528ca7a8e85SJeff Kirsher 		if(type == TYPHOON_TX_DESC) {
1529ca7a8e85SJeff Kirsher 			/* This tx_desc describes a packet.
1530ca7a8e85SJeff Kirsher 			 */
1531ca7a8e85SJeff Kirsher 			unsigned long ptr = tx->tx_addr;
1532ca7a8e85SJeff Kirsher 			struct sk_buff *skb = (struct sk_buff *) ptr;
1533ca7a8e85SJeff Kirsher 			dev_kfree_skb_irq(skb);
1534ca7a8e85SJeff Kirsher 		} else if(type == TYPHOON_FRAG_DESC) {
1535ca7a8e85SJeff Kirsher 			/* This tx_desc describes a memory mapping. Free it.
1536ca7a8e85SJeff Kirsher 			 */
1537ca7a8e85SJeff Kirsher 			skb_dma = (dma_addr_t) le32_to_cpu(tx->frag.addr);
1538ca7a8e85SJeff Kirsher 			dma_len = le16_to_cpu(tx->len);
1539ca7a8e85SJeff Kirsher 			pci_unmap_single(tp->pdev, skb_dma, dma_len,
1540ca7a8e85SJeff Kirsher 				       PCI_DMA_TODEVICE);
1541ca7a8e85SJeff Kirsher 		}
1542ca7a8e85SJeff Kirsher 
1543ca7a8e85SJeff Kirsher 		tx->flags = 0;
1544ca7a8e85SJeff Kirsher 		typhoon_inc_tx_index(&lastRead, 1);
1545ca7a8e85SJeff Kirsher 	}
1546ca7a8e85SJeff Kirsher 
1547ca7a8e85SJeff Kirsher 	return lastRead;
1548ca7a8e85SJeff Kirsher }
1549ca7a8e85SJeff Kirsher 
1550ca7a8e85SJeff Kirsher static void
1551ca7a8e85SJeff Kirsher typhoon_tx_complete(struct typhoon *tp, struct transmit_ring *txRing,
1552ca7a8e85SJeff Kirsher 			volatile __le32 * index)
1553ca7a8e85SJeff Kirsher {
1554ca7a8e85SJeff Kirsher 	u32 lastRead;
1555ca7a8e85SJeff Kirsher 	int numDesc = MAX_SKB_FRAGS + 1;
1556ca7a8e85SJeff Kirsher 
1557ca7a8e85SJeff Kirsher 	/* This will need changing if we start to use the Hi Tx ring. */
1558ca7a8e85SJeff Kirsher 	lastRead = typhoon_clean_tx(tp, txRing, index);
1559ca7a8e85SJeff Kirsher 	if(netif_queue_stopped(tp->dev) && typhoon_num_free(txRing->lastWrite,
1560ca7a8e85SJeff Kirsher 				lastRead, TXLO_ENTRIES) > (numDesc + 2))
1561ca7a8e85SJeff Kirsher 		netif_wake_queue(tp->dev);
1562ca7a8e85SJeff Kirsher 
1563ca7a8e85SJeff Kirsher 	txRing->lastRead = lastRead;
1564ca7a8e85SJeff Kirsher 	smp_wmb();
1565ca7a8e85SJeff Kirsher }
1566ca7a8e85SJeff Kirsher 
1567ca7a8e85SJeff Kirsher static void
1568ca7a8e85SJeff Kirsher typhoon_recycle_rx_skb(struct typhoon *tp, u32 idx)
1569ca7a8e85SJeff Kirsher {
1570ca7a8e85SJeff Kirsher 	struct typhoon_indexes *indexes = tp->indexes;
1571ca7a8e85SJeff Kirsher 	struct rxbuff_ent *rxb = &tp->rxbuffers[idx];
1572ca7a8e85SJeff Kirsher 	struct basic_ring *ring = &tp->rxBuffRing;
1573ca7a8e85SJeff Kirsher 	struct rx_free *r;
1574ca7a8e85SJeff Kirsher 
1575ca7a8e85SJeff Kirsher 	if((ring->lastWrite + sizeof(*r)) % (RXFREE_ENTRIES * sizeof(*r)) ==
1576ca7a8e85SJeff Kirsher 				le32_to_cpu(indexes->rxBuffCleared)) {
1577ca7a8e85SJeff Kirsher 		/* no room in ring, just drop the skb
1578ca7a8e85SJeff Kirsher 		 */
1579ca7a8e85SJeff Kirsher 		dev_kfree_skb_any(rxb->skb);
1580ca7a8e85SJeff Kirsher 		rxb->skb = NULL;
1581ca7a8e85SJeff Kirsher 		return;
1582ca7a8e85SJeff Kirsher 	}
1583ca7a8e85SJeff Kirsher 
1584ca7a8e85SJeff Kirsher 	r = (struct rx_free *) (ring->ringBase + ring->lastWrite);
1585ca7a8e85SJeff Kirsher 	typhoon_inc_rxfree_index(&ring->lastWrite, 1);
1586ca7a8e85SJeff Kirsher 	r->virtAddr = idx;
1587ca7a8e85SJeff Kirsher 	r->physAddr = cpu_to_le32(rxb->dma_addr);
1588ca7a8e85SJeff Kirsher 
1589ca7a8e85SJeff Kirsher 	/* Tell the card about it */
1590ca7a8e85SJeff Kirsher 	wmb();
1591ca7a8e85SJeff Kirsher 	indexes->rxBuffReady = cpu_to_le32(ring->lastWrite);
1592ca7a8e85SJeff Kirsher }
1593ca7a8e85SJeff Kirsher 
1594ca7a8e85SJeff Kirsher static int
1595ca7a8e85SJeff Kirsher typhoon_alloc_rx_skb(struct typhoon *tp, u32 idx)
1596ca7a8e85SJeff Kirsher {
1597ca7a8e85SJeff Kirsher 	struct typhoon_indexes *indexes = tp->indexes;
1598ca7a8e85SJeff Kirsher 	struct rxbuff_ent *rxb = &tp->rxbuffers[idx];
1599ca7a8e85SJeff Kirsher 	struct basic_ring *ring = &tp->rxBuffRing;
1600ca7a8e85SJeff Kirsher 	struct rx_free *r;
1601ca7a8e85SJeff Kirsher 	struct sk_buff *skb;
1602ca7a8e85SJeff Kirsher 	dma_addr_t dma_addr;
1603ca7a8e85SJeff Kirsher 
1604ca7a8e85SJeff Kirsher 	rxb->skb = NULL;
1605ca7a8e85SJeff Kirsher 
1606ca7a8e85SJeff Kirsher 	if((ring->lastWrite + sizeof(*r)) % (RXFREE_ENTRIES * sizeof(*r)) ==
1607ca7a8e85SJeff Kirsher 				le32_to_cpu(indexes->rxBuffCleared))
1608ca7a8e85SJeff Kirsher 		return -ENOMEM;
1609ca7a8e85SJeff Kirsher 
16101d266430SPradeep A Dalvi 	skb = netdev_alloc_skb(tp->dev, PKT_BUF_SZ);
1611ca7a8e85SJeff Kirsher 	if(!skb)
1612ca7a8e85SJeff Kirsher 		return -ENOMEM;
1613ca7a8e85SJeff Kirsher 
1614ca7a8e85SJeff Kirsher #if 0
1615ca7a8e85SJeff Kirsher 	/* Please, 3com, fix the firmware to allow DMA to a unaligned
1616ca7a8e85SJeff Kirsher 	 * address! Pretty please?
1617ca7a8e85SJeff Kirsher 	 */
1618ca7a8e85SJeff Kirsher 	skb_reserve(skb, 2);
1619ca7a8e85SJeff Kirsher #endif
1620ca7a8e85SJeff Kirsher 
1621ca7a8e85SJeff Kirsher 	dma_addr = pci_map_single(tp->pdev, skb->data,
1622ca7a8e85SJeff Kirsher 				  PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
1623ca7a8e85SJeff Kirsher 
1624ca7a8e85SJeff Kirsher 	/* Since no card does 64 bit DAC, the high bits will never
1625ca7a8e85SJeff Kirsher 	 * change from zero.
1626ca7a8e85SJeff Kirsher 	 */
1627ca7a8e85SJeff Kirsher 	r = (struct rx_free *) (ring->ringBase + ring->lastWrite);
1628ca7a8e85SJeff Kirsher 	typhoon_inc_rxfree_index(&ring->lastWrite, 1);
1629ca7a8e85SJeff Kirsher 	r->virtAddr = idx;
1630ca7a8e85SJeff Kirsher 	r->physAddr = cpu_to_le32(dma_addr);
1631ca7a8e85SJeff Kirsher 	rxb->skb = skb;
1632ca7a8e85SJeff Kirsher 	rxb->dma_addr = dma_addr;
1633ca7a8e85SJeff Kirsher 
1634ca7a8e85SJeff Kirsher 	/* Tell the card about it */
1635ca7a8e85SJeff Kirsher 	wmb();
1636ca7a8e85SJeff Kirsher 	indexes->rxBuffReady = cpu_to_le32(ring->lastWrite);
1637ca7a8e85SJeff Kirsher 	return 0;
1638ca7a8e85SJeff Kirsher }
1639ca7a8e85SJeff Kirsher 
1640ca7a8e85SJeff Kirsher static int
1641ca7a8e85SJeff Kirsher typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile __le32 * ready,
1642ca7a8e85SJeff Kirsher 	   volatile __le32 * cleared, int budget)
1643ca7a8e85SJeff Kirsher {
1644ca7a8e85SJeff Kirsher 	struct rx_desc *rx;
1645ca7a8e85SJeff Kirsher 	struct sk_buff *skb, *new_skb;
1646ca7a8e85SJeff Kirsher 	struct rxbuff_ent *rxb;
1647ca7a8e85SJeff Kirsher 	dma_addr_t dma_addr;
1648ca7a8e85SJeff Kirsher 	u32 local_ready;
1649ca7a8e85SJeff Kirsher 	u32 rxaddr;
1650ca7a8e85SJeff Kirsher 	int pkt_len;
1651ca7a8e85SJeff Kirsher 	u32 idx;
1652ca7a8e85SJeff Kirsher 	__le32 csum_bits;
1653ca7a8e85SJeff Kirsher 	int received;
1654ca7a8e85SJeff Kirsher 
1655ca7a8e85SJeff Kirsher 	received = 0;
1656ca7a8e85SJeff Kirsher 	local_ready = le32_to_cpu(*ready);
1657ca7a8e85SJeff Kirsher 	rxaddr = le32_to_cpu(*cleared);
1658ca7a8e85SJeff Kirsher 	while(rxaddr != local_ready && budget > 0) {
1659ca7a8e85SJeff Kirsher 		rx = (struct rx_desc *) (rxRing->ringBase + rxaddr);
1660ca7a8e85SJeff Kirsher 		idx = rx->addr;
1661ca7a8e85SJeff Kirsher 		rxb = &tp->rxbuffers[idx];
1662ca7a8e85SJeff Kirsher 		skb = rxb->skb;
1663ca7a8e85SJeff Kirsher 		dma_addr = rxb->dma_addr;
1664ca7a8e85SJeff Kirsher 
1665ca7a8e85SJeff Kirsher 		typhoon_inc_rx_index(&rxaddr, 1);
1666ca7a8e85SJeff Kirsher 
1667ca7a8e85SJeff Kirsher 		if(rx->flags & TYPHOON_RX_ERROR) {
1668ca7a8e85SJeff Kirsher 			typhoon_recycle_rx_skb(tp, idx);
1669ca7a8e85SJeff Kirsher 			continue;
1670ca7a8e85SJeff Kirsher 		}
1671ca7a8e85SJeff Kirsher 
1672ca7a8e85SJeff Kirsher 		pkt_len = le16_to_cpu(rx->frameLen);
1673ca7a8e85SJeff Kirsher 
1674ca7a8e85SJeff Kirsher 		if(pkt_len < rx_copybreak &&
16751d266430SPradeep A Dalvi 		   (new_skb = netdev_alloc_skb(tp->dev, pkt_len + 2)) != NULL) {
1676ca7a8e85SJeff Kirsher 			skb_reserve(new_skb, 2);
1677ca7a8e85SJeff Kirsher 			pci_dma_sync_single_for_cpu(tp->pdev, dma_addr,
1678ca7a8e85SJeff Kirsher 						    PKT_BUF_SZ,
1679ca7a8e85SJeff Kirsher 						    PCI_DMA_FROMDEVICE);
1680ca7a8e85SJeff Kirsher 			skb_copy_to_linear_data(new_skb, skb->data, pkt_len);
1681ca7a8e85SJeff Kirsher 			pci_dma_sync_single_for_device(tp->pdev, dma_addr,
1682ca7a8e85SJeff Kirsher 						       PKT_BUF_SZ,
1683ca7a8e85SJeff Kirsher 						       PCI_DMA_FROMDEVICE);
1684ca7a8e85SJeff Kirsher 			skb_put(new_skb, pkt_len);
1685ca7a8e85SJeff Kirsher 			typhoon_recycle_rx_skb(tp, idx);
1686ca7a8e85SJeff Kirsher 		} else {
1687ca7a8e85SJeff Kirsher 			new_skb = skb;
1688ca7a8e85SJeff Kirsher 			skb_put(new_skb, pkt_len);
1689ca7a8e85SJeff Kirsher 			pci_unmap_single(tp->pdev, dma_addr, PKT_BUF_SZ,
1690ca7a8e85SJeff Kirsher 				       PCI_DMA_FROMDEVICE);
1691ca7a8e85SJeff Kirsher 			typhoon_alloc_rx_skb(tp, idx);
1692ca7a8e85SJeff Kirsher 		}
1693ca7a8e85SJeff Kirsher 		new_skb->protocol = eth_type_trans(new_skb, tp->dev);
1694ca7a8e85SJeff Kirsher 		csum_bits = rx->rxStatus & (TYPHOON_RX_IP_CHK_GOOD |
1695ca7a8e85SJeff Kirsher 			TYPHOON_RX_UDP_CHK_GOOD | TYPHOON_RX_TCP_CHK_GOOD);
1696ca7a8e85SJeff Kirsher 		if(csum_bits ==
1697ca7a8e85SJeff Kirsher 		   (TYPHOON_RX_IP_CHK_GOOD | TYPHOON_RX_TCP_CHK_GOOD) ||
1698ca7a8e85SJeff Kirsher 		   csum_bits ==
1699ca7a8e85SJeff Kirsher 		   (TYPHOON_RX_IP_CHK_GOOD | TYPHOON_RX_UDP_CHK_GOOD)) {
1700ca7a8e85SJeff Kirsher 			new_skb->ip_summed = CHECKSUM_UNNECESSARY;
1701ca7a8e85SJeff Kirsher 		} else
1702ca7a8e85SJeff Kirsher 			skb_checksum_none_assert(new_skb);
1703ca7a8e85SJeff Kirsher 
1704ca7a8e85SJeff Kirsher 		if (rx->rxStatus & TYPHOON_RX_VLAN)
1705ca7a8e85SJeff Kirsher 			__vlan_hwaccel_put_tag(new_skb,
1706ca7a8e85SJeff Kirsher 					       ntohl(rx->vlanTag) & 0xffff);
1707ca7a8e85SJeff Kirsher 		netif_receive_skb(new_skb);
1708ca7a8e85SJeff Kirsher 
1709ca7a8e85SJeff Kirsher 		received++;
1710ca7a8e85SJeff Kirsher 		budget--;
1711ca7a8e85SJeff Kirsher 	}
1712ca7a8e85SJeff Kirsher 	*cleared = cpu_to_le32(rxaddr);
1713ca7a8e85SJeff Kirsher 
1714ca7a8e85SJeff Kirsher 	return received;
1715ca7a8e85SJeff Kirsher }
1716ca7a8e85SJeff Kirsher 
1717ca7a8e85SJeff Kirsher static void
1718ca7a8e85SJeff Kirsher typhoon_fill_free_ring(struct typhoon *tp)
1719ca7a8e85SJeff Kirsher {
1720ca7a8e85SJeff Kirsher 	u32 i;
1721ca7a8e85SJeff Kirsher 
1722ca7a8e85SJeff Kirsher 	for(i = 0; i < RXENT_ENTRIES; i++) {
1723ca7a8e85SJeff Kirsher 		struct rxbuff_ent *rxb = &tp->rxbuffers[i];
1724ca7a8e85SJeff Kirsher 		if(rxb->skb)
1725ca7a8e85SJeff Kirsher 			continue;
1726ca7a8e85SJeff Kirsher 		if(typhoon_alloc_rx_skb(tp, i) < 0)
1727ca7a8e85SJeff Kirsher 			break;
1728ca7a8e85SJeff Kirsher 	}
1729ca7a8e85SJeff Kirsher }
1730ca7a8e85SJeff Kirsher 
1731ca7a8e85SJeff Kirsher static int
1732ca7a8e85SJeff Kirsher typhoon_poll(struct napi_struct *napi, int budget)
1733ca7a8e85SJeff Kirsher {
1734ca7a8e85SJeff Kirsher 	struct typhoon *tp = container_of(napi, struct typhoon, napi);
1735ca7a8e85SJeff Kirsher 	struct typhoon_indexes *indexes = tp->indexes;
1736ca7a8e85SJeff Kirsher 	int work_done;
1737ca7a8e85SJeff Kirsher 
1738ca7a8e85SJeff Kirsher 	rmb();
1739ca7a8e85SJeff Kirsher 	if(!tp->awaiting_resp && indexes->respReady != indexes->respCleared)
1740ca7a8e85SJeff Kirsher 			typhoon_process_response(tp, 0, NULL);
1741ca7a8e85SJeff Kirsher 
1742ca7a8e85SJeff Kirsher 	if(le32_to_cpu(indexes->txLoCleared) != tp->txLoRing.lastRead)
1743ca7a8e85SJeff Kirsher 		typhoon_tx_complete(tp, &tp->txLoRing, &indexes->txLoCleared);
1744ca7a8e85SJeff Kirsher 
1745ca7a8e85SJeff Kirsher 	work_done = 0;
1746ca7a8e85SJeff Kirsher 
1747ca7a8e85SJeff Kirsher 	if(indexes->rxHiCleared != indexes->rxHiReady) {
1748ca7a8e85SJeff Kirsher 		work_done += typhoon_rx(tp, &tp->rxHiRing, &indexes->rxHiReady,
1749ca7a8e85SJeff Kirsher 			   		&indexes->rxHiCleared, budget);
1750ca7a8e85SJeff Kirsher 	}
1751ca7a8e85SJeff Kirsher 
1752ca7a8e85SJeff Kirsher 	if(indexes->rxLoCleared != indexes->rxLoReady) {
1753ca7a8e85SJeff Kirsher 		work_done += typhoon_rx(tp, &tp->rxLoRing, &indexes->rxLoReady,
1754ca7a8e85SJeff Kirsher 					&indexes->rxLoCleared, budget - work_done);
1755ca7a8e85SJeff Kirsher 	}
1756ca7a8e85SJeff Kirsher 
1757ca7a8e85SJeff Kirsher 	if(le32_to_cpu(indexes->rxBuffCleared) == tp->rxBuffRing.lastWrite) {
1758ca7a8e85SJeff Kirsher 		/* rxBuff ring is empty, try to fill it. */
1759ca7a8e85SJeff Kirsher 		typhoon_fill_free_ring(tp);
1760ca7a8e85SJeff Kirsher 	}
1761ca7a8e85SJeff Kirsher 
1762ca7a8e85SJeff Kirsher 	if (work_done < budget) {
1763ca7a8e85SJeff Kirsher 		napi_complete(napi);
1764ca7a8e85SJeff Kirsher 		iowrite32(TYPHOON_INTR_NONE,
1765ca7a8e85SJeff Kirsher 				tp->ioaddr + TYPHOON_REG_INTR_MASK);
1766ca7a8e85SJeff Kirsher 		typhoon_post_pci_writes(tp->ioaddr);
1767ca7a8e85SJeff Kirsher 	}
1768ca7a8e85SJeff Kirsher 
1769ca7a8e85SJeff Kirsher 	return work_done;
1770ca7a8e85SJeff Kirsher }
1771ca7a8e85SJeff Kirsher 
1772ca7a8e85SJeff Kirsher static irqreturn_t
1773ca7a8e85SJeff Kirsher typhoon_interrupt(int irq, void *dev_instance)
1774ca7a8e85SJeff Kirsher {
1775ca7a8e85SJeff Kirsher 	struct net_device *dev = dev_instance;
1776ca7a8e85SJeff Kirsher 	struct typhoon *tp = netdev_priv(dev);
1777ca7a8e85SJeff Kirsher 	void __iomem *ioaddr = tp->ioaddr;
1778ca7a8e85SJeff Kirsher 	u32 intr_status;
1779ca7a8e85SJeff Kirsher 
1780ca7a8e85SJeff Kirsher 	intr_status = ioread32(ioaddr + TYPHOON_REG_INTR_STATUS);
1781ca7a8e85SJeff Kirsher 	if(!(intr_status & TYPHOON_INTR_HOST_INT))
1782ca7a8e85SJeff Kirsher 		return IRQ_NONE;
1783ca7a8e85SJeff Kirsher 
1784ca7a8e85SJeff Kirsher 	iowrite32(intr_status, ioaddr + TYPHOON_REG_INTR_STATUS);
1785ca7a8e85SJeff Kirsher 
1786ca7a8e85SJeff Kirsher 	if (napi_schedule_prep(&tp->napi)) {
1787ca7a8e85SJeff Kirsher 		iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK);
1788ca7a8e85SJeff Kirsher 		typhoon_post_pci_writes(ioaddr);
1789ca7a8e85SJeff Kirsher 		__napi_schedule(&tp->napi);
1790ca7a8e85SJeff Kirsher 	} else {
1791ca7a8e85SJeff Kirsher 		netdev_err(dev, "Error, poll already scheduled\n");
1792ca7a8e85SJeff Kirsher 	}
1793ca7a8e85SJeff Kirsher 	return IRQ_HANDLED;
1794ca7a8e85SJeff Kirsher }
1795ca7a8e85SJeff Kirsher 
1796ca7a8e85SJeff Kirsher static void
1797ca7a8e85SJeff Kirsher typhoon_free_rx_rings(struct typhoon *tp)
1798ca7a8e85SJeff Kirsher {
1799ca7a8e85SJeff Kirsher 	u32 i;
1800ca7a8e85SJeff Kirsher 
1801ca7a8e85SJeff Kirsher 	for(i = 0; i < RXENT_ENTRIES; i++) {
1802ca7a8e85SJeff Kirsher 		struct rxbuff_ent *rxb = &tp->rxbuffers[i];
1803ca7a8e85SJeff Kirsher 		if(rxb->skb) {
1804ca7a8e85SJeff Kirsher 			pci_unmap_single(tp->pdev, rxb->dma_addr, PKT_BUF_SZ,
1805ca7a8e85SJeff Kirsher 				       PCI_DMA_FROMDEVICE);
1806ca7a8e85SJeff Kirsher 			dev_kfree_skb(rxb->skb);
1807ca7a8e85SJeff Kirsher 			rxb->skb = NULL;
1808ca7a8e85SJeff Kirsher 		}
1809ca7a8e85SJeff Kirsher 	}
1810ca7a8e85SJeff Kirsher }
1811ca7a8e85SJeff Kirsher 
1812ca7a8e85SJeff Kirsher static int
1813ca7a8e85SJeff Kirsher typhoon_sleep(struct typhoon *tp, pci_power_t state, __le16 events)
1814ca7a8e85SJeff Kirsher {
1815ca7a8e85SJeff Kirsher 	struct pci_dev *pdev = tp->pdev;
1816ca7a8e85SJeff Kirsher 	void __iomem *ioaddr = tp->ioaddr;
1817ca7a8e85SJeff Kirsher 	struct cmd_desc xp_cmd;
1818ca7a8e85SJeff Kirsher 	int err;
1819ca7a8e85SJeff Kirsher 
1820ca7a8e85SJeff Kirsher 	INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_ENABLE_WAKE_EVENTS);
1821ca7a8e85SJeff Kirsher 	xp_cmd.parm1 = events;
1822ca7a8e85SJeff Kirsher 	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
1823ca7a8e85SJeff Kirsher 	if(err < 0) {
1824ca7a8e85SJeff Kirsher 		netdev_err(tp->dev, "typhoon_sleep(): wake events cmd err %d\n",
1825ca7a8e85SJeff Kirsher 			   err);
1826ca7a8e85SJeff Kirsher 		return err;
1827ca7a8e85SJeff Kirsher 	}
1828ca7a8e85SJeff Kirsher 
1829ca7a8e85SJeff Kirsher 	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_GOTO_SLEEP);
1830ca7a8e85SJeff Kirsher 	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
1831ca7a8e85SJeff Kirsher 	if(err < 0) {
1832ca7a8e85SJeff Kirsher 		netdev_err(tp->dev, "typhoon_sleep(): sleep cmd err %d\n", err);
1833ca7a8e85SJeff Kirsher 		return err;
1834ca7a8e85SJeff Kirsher 	}
1835ca7a8e85SJeff Kirsher 
1836ca7a8e85SJeff Kirsher 	if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_SLEEPING) < 0)
1837ca7a8e85SJeff Kirsher 		return -ETIMEDOUT;
1838ca7a8e85SJeff Kirsher 
1839ca7a8e85SJeff Kirsher 	/* Since we cannot monitor the status of the link while sleeping,
1840ca7a8e85SJeff Kirsher 	 * tell the world it went away.
1841ca7a8e85SJeff Kirsher 	 */
1842ca7a8e85SJeff Kirsher 	netif_carrier_off(tp->dev);
1843ca7a8e85SJeff Kirsher 
1844ca7a8e85SJeff Kirsher 	pci_enable_wake(tp->pdev, state, 1);
1845ca7a8e85SJeff Kirsher 	pci_disable_device(pdev);
1846ca7a8e85SJeff Kirsher 	return pci_set_power_state(pdev, state);
1847ca7a8e85SJeff Kirsher }
1848ca7a8e85SJeff Kirsher 
1849ca7a8e85SJeff Kirsher static int
1850ca7a8e85SJeff Kirsher typhoon_wakeup(struct typhoon *tp, int wait_type)
1851ca7a8e85SJeff Kirsher {
1852ca7a8e85SJeff Kirsher 	struct pci_dev *pdev = tp->pdev;
1853ca7a8e85SJeff Kirsher 	void __iomem *ioaddr = tp->ioaddr;
1854ca7a8e85SJeff Kirsher 
1855ca7a8e85SJeff Kirsher 	pci_set_power_state(pdev, PCI_D0);
1856ca7a8e85SJeff Kirsher 	pci_restore_state(pdev);
1857ca7a8e85SJeff Kirsher 
1858ca7a8e85SJeff Kirsher 	/* Post 2.x.x versions of the Sleep Image require a reset before
1859ca7a8e85SJeff Kirsher 	 * we can download the Runtime Image. But let's not make users of
1860ca7a8e85SJeff Kirsher 	 * the old firmware pay for the reset.
1861ca7a8e85SJeff Kirsher 	 */
1862ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_BOOTCMD_WAKEUP, ioaddr + TYPHOON_REG_COMMAND);
1863ca7a8e85SJeff Kirsher 	if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_HOST) < 0 ||
1864ca7a8e85SJeff Kirsher 			(tp->capabilities & TYPHOON_WAKEUP_NEEDS_RESET))
1865ca7a8e85SJeff Kirsher 		return typhoon_reset(ioaddr, wait_type);
1866ca7a8e85SJeff Kirsher 
1867ca7a8e85SJeff Kirsher 	return 0;
1868ca7a8e85SJeff Kirsher }
1869ca7a8e85SJeff Kirsher 
1870ca7a8e85SJeff Kirsher static int
1871ca7a8e85SJeff Kirsher typhoon_start_runtime(struct typhoon *tp)
1872ca7a8e85SJeff Kirsher {
1873ca7a8e85SJeff Kirsher 	struct net_device *dev = tp->dev;
1874ca7a8e85SJeff Kirsher 	void __iomem *ioaddr = tp->ioaddr;
1875ca7a8e85SJeff Kirsher 	struct cmd_desc xp_cmd;
1876ca7a8e85SJeff Kirsher 	int err;
1877ca7a8e85SJeff Kirsher 
1878ca7a8e85SJeff Kirsher 	typhoon_init_rings(tp);
1879ca7a8e85SJeff Kirsher 	typhoon_fill_free_ring(tp);
1880ca7a8e85SJeff Kirsher 
1881ca7a8e85SJeff Kirsher 	err = typhoon_download_firmware(tp);
1882ca7a8e85SJeff Kirsher 	if(err < 0) {
1883ca7a8e85SJeff Kirsher 		netdev_err(tp->dev, "cannot load runtime on 3XP\n");
1884ca7a8e85SJeff Kirsher 		goto error_out;
1885ca7a8e85SJeff Kirsher 	}
1886ca7a8e85SJeff Kirsher 
1887ca7a8e85SJeff Kirsher 	if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_BOOT) < 0) {
1888ca7a8e85SJeff Kirsher 		netdev_err(tp->dev, "cannot boot 3XP\n");
1889ca7a8e85SJeff Kirsher 		err = -EIO;
1890ca7a8e85SJeff Kirsher 		goto error_out;
1891ca7a8e85SJeff Kirsher 	}
1892ca7a8e85SJeff Kirsher 
1893ca7a8e85SJeff Kirsher 	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_MAX_PKT_SIZE);
1894ca7a8e85SJeff Kirsher 	xp_cmd.parm1 = cpu_to_le16(PKT_BUF_SZ);
1895ca7a8e85SJeff Kirsher 	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
1896ca7a8e85SJeff Kirsher 	if(err < 0)
1897ca7a8e85SJeff Kirsher 		goto error_out;
1898ca7a8e85SJeff Kirsher 
1899ca7a8e85SJeff Kirsher 	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_MAC_ADDRESS);
1900ca7a8e85SJeff Kirsher 	xp_cmd.parm1 = cpu_to_le16(ntohs(*(__be16 *)&dev->dev_addr[0]));
1901ca7a8e85SJeff Kirsher 	xp_cmd.parm2 = cpu_to_le32(ntohl(*(__be32 *)&dev->dev_addr[2]));
1902ca7a8e85SJeff Kirsher 	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
1903ca7a8e85SJeff Kirsher 	if(err < 0)
1904ca7a8e85SJeff Kirsher 		goto error_out;
1905ca7a8e85SJeff Kirsher 
1906ca7a8e85SJeff Kirsher 	/* Disable IRQ coalescing -- we can reenable it when 3Com gives
1907ca7a8e85SJeff Kirsher 	 * us some more information on how to control it.
1908ca7a8e85SJeff Kirsher 	 */
1909ca7a8e85SJeff Kirsher 	INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_IRQ_COALESCE_CTRL);
1910ca7a8e85SJeff Kirsher 	xp_cmd.parm1 = 0;
1911ca7a8e85SJeff Kirsher 	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
1912ca7a8e85SJeff Kirsher 	if(err < 0)
1913ca7a8e85SJeff Kirsher 		goto error_out;
1914ca7a8e85SJeff Kirsher 
1915ca7a8e85SJeff Kirsher 	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_XCVR_SELECT);
1916ca7a8e85SJeff Kirsher 	xp_cmd.parm1 = tp->xcvr_select;
1917ca7a8e85SJeff Kirsher 	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
1918ca7a8e85SJeff Kirsher 	if(err < 0)
1919ca7a8e85SJeff Kirsher 		goto error_out;
1920ca7a8e85SJeff Kirsher 
1921ca7a8e85SJeff Kirsher 	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_VLAN_TYPE_WRITE);
1922ca7a8e85SJeff Kirsher 	xp_cmd.parm1 = cpu_to_le16(ETH_P_8021Q);
1923ca7a8e85SJeff Kirsher 	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
1924ca7a8e85SJeff Kirsher 	if(err < 0)
1925ca7a8e85SJeff Kirsher 		goto error_out;
1926ca7a8e85SJeff Kirsher 
1927ca7a8e85SJeff Kirsher 	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_OFFLOAD_TASKS);
1928ca7a8e85SJeff Kirsher 	xp_cmd.parm2 = tp->offload;
1929ca7a8e85SJeff Kirsher 	xp_cmd.parm3 = tp->offload;
1930ca7a8e85SJeff Kirsher 	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
1931ca7a8e85SJeff Kirsher 	if(err < 0)
1932ca7a8e85SJeff Kirsher 		goto error_out;
1933ca7a8e85SJeff Kirsher 
1934ca7a8e85SJeff Kirsher 	typhoon_set_rx_mode(dev);
1935ca7a8e85SJeff Kirsher 
1936ca7a8e85SJeff Kirsher 	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_TX_ENABLE);
1937ca7a8e85SJeff Kirsher 	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
1938ca7a8e85SJeff Kirsher 	if(err < 0)
1939ca7a8e85SJeff Kirsher 		goto error_out;
1940ca7a8e85SJeff Kirsher 
1941ca7a8e85SJeff Kirsher 	INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_RX_ENABLE);
1942ca7a8e85SJeff Kirsher 	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
1943ca7a8e85SJeff Kirsher 	if(err < 0)
1944ca7a8e85SJeff Kirsher 		goto error_out;
1945ca7a8e85SJeff Kirsher 
1946ca7a8e85SJeff Kirsher 	tp->card_state = Running;
1947ca7a8e85SJeff Kirsher 	smp_wmb();
1948ca7a8e85SJeff Kirsher 
1949ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_INTR_ENABLE_ALL, ioaddr + TYPHOON_REG_INTR_ENABLE);
1950ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_INTR_NONE, ioaddr + TYPHOON_REG_INTR_MASK);
1951ca7a8e85SJeff Kirsher 	typhoon_post_pci_writes(ioaddr);
1952ca7a8e85SJeff Kirsher 
1953ca7a8e85SJeff Kirsher 	return 0;
1954ca7a8e85SJeff Kirsher 
1955ca7a8e85SJeff Kirsher error_out:
1956ca7a8e85SJeff Kirsher 	typhoon_reset(ioaddr, WaitNoSleep);
1957ca7a8e85SJeff Kirsher 	typhoon_free_rx_rings(tp);
1958ca7a8e85SJeff Kirsher 	typhoon_init_rings(tp);
1959ca7a8e85SJeff Kirsher 	return err;
1960ca7a8e85SJeff Kirsher }
1961ca7a8e85SJeff Kirsher 
1962ca7a8e85SJeff Kirsher static int
1963ca7a8e85SJeff Kirsher typhoon_stop_runtime(struct typhoon *tp, int wait_type)
1964ca7a8e85SJeff Kirsher {
1965ca7a8e85SJeff Kirsher 	struct typhoon_indexes *indexes = tp->indexes;
1966ca7a8e85SJeff Kirsher 	struct transmit_ring *txLo = &tp->txLoRing;
1967ca7a8e85SJeff Kirsher 	void __iomem *ioaddr = tp->ioaddr;
1968ca7a8e85SJeff Kirsher 	struct cmd_desc xp_cmd;
1969ca7a8e85SJeff Kirsher 	int i;
1970ca7a8e85SJeff Kirsher 
1971ca7a8e85SJeff Kirsher 	/* Disable interrupts early, since we can't schedule a poll
1972ca7a8e85SJeff Kirsher 	 * when called with !netif_running(). This will be posted
1973ca7a8e85SJeff Kirsher 	 * when we force the posting of the command.
1974ca7a8e85SJeff Kirsher 	 */
1975ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_INTR_NONE, ioaddr + TYPHOON_REG_INTR_ENABLE);
1976ca7a8e85SJeff Kirsher 
1977ca7a8e85SJeff Kirsher 	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_RX_DISABLE);
1978ca7a8e85SJeff Kirsher 	typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
1979ca7a8e85SJeff Kirsher 
1980ca7a8e85SJeff Kirsher 	/* Wait 1/2 sec for any outstanding transmits to occur
1981ca7a8e85SJeff Kirsher 	 * We'll cleanup after the reset if this times out.
1982ca7a8e85SJeff Kirsher 	 */
1983ca7a8e85SJeff Kirsher 	for(i = 0; i < TYPHOON_WAIT_TIMEOUT; i++) {
1984ca7a8e85SJeff Kirsher 		if(indexes->txLoCleared == cpu_to_le32(txLo->lastWrite))
1985ca7a8e85SJeff Kirsher 			break;
1986ca7a8e85SJeff Kirsher 		udelay(TYPHOON_UDELAY);
1987ca7a8e85SJeff Kirsher 	}
1988ca7a8e85SJeff Kirsher 
1989ca7a8e85SJeff Kirsher 	if(i == TYPHOON_WAIT_TIMEOUT)
1990ca7a8e85SJeff Kirsher 		netdev_err(tp->dev, "halt timed out waiting for Tx to complete\n");
1991ca7a8e85SJeff Kirsher 
1992ca7a8e85SJeff Kirsher 	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_TX_DISABLE);
1993ca7a8e85SJeff Kirsher 	typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
1994ca7a8e85SJeff Kirsher 
1995ca7a8e85SJeff Kirsher 	/* save the statistics so when we bring the interface up again,
1996ca7a8e85SJeff Kirsher 	 * the values reported to userspace are correct.
1997ca7a8e85SJeff Kirsher 	 */
1998ca7a8e85SJeff Kirsher 	tp->card_state = Sleeping;
1999ca7a8e85SJeff Kirsher 	smp_wmb();
2000ca7a8e85SJeff Kirsher 	typhoon_do_get_stats(tp);
2001ca7a8e85SJeff Kirsher 	memcpy(&tp->stats_saved, &tp->stats, sizeof(struct net_device_stats));
2002ca7a8e85SJeff Kirsher 
2003ca7a8e85SJeff Kirsher 	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_HALT);
2004ca7a8e85SJeff Kirsher 	typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
2005ca7a8e85SJeff Kirsher 
2006ca7a8e85SJeff Kirsher 	if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_HALTED) < 0)
2007ca7a8e85SJeff Kirsher 		netdev_err(tp->dev, "timed out waiting for 3XP to halt\n");
2008ca7a8e85SJeff Kirsher 
2009ca7a8e85SJeff Kirsher 	if(typhoon_reset(ioaddr, wait_type) < 0) {
2010ca7a8e85SJeff Kirsher 		netdev_err(tp->dev, "unable to reset 3XP\n");
2011ca7a8e85SJeff Kirsher 		return -ETIMEDOUT;
2012ca7a8e85SJeff Kirsher 	}
2013ca7a8e85SJeff Kirsher 
2014ca7a8e85SJeff Kirsher 	/* cleanup any outstanding Tx packets */
2015ca7a8e85SJeff Kirsher 	if(indexes->txLoCleared != cpu_to_le32(txLo->lastWrite)) {
2016ca7a8e85SJeff Kirsher 		indexes->txLoCleared = cpu_to_le32(txLo->lastWrite);
2017ca7a8e85SJeff Kirsher 		typhoon_clean_tx(tp, &tp->txLoRing, &indexes->txLoCleared);
2018ca7a8e85SJeff Kirsher 	}
2019ca7a8e85SJeff Kirsher 
2020ca7a8e85SJeff Kirsher 	return 0;
2021ca7a8e85SJeff Kirsher }
2022ca7a8e85SJeff Kirsher 
2023ca7a8e85SJeff Kirsher static void
2024ca7a8e85SJeff Kirsher typhoon_tx_timeout(struct net_device *dev)
2025ca7a8e85SJeff Kirsher {
2026ca7a8e85SJeff Kirsher 	struct typhoon *tp = netdev_priv(dev);
2027ca7a8e85SJeff Kirsher 
2028ca7a8e85SJeff Kirsher 	if(typhoon_reset(tp->ioaddr, WaitNoSleep) < 0) {
2029ca7a8e85SJeff Kirsher 		netdev_warn(dev, "could not reset in tx timeout\n");
2030ca7a8e85SJeff Kirsher 		goto truly_dead;
2031ca7a8e85SJeff Kirsher 	}
2032ca7a8e85SJeff Kirsher 
2033ca7a8e85SJeff Kirsher 	/* If we ever start using the Hi ring, it will need cleaning too */
2034ca7a8e85SJeff Kirsher 	typhoon_clean_tx(tp, &tp->txLoRing, &tp->indexes->txLoCleared);
2035ca7a8e85SJeff Kirsher 	typhoon_free_rx_rings(tp);
2036ca7a8e85SJeff Kirsher 
2037ca7a8e85SJeff Kirsher 	if(typhoon_start_runtime(tp) < 0) {
2038ca7a8e85SJeff Kirsher 		netdev_err(dev, "could not start runtime in tx timeout\n");
2039ca7a8e85SJeff Kirsher 		goto truly_dead;
2040ca7a8e85SJeff Kirsher         }
2041ca7a8e85SJeff Kirsher 
2042ca7a8e85SJeff Kirsher 	netif_wake_queue(dev);
2043ca7a8e85SJeff Kirsher 	return;
2044ca7a8e85SJeff Kirsher 
2045ca7a8e85SJeff Kirsher truly_dead:
2046ca7a8e85SJeff Kirsher 	/* Reset the hardware, and turn off carrier to avoid more timeouts */
2047ca7a8e85SJeff Kirsher 	typhoon_reset(tp->ioaddr, NoWait);
2048ca7a8e85SJeff Kirsher 	netif_carrier_off(dev);
2049ca7a8e85SJeff Kirsher }
2050ca7a8e85SJeff Kirsher 
2051ca7a8e85SJeff Kirsher static int
2052ca7a8e85SJeff Kirsher typhoon_open(struct net_device *dev)
2053ca7a8e85SJeff Kirsher {
2054ca7a8e85SJeff Kirsher 	struct typhoon *tp = netdev_priv(dev);
2055ca7a8e85SJeff Kirsher 	int err;
2056ca7a8e85SJeff Kirsher 
2057ca7a8e85SJeff Kirsher 	err = typhoon_request_firmware(tp);
2058ca7a8e85SJeff Kirsher 	if (err)
2059ca7a8e85SJeff Kirsher 		goto out;
2060ca7a8e85SJeff Kirsher 
2061ca7a8e85SJeff Kirsher 	err = typhoon_wakeup(tp, WaitSleep);
2062ca7a8e85SJeff Kirsher 	if(err < 0) {
2063ca7a8e85SJeff Kirsher 		netdev_err(dev, "unable to wakeup device\n");
2064ca7a8e85SJeff Kirsher 		goto out_sleep;
2065ca7a8e85SJeff Kirsher 	}
2066ca7a8e85SJeff Kirsher 
2067ca7a8e85SJeff Kirsher 	err = request_irq(dev->irq, typhoon_interrupt, IRQF_SHARED,
2068ca7a8e85SJeff Kirsher 				dev->name, dev);
2069ca7a8e85SJeff Kirsher 	if(err < 0)
2070ca7a8e85SJeff Kirsher 		goto out_sleep;
2071ca7a8e85SJeff Kirsher 
2072ca7a8e85SJeff Kirsher 	napi_enable(&tp->napi);
2073ca7a8e85SJeff Kirsher 
2074ca7a8e85SJeff Kirsher 	err = typhoon_start_runtime(tp);
2075ca7a8e85SJeff Kirsher 	if(err < 0) {
2076ca7a8e85SJeff Kirsher 		napi_disable(&tp->napi);
2077ca7a8e85SJeff Kirsher 		goto out_irq;
2078ca7a8e85SJeff Kirsher 	}
2079ca7a8e85SJeff Kirsher 
2080ca7a8e85SJeff Kirsher 	netif_start_queue(dev);
2081ca7a8e85SJeff Kirsher 	return 0;
2082ca7a8e85SJeff Kirsher 
2083ca7a8e85SJeff Kirsher out_irq:
2084ca7a8e85SJeff Kirsher 	free_irq(dev->irq, dev);
2085ca7a8e85SJeff Kirsher 
2086ca7a8e85SJeff Kirsher out_sleep:
2087ca7a8e85SJeff Kirsher 	if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) {
2088ca7a8e85SJeff Kirsher 		netdev_err(dev, "unable to reboot into sleep img\n");
2089ca7a8e85SJeff Kirsher 		typhoon_reset(tp->ioaddr, NoWait);
2090ca7a8e85SJeff Kirsher 		goto out;
2091ca7a8e85SJeff Kirsher 	}
2092ca7a8e85SJeff Kirsher 
2093ca7a8e85SJeff Kirsher 	if(typhoon_sleep(tp, PCI_D3hot, 0) < 0)
2094ca7a8e85SJeff Kirsher 		netdev_err(dev, "unable to go back to sleep\n");
2095ca7a8e85SJeff Kirsher 
2096ca7a8e85SJeff Kirsher out:
2097ca7a8e85SJeff Kirsher 	return err;
2098ca7a8e85SJeff Kirsher }
2099ca7a8e85SJeff Kirsher 
2100ca7a8e85SJeff Kirsher static int
2101ca7a8e85SJeff Kirsher typhoon_close(struct net_device *dev)
2102ca7a8e85SJeff Kirsher {
2103ca7a8e85SJeff Kirsher 	struct typhoon *tp = netdev_priv(dev);
2104ca7a8e85SJeff Kirsher 
2105ca7a8e85SJeff Kirsher 	netif_stop_queue(dev);
2106ca7a8e85SJeff Kirsher 	napi_disable(&tp->napi);
2107ca7a8e85SJeff Kirsher 
2108ca7a8e85SJeff Kirsher 	if(typhoon_stop_runtime(tp, WaitSleep) < 0)
2109ca7a8e85SJeff Kirsher 		netdev_err(dev, "unable to stop runtime\n");
2110ca7a8e85SJeff Kirsher 
2111ca7a8e85SJeff Kirsher 	/* Make sure there is no irq handler running on a different CPU. */
2112ca7a8e85SJeff Kirsher 	free_irq(dev->irq, dev);
2113ca7a8e85SJeff Kirsher 
2114ca7a8e85SJeff Kirsher 	typhoon_free_rx_rings(tp);
2115ca7a8e85SJeff Kirsher 	typhoon_init_rings(tp);
2116ca7a8e85SJeff Kirsher 
2117ca7a8e85SJeff Kirsher 	if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0)
2118ca7a8e85SJeff Kirsher 		netdev_err(dev, "unable to boot sleep image\n");
2119ca7a8e85SJeff Kirsher 
2120ca7a8e85SJeff Kirsher 	if(typhoon_sleep(tp, PCI_D3hot, 0) < 0)
2121ca7a8e85SJeff Kirsher 		netdev_err(dev, "unable to put card to sleep\n");
2122ca7a8e85SJeff Kirsher 
2123ca7a8e85SJeff Kirsher 	return 0;
2124ca7a8e85SJeff Kirsher }
2125ca7a8e85SJeff Kirsher 
2126ca7a8e85SJeff Kirsher #ifdef CONFIG_PM
2127ca7a8e85SJeff Kirsher static int
2128ca7a8e85SJeff Kirsher typhoon_resume(struct pci_dev *pdev)
2129ca7a8e85SJeff Kirsher {
2130ca7a8e85SJeff Kirsher 	struct net_device *dev = pci_get_drvdata(pdev);
2131ca7a8e85SJeff Kirsher 	struct typhoon *tp = netdev_priv(dev);
2132ca7a8e85SJeff Kirsher 
2133ca7a8e85SJeff Kirsher 	/* If we're down, resume when we are upped.
2134ca7a8e85SJeff Kirsher 	 */
2135ca7a8e85SJeff Kirsher 	if(!netif_running(dev))
2136ca7a8e85SJeff Kirsher 		return 0;
2137ca7a8e85SJeff Kirsher 
2138ca7a8e85SJeff Kirsher 	if(typhoon_wakeup(tp, WaitNoSleep) < 0) {
2139ca7a8e85SJeff Kirsher 		netdev_err(dev, "critical: could not wake up in resume\n");
2140ca7a8e85SJeff Kirsher 		goto reset;
2141ca7a8e85SJeff Kirsher 	}
2142ca7a8e85SJeff Kirsher 
2143ca7a8e85SJeff Kirsher 	if(typhoon_start_runtime(tp) < 0) {
2144ca7a8e85SJeff Kirsher 		netdev_err(dev, "critical: could not start runtime in resume\n");
2145ca7a8e85SJeff Kirsher 		goto reset;
2146ca7a8e85SJeff Kirsher 	}
2147ca7a8e85SJeff Kirsher 
2148ca7a8e85SJeff Kirsher 	netif_device_attach(dev);
2149ca7a8e85SJeff Kirsher 	return 0;
2150ca7a8e85SJeff Kirsher 
2151ca7a8e85SJeff Kirsher reset:
2152ca7a8e85SJeff Kirsher 	typhoon_reset(tp->ioaddr, NoWait);
2153ca7a8e85SJeff Kirsher 	return -EBUSY;
2154ca7a8e85SJeff Kirsher }
2155ca7a8e85SJeff Kirsher 
2156ca7a8e85SJeff Kirsher static int
2157ca7a8e85SJeff Kirsher typhoon_suspend(struct pci_dev *pdev, pm_message_t state)
2158ca7a8e85SJeff Kirsher {
2159ca7a8e85SJeff Kirsher 	struct net_device *dev = pci_get_drvdata(pdev);
2160ca7a8e85SJeff Kirsher 	struct typhoon *tp = netdev_priv(dev);
2161ca7a8e85SJeff Kirsher 	struct cmd_desc xp_cmd;
2162ca7a8e85SJeff Kirsher 
2163ca7a8e85SJeff Kirsher 	/* If we're down, we're already suspended.
2164ca7a8e85SJeff Kirsher 	 */
2165ca7a8e85SJeff Kirsher 	if(!netif_running(dev))
2166ca7a8e85SJeff Kirsher 		return 0;
2167ca7a8e85SJeff Kirsher 
2168ca7a8e85SJeff Kirsher 	/* TYPHOON_OFFLOAD_VLAN is always on now, so this doesn't work */
2169ca7a8e85SJeff Kirsher 	if(tp->wol_events & TYPHOON_WAKE_MAGIC_PKT)
2170ca7a8e85SJeff Kirsher 		netdev_warn(dev, "cannot do WAKE_MAGIC with VLAN offloading\n");
2171ca7a8e85SJeff Kirsher 
2172ca7a8e85SJeff Kirsher 	netif_device_detach(dev);
2173ca7a8e85SJeff Kirsher 
2174ca7a8e85SJeff Kirsher 	if(typhoon_stop_runtime(tp, WaitNoSleep) < 0) {
2175ca7a8e85SJeff Kirsher 		netdev_err(dev, "unable to stop runtime\n");
2176ca7a8e85SJeff Kirsher 		goto need_resume;
2177ca7a8e85SJeff Kirsher 	}
2178ca7a8e85SJeff Kirsher 
2179ca7a8e85SJeff Kirsher 	typhoon_free_rx_rings(tp);
2180ca7a8e85SJeff Kirsher 	typhoon_init_rings(tp);
2181ca7a8e85SJeff Kirsher 
2182ca7a8e85SJeff Kirsher 	if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) {
2183ca7a8e85SJeff Kirsher 		netdev_err(dev, "unable to boot sleep image\n");
2184ca7a8e85SJeff Kirsher 		goto need_resume;
2185ca7a8e85SJeff Kirsher 	}
2186ca7a8e85SJeff Kirsher 
2187ca7a8e85SJeff Kirsher 	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_MAC_ADDRESS);
2188ca7a8e85SJeff Kirsher 	xp_cmd.parm1 = cpu_to_le16(ntohs(*(__be16 *)&dev->dev_addr[0]));
2189ca7a8e85SJeff Kirsher 	xp_cmd.parm2 = cpu_to_le32(ntohl(*(__be32 *)&dev->dev_addr[2]));
2190ca7a8e85SJeff Kirsher 	if(typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL) < 0) {
2191ca7a8e85SJeff Kirsher 		netdev_err(dev, "unable to set mac address in suspend\n");
2192ca7a8e85SJeff Kirsher 		goto need_resume;
2193ca7a8e85SJeff Kirsher 	}
2194ca7a8e85SJeff Kirsher 
2195ca7a8e85SJeff Kirsher 	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_RX_FILTER);
2196ca7a8e85SJeff Kirsher 	xp_cmd.parm1 = TYPHOON_RX_FILTER_DIRECTED | TYPHOON_RX_FILTER_BROADCAST;
2197ca7a8e85SJeff Kirsher 	if(typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL) < 0) {
2198ca7a8e85SJeff Kirsher 		netdev_err(dev, "unable to set rx filter in suspend\n");
2199ca7a8e85SJeff Kirsher 		goto need_resume;
2200ca7a8e85SJeff Kirsher 	}
2201ca7a8e85SJeff Kirsher 
2202ca7a8e85SJeff Kirsher 	if(typhoon_sleep(tp, pci_choose_state(pdev, state), tp->wol_events) < 0) {
2203ca7a8e85SJeff Kirsher 		netdev_err(dev, "unable to put card to sleep\n");
2204ca7a8e85SJeff Kirsher 		goto need_resume;
2205ca7a8e85SJeff Kirsher 	}
2206ca7a8e85SJeff Kirsher 
2207ca7a8e85SJeff Kirsher 	return 0;
2208ca7a8e85SJeff Kirsher 
2209ca7a8e85SJeff Kirsher need_resume:
2210ca7a8e85SJeff Kirsher 	typhoon_resume(pdev);
2211ca7a8e85SJeff Kirsher 	return -EBUSY;
2212ca7a8e85SJeff Kirsher }
2213ca7a8e85SJeff Kirsher #endif
2214ca7a8e85SJeff Kirsher 
2215ca7a8e85SJeff Kirsher static int __devinit
2216ca7a8e85SJeff Kirsher typhoon_test_mmio(struct pci_dev *pdev)
2217ca7a8e85SJeff Kirsher {
2218ca7a8e85SJeff Kirsher 	void __iomem *ioaddr = pci_iomap(pdev, 1, 128);
2219ca7a8e85SJeff Kirsher 	int mode = 0;
2220ca7a8e85SJeff Kirsher 	u32 val;
2221ca7a8e85SJeff Kirsher 
2222ca7a8e85SJeff Kirsher 	if(!ioaddr)
2223ca7a8e85SJeff Kirsher 		goto out;
2224ca7a8e85SJeff Kirsher 
2225ca7a8e85SJeff Kirsher 	if(ioread32(ioaddr + TYPHOON_REG_STATUS) !=
2226ca7a8e85SJeff Kirsher 				TYPHOON_STATUS_WAITING_FOR_HOST)
2227ca7a8e85SJeff Kirsher 		goto out_unmap;
2228ca7a8e85SJeff Kirsher 
2229ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK);
2230ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_STATUS);
2231ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_ENABLE);
2232ca7a8e85SJeff Kirsher 
2233ca7a8e85SJeff Kirsher 	/* Ok, see if we can change our interrupt status register by
2234ca7a8e85SJeff Kirsher 	 * sending ourselves an interrupt. If so, then MMIO works.
2235ca7a8e85SJeff Kirsher 	 * The 50usec delay is arbitrary -- it could probably be smaller.
2236ca7a8e85SJeff Kirsher 	 */
2237ca7a8e85SJeff Kirsher 	val = ioread32(ioaddr + TYPHOON_REG_INTR_STATUS);
2238ca7a8e85SJeff Kirsher 	if((val & TYPHOON_INTR_SELF) == 0) {
2239ca7a8e85SJeff Kirsher 		iowrite32(1, ioaddr + TYPHOON_REG_SELF_INTERRUPT);
2240ca7a8e85SJeff Kirsher 		ioread32(ioaddr + TYPHOON_REG_INTR_STATUS);
2241ca7a8e85SJeff Kirsher 		udelay(50);
2242ca7a8e85SJeff Kirsher 		val = ioread32(ioaddr + TYPHOON_REG_INTR_STATUS);
2243ca7a8e85SJeff Kirsher 		if(val & TYPHOON_INTR_SELF)
2244ca7a8e85SJeff Kirsher 			mode = 1;
2245ca7a8e85SJeff Kirsher 	}
2246ca7a8e85SJeff Kirsher 
2247ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK);
2248ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_STATUS);
2249ca7a8e85SJeff Kirsher 	iowrite32(TYPHOON_INTR_NONE, ioaddr + TYPHOON_REG_INTR_ENABLE);
2250ca7a8e85SJeff Kirsher 	ioread32(ioaddr + TYPHOON_REG_INTR_STATUS);
2251ca7a8e85SJeff Kirsher 
2252ca7a8e85SJeff Kirsher out_unmap:
2253ca7a8e85SJeff Kirsher 	pci_iounmap(pdev, ioaddr);
2254ca7a8e85SJeff Kirsher 
2255ca7a8e85SJeff Kirsher out:
2256ca7a8e85SJeff Kirsher 	if(!mode)
2257ca7a8e85SJeff Kirsher 		pr_info("%s: falling back to port IO\n", pci_name(pdev));
2258ca7a8e85SJeff Kirsher 	return mode;
2259ca7a8e85SJeff Kirsher }
2260ca7a8e85SJeff Kirsher 
2261ca7a8e85SJeff Kirsher static const struct net_device_ops typhoon_netdev_ops = {
2262ca7a8e85SJeff Kirsher 	.ndo_open		= typhoon_open,
2263ca7a8e85SJeff Kirsher 	.ndo_stop		= typhoon_close,
2264ca7a8e85SJeff Kirsher 	.ndo_start_xmit		= typhoon_start_tx,
2265afc4b13dSJiri Pirko 	.ndo_set_rx_mode	= typhoon_set_rx_mode,
2266ca7a8e85SJeff Kirsher 	.ndo_tx_timeout		= typhoon_tx_timeout,
2267ca7a8e85SJeff Kirsher 	.ndo_get_stats		= typhoon_get_stats,
2268ca7a8e85SJeff Kirsher 	.ndo_validate_addr	= eth_validate_addr,
2269ca7a8e85SJeff Kirsher 	.ndo_set_mac_address	= typhoon_set_mac_address,
2270ca7a8e85SJeff Kirsher 	.ndo_change_mtu		= eth_change_mtu,
2271ca7a8e85SJeff Kirsher };
2272ca7a8e85SJeff Kirsher 
2273ca7a8e85SJeff Kirsher static int __devinit
2274ca7a8e85SJeff Kirsher typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2275ca7a8e85SJeff Kirsher {
2276ca7a8e85SJeff Kirsher 	struct net_device *dev;
2277ca7a8e85SJeff Kirsher 	struct typhoon *tp;
2278ca7a8e85SJeff Kirsher 	int card_id = (int) ent->driver_data;
2279ca7a8e85SJeff Kirsher 	void __iomem *ioaddr;
2280ca7a8e85SJeff Kirsher 	void *shared;
2281ca7a8e85SJeff Kirsher 	dma_addr_t shared_dma;
2282ca7a8e85SJeff Kirsher 	struct cmd_desc xp_cmd;
2283ca7a8e85SJeff Kirsher 	struct resp_desc xp_resp[3];
2284ca7a8e85SJeff Kirsher 	int err = 0;
2285ca7a8e85SJeff Kirsher 	const char *err_msg;
2286ca7a8e85SJeff Kirsher 
2287ca7a8e85SJeff Kirsher 	dev = alloc_etherdev(sizeof(*tp));
2288ca7a8e85SJeff Kirsher 	if(dev == NULL) {
2289ca7a8e85SJeff Kirsher 		err_msg = "unable to alloc new net device";
2290ca7a8e85SJeff Kirsher 		err = -ENOMEM;
2291ca7a8e85SJeff Kirsher 		goto error_out;
2292ca7a8e85SJeff Kirsher 	}
2293ca7a8e85SJeff Kirsher 	SET_NETDEV_DEV(dev, &pdev->dev);
2294ca7a8e85SJeff Kirsher 
2295ca7a8e85SJeff Kirsher 	err = pci_enable_device(pdev);
2296ca7a8e85SJeff Kirsher 	if(err < 0) {
2297ca7a8e85SJeff Kirsher 		err_msg = "unable to enable device";
2298ca7a8e85SJeff Kirsher 		goto error_out_dev;
2299ca7a8e85SJeff Kirsher 	}
2300ca7a8e85SJeff Kirsher 
2301ca7a8e85SJeff Kirsher 	err = pci_set_mwi(pdev);
2302ca7a8e85SJeff Kirsher 	if(err < 0) {
2303ca7a8e85SJeff Kirsher 		err_msg = "unable to set MWI";
2304ca7a8e85SJeff Kirsher 		goto error_out_disable;
2305ca7a8e85SJeff Kirsher 	}
2306ca7a8e85SJeff Kirsher 
2307ca7a8e85SJeff Kirsher 	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2308ca7a8e85SJeff Kirsher 	if(err < 0) {
2309ca7a8e85SJeff Kirsher 		err_msg = "No usable DMA configuration";
2310ca7a8e85SJeff Kirsher 		goto error_out_mwi;
2311ca7a8e85SJeff Kirsher 	}
2312ca7a8e85SJeff Kirsher 
2313ca7a8e85SJeff Kirsher 	/* sanity checks on IO and MMIO BARs
2314ca7a8e85SJeff Kirsher 	 */
2315ca7a8e85SJeff Kirsher 	if(!(pci_resource_flags(pdev, 0) & IORESOURCE_IO)) {
2316ca7a8e85SJeff Kirsher 		err_msg = "region #1 not a PCI IO resource, aborting";
2317ca7a8e85SJeff Kirsher 		err = -ENODEV;
2318ca7a8e85SJeff Kirsher 		goto error_out_mwi;
2319ca7a8e85SJeff Kirsher 	}
2320ca7a8e85SJeff Kirsher 	if(pci_resource_len(pdev, 0) < 128) {
2321ca7a8e85SJeff Kirsher 		err_msg = "Invalid PCI IO region size, aborting";
2322ca7a8e85SJeff Kirsher 		err = -ENODEV;
2323ca7a8e85SJeff Kirsher 		goto error_out_mwi;
2324ca7a8e85SJeff Kirsher 	}
2325ca7a8e85SJeff Kirsher 	if(!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
2326ca7a8e85SJeff Kirsher 		err_msg = "region #1 not a PCI MMIO resource, aborting";
2327ca7a8e85SJeff Kirsher 		err = -ENODEV;
2328ca7a8e85SJeff Kirsher 		goto error_out_mwi;
2329ca7a8e85SJeff Kirsher 	}
2330ca7a8e85SJeff Kirsher 	if(pci_resource_len(pdev, 1) < 128) {
2331ca7a8e85SJeff Kirsher 		err_msg = "Invalid PCI MMIO region size, aborting";
2332ca7a8e85SJeff Kirsher 		err = -ENODEV;
2333ca7a8e85SJeff Kirsher 		goto error_out_mwi;
2334ca7a8e85SJeff Kirsher 	}
2335ca7a8e85SJeff Kirsher 
2336ca7a8e85SJeff Kirsher 	err = pci_request_regions(pdev, KBUILD_MODNAME);
2337ca7a8e85SJeff Kirsher 	if(err < 0) {
2338ca7a8e85SJeff Kirsher 		err_msg = "could not request regions";
2339ca7a8e85SJeff Kirsher 		goto error_out_mwi;
2340ca7a8e85SJeff Kirsher 	}
2341ca7a8e85SJeff Kirsher 
2342ca7a8e85SJeff Kirsher 	/* map our registers
2343ca7a8e85SJeff Kirsher 	 */
2344ca7a8e85SJeff Kirsher 	if(use_mmio != 0 && use_mmio != 1)
2345ca7a8e85SJeff Kirsher 		use_mmio = typhoon_test_mmio(pdev);
2346ca7a8e85SJeff Kirsher 
2347ca7a8e85SJeff Kirsher 	ioaddr = pci_iomap(pdev, use_mmio, 128);
2348ca7a8e85SJeff Kirsher 	if (!ioaddr) {
2349ca7a8e85SJeff Kirsher 		err_msg = "cannot remap registers, aborting";
2350ca7a8e85SJeff Kirsher 		err = -EIO;
2351ca7a8e85SJeff Kirsher 		goto error_out_regions;
2352ca7a8e85SJeff Kirsher 	}
2353ca7a8e85SJeff Kirsher 
2354ca7a8e85SJeff Kirsher 	/* allocate pci dma space for rx and tx descriptor rings
2355ca7a8e85SJeff Kirsher 	 */
2356ca7a8e85SJeff Kirsher 	shared = pci_alloc_consistent(pdev, sizeof(struct typhoon_shared),
2357ca7a8e85SJeff Kirsher 				      &shared_dma);
2358ca7a8e85SJeff Kirsher 	if(!shared) {
2359ca7a8e85SJeff Kirsher 		err_msg = "could not allocate DMA memory";
2360ca7a8e85SJeff Kirsher 		err = -ENOMEM;
2361ca7a8e85SJeff Kirsher 		goto error_out_remap;
2362ca7a8e85SJeff Kirsher 	}
2363ca7a8e85SJeff Kirsher 
2364ca7a8e85SJeff Kirsher 	dev->irq = pdev->irq;
2365ca7a8e85SJeff Kirsher 	tp = netdev_priv(dev);
2366ca7a8e85SJeff Kirsher 	tp->shared = shared;
2367ca7a8e85SJeff Kirsher 	tp->shared_dma = shared_dma;
2368ca7a8e85SJeff Kirsher 	tp->pdev = pdev;
2369ca7a8e85SJeff Kirsher 	tp->tx_pdev = pdev;
2370ca7a8e85SJeff Kirsher 	tp->ioaddr = ioaddr;
2371ca7a8e85SJeff Kirsher 	tp->tx_ioaddr = ioaddr;
2372ca7a8e85SJeff Kirsher 	tp->dev = dev;
2373ca7a8e85SJeff Kirsher 
2374ca7a8e85SJeff Kirsher 	/* Init sequence:
2375ca7a8e85SJeff Kirsher 	 * 1) Reset the adapter to clear any bad juju
2376ca7a8e85SJeff Kirsher 	 * 2) Reload the sleep image
2377ca7a8e85SJeff Kirsher 	 * 3) Boot the sleep image
2378ca7a8e85SJeff Kirsher 	 * 4) Get the hardware address.
2379ca7a8e85SJeff Kirsher 	 * 5) Put the card to sleep.
2380ca7a8e85SJeff Kirsher 	 */
2381ca7a8e85SJeff Kirsher 	if (typhoon_reset(ioaddr, WaitSleep) < 0) {
2382ca7a8e85SJeff Kirsher 		err_msg = "could not reset 3XP";
2383ca7a8e85SJeff Kirsher 		err = -EIO;
2384ca7a8e85SJeff Kirsher 		goto error_out_dma;
2385ca7a8e85SJeff Kirsher 	}
2386ca7a8e85SJeff Kirsher 
2387ca7a8e85SJeff Kirsher 	/* Now that we've reset the 3XP and are sure it's not going to
2388ca7a8e85SJeff Kirsher 	 * write all over memory, enable bus mastering, and save our
2389ca7a8e85SJeff Kirsher 	 * state for resuming after a suspend.
2390ca7a8e85SJeff Kirsher 	 */
2391ca7a8e85SJeff Kirsher 	pci_set_master(pdev);
2392ca7a8e85SJeff Kirsher 	pci_save_state(pdev);
2393ca7a8e85SJeff Kirsher 
2394ca7a8e85SJeff Kirsher 	typhoon_init_interface(tp);
2395ca7a8e85SJeff Kirsher 	typhoon_init_rings(tp);
2396ca7a8e85SJeff Kirsher 
2397ca7a8e85SJeff Kirsher 	if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) {
2398ca7a8e85SJeff Kirsher 		err_msg = "cannot boot 3XP sleep image";
2399ca7a8e85SJeff Kirsher 		err = -EIO;
2400ca7a8e85SJeff Kirsher 		goto error_out_reset;
2401ca7a8e85SJeff Kirsher 	}
2402ca7a8e85SJeff Kirsher 
2403ca7a8e85SJeff Kirsher 	INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_MAC_ADDRESS);
2404ca7a8e85SJeff Kirsher 	if(typhoon_issue_command(tp, 1, &xp_cmd, 1, xp_resp) < 0) {
2405ca7a8e85SJeff Kirsher 		err_msg = "cannot read MAC address";
2406ca7a8e85SJeff Kirsher 		err = -EIO;
2407ca7a8e85SJeff Kirsher 		goto error_out_reset;
2408ca7a8e85SJeff Kirsher 	}
2409ca7a8e85SJeff Kirsher 
2410ca7a8e85SJeff Kirsher 	*(__be16 *)&dev->dev_addr[0] = htons(le16_to_cpu(xp_resp[0].parm1));
2411ca7a8e85SJeff Kirsher 	*(__be32 *)&dev->dev_addr[2] = htonl(le32_to_cpu(xp_resp[0].parm2));
2412ca7a8e85SJeff Kirsher 
2413ca7a8e85SJeff Kirsher 	if(!is_valid_ether_addr(dev->dev_addr)) {
2414ca7a8e85SJeff Kirsher 		err_msg = "Could not obtain valid ethernet address, aborting";
2415ca7a8e85SJeff Kirsher 		goto error_out_reset;
2416ca7a8e85SJeff Kirsher 	}
2417ca7a8e85SJeff Kirsher 
2418ca7a8e85SJeff Kirsher 	/* Read the Sleep Image version last, so the response is valid
2419ca7a8e85SJeff Kirsher 	 * later when we print out the version reported.
2420ca7a8e85SJeff Kirsher 	 */
2421ca7a8e85SJeff Kirsher 	INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_VERSIONS);
2422ca7a8e85SJeff Kirsher 	if(typhoon_issue_command(tp, 1, &xp_cmd, 3, xp_resp) < 0) {
2423ca7a8e85SJeff Kirsher 		err_msg = "Could not get Sleep Image version";
2424ca7a8e85SJeff Kirsher 		goto error_out_reset;
2425ca7a8e85SJeff Kirsher 	}
2426ca7a8e85SJeff Kirsher 
2427ca7a8e85SJeff Kirsher 	tp->capabilities = typhoon_card_info[card_id].capabilities;
2428ca7a8e85SJeff Kirsher 	tp->xcvr_select = TYPHOON_XCVR_AUTONEG;
2429ca7a8e85SJeff Kirsher 
2430ca7a8e85SJeff Kirsher 	/* Typhoon 1.0 Sleep Images return one response descriptor to the
2431ca7a8e85SJeff Kirsher 	 * READ_VERSIONS command. Those versions are OK after waking up
2432ca7a8e85SJeff Kirsher 	 * from sleep without needing a reset. Typhoon 1.1+ Sleep Images
2433ca7a8e85SJeff Kirsher 	 * seem to need a little extra help to get started. Since we don't
2434ca7a8e85SJeff Kirsher 	 * know how to nudge it along, just kick it.
2435ca7a8e85SJeff Kirsher 	 */
2436ca7a8e85SJeff Kirsher 	if(xp_resp[0].numDesc != 0)
2437ca7a8e85SJeff Kirsher 		tp->capabilities |= TYPHOON_WAKEUP_NEEDS_RESET;
2438ca7a8e85SJeff Kirsher 
2439ca7a8e85SJeff Kirsher 	if(typhoon_sleep(tp, PCI_D3hot, 0) < 0) {
2440ca7a8e85SJeff Kirsher 		err_msg = "cannot put adapter to sleep";
2441ca7a8e85SJeff Kirsher 		err = -EIO;
2442ca7a8e85SJeff Kirsher 		goto error_out_reset;
2443ca7a8e85SJeff Kirsher 	}
2444ca7a8e85SJeff Kirsher 
2445ca7a8e85SJeff Kirsher 	/* The chip-specific entries in the device structure. */
2446ca7a8e85SJeff Kirsher 	dev->netdev_ops		= &typhoon_netdev_ops;
2447ca7a8e85SJeff Kirsher 	netif_napi_add(dev, &tp->napi, typhoon_poll, 16);
2448ca7a8e85SJeff Kirsher 	dev->watchdog_timeo	= TX_TIMEOUT;
2449ca7a8e85SJeff Kirsher 
2450ca7a8e85SJeff Kirsher 	SET_ETHTOOL_OPS(dev, &typhoon_ethtool_ops);
2451ca7a8e85SJeff Kirsher 
2452ca7a8e85SJeff Kirsher 	/* We can handle scatter gather, up to 16 entries, and
2453ca7a8e85SJeff Kirsher 	 * we can do IP checksumming (only version 4, doh...)
2454ca7a8e85SJeff Kirsher 	 *
2455ca7a8e85SJeff Kirsher 	 * There's no way to turn off the RX VLAN offloading and stripping
2456ca7a8e85SJeff Kirsher 	 * on the current 3XP firmware -- it does not respect the offload
2457ca7a8e85SJeff Kirsher 	 * settings -- so we only allow the user to toggle the TX processing.
2458ca7a8e85SJeff Kirsher 	 */
2459ca7a8e85SJeff Kirsher 	dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
2460ca7a8e85SJeff Kirsher 		NETIF_F_HW_VLAN_TX;
2461ca7a8e85SJeff Kirsher 	dev->features = dev->hw_features |
2462ca7a8e85SJeff Kirsher 		NETIF_F_HW_VLAN_RX | NETIF_F_RXCSUM;
2463ca7a8e85SJeff Kirsher 
2464ca7a8e85SJeff Kirsher 	if(register_netdev(dev) < 0) {
2465ca7a8e85SJeff Kirsher 		err_msg = "unable to register netdev";
2466ca7a8e85SJeff Kirsher 		goto error_out_reset;
2467ca7a8e85SJeff Kirsher 	}
2468ca7a8e85SJeff Kirsher 
2469ca7a8e85SJeff Kirsher 	pci_set_drvdata(pdev, dev);
2470ca7a8e85SJeff Kirsher 
2471ca7a8e85SJeff Kirsher 	netdev_info(dev, "%s at %s 0x%llx, %pM\n",
2472ca7a8e85SJeff Kirsher 		    typhoon_card_info[card_id].name,
2473ca7a8e85SJeff Kirsher 		    use_mmio ? "MMIO" : "IO",
2474ca7a8e85SJeff Kirsher 		    (unsigned long long)pci_resource_start(pdev, use_mmio),
2475ca7a8e85SJeff Kirsher 		    dev->dev_addr);
2476ca7a8e85SJeff Kirsher 
2477ca7a8e85SJeff Kirsher 	/* xp_resp still contains the response to the READ_VERSIONS command.
2478ca7a8e85SJeff Kirsher 	 * For debugging, let the user know what version he has.
2479ca7a8e85SJeff Kirsher 	 */
2480ca7a8e85SJeff Kirsher 	if(xp_resp[0].numDesc == 0) {
2481ca7a8e85SJeff Kirsher 		/* This is the Typhoon 1.0 type Sleep Image, last 16 bits
2482ca7a8e85SJeff Kirsher 		 * of version is Month/Day of build.
2483ca7a8e85SJeff Kirsher 		 */
2484ca7a8e85SJeff Kirsher 		u16 monthday = le32_to_cpu(xp_resp[0].parm2) & 0xffff;
2485ca7a8e85SJeff Kirsher 		netdev_info(dev, "Typhoon 1.0 Sleep Image built %02u/%02u/2000\n",
2486ca7a8e85SJeff Kirsher 			    monthday >> 8, monthday & 0xff);
2487ca7a8e85SJeff Kirsher 	} else if(xp_resp[0].numDesc == 2) {
2488ca7a8e85SJeff Kirsher 		/* This is the Typhoon 1.1+ type Sleep Image
2489ca7a8e85SJeff Kirsher 		 */
2490ca7a8e85SJeff Kirsher 		u32 sleep_ver = le32_to_cpu(xp_resp[0].parm2);
2491ca7a8e85SJeff Kirsher 		u8 *ver_string = (u8 *) &xp_resp[1];
2492ca7a8e85SJeff Kirsher 		ver_string[25] = 0;
2493ca7a8e85SJeff Kirsher 		netdev_info(dev, "Typhoon 1.1+ Sleep Image version %02x.%03x.%03x %s\n",
2494ca7a8e85SJeff Kirsher 			    sleep_ver >> 24, (sleep_ver >> 12) & 0xfff,
2495ca7a8e85SJeff Kirsher 			    sleep_ver & 0xfff, ver_string);
2496ca7a8e85SJeff Kirsher 	} else {
2497ca7a8e85SJeff Kirsher 		netdev_warn(dev, "Unknown Sleep Image version (%u:%04x)\n",
2498ca7a8e85SJeff Kirsher 			    xp_resp[0].numDesc, le32_to_cpu(xp_resp[0].parm2));
2499ca7a8e85SJeff Kirsher 	}
2500ca7a8e85SJeff Kirsher 
2501ca7a8e85SJeff Kirsher 	return 0;
2502ca7a8e85SJeff Kirsher 
2503ca7a8e85SJeff Kirsher error_out_reset:
2504ca7a8e85SJeff Kirsher 	typhoon_reset(ioaddr, NoWait);
2505ca7a8e85SJeff Kirsher 
2506ca7a8e85SJeff Kirsher error_out_dma:
2507ca7a8e85SJeff Kirsher 	pci_free_consistent(pdev, sizeof(struct typhoon_shared),
2508ca7a8e85SJeff Kirsher 			    shared, shared_dma);
2509ca7a8e85SJeff Kirsher error_out_remap:
2510ca7a8e85SJeff Kirsher 	pci_iounmap(pdev, ioaddr);
2511ca7a8e85SJeff Kirsher error_out_regions:
2512ca7a8e85SJeff Kirsher 	pci_release_regions(pdev);
2513ca7a8e85SJeff Kirsher error_out_mwi:
2514ca7a8e85SJeff Kirsher 	pci_clear_mwi(pdev);
2515ca7a8e85SJeff Kirsher error_out_disable:
2516ca7a8e85SJeff Kirsher 	pci_disable_device(pdev);
2517ca7a8e85SJeff Kirsher error_out_dev:
2518ca7a8e85SJeff Kirsher 	free_netdev(dev);
2519ca7a8e85SJeff Kirsher error_out:
2520ca7a8e85SJeff Kirsher 	pr_err("%s: %s\n", pci_name(pdev), err_msg);
2521ca7a8e85SJeff Kirsher 	return err;
2522ca7a8e85SJeff Kirsher }
2523ca7a8e85SJeff Kirsher 
2524ca7a8e85SJeff Kirsher static void __devexit
2525ca7a8e85SJeff Kirsher typhoon_remove_one(struct pci_dev *pdev)
2526ca7a8e85SJeff Kirsher {
2527ca7a8e85SJeff Kirsher 	struct net_device *dev = pci_get_drvdata(pdev);
2528ca7a8e85SJeff Kirsher 	struct typhoon *tp = netdev_priv(dev);
2529ca7a8e85SJeff Kirsher 
2530ca7a8e85SJeff Kirsher 	unregister_netdev(dev);
2531ca7a8e85SJeff Kirsher 	pci_set_power_state(pdev, PCI_D0);
2532ca7a8e85SJeff Kirsher 	pci_restore_state(pdev);
2533ca7a8e85SJeff Kirsher 	typhoon_reset(tp->ioaddr, NoWait);
2534ca7a8e85SJeff Kirsher 	pci_iounmap(pdev, tp->ioaddr);
2535ca7a8e85SJeff Kirsher 	pci_free_consistent(pdev, sizeof(struct typhoon_shared),
2536ca7a8e85SJeff Kirsher 			    tp->shared, tp->shared_dma);
2537ca7a8e85SJeff Kirsher 	pci_release_regions(pdev);
2538ca7a8e85SJeff Kirsher 	pci_clear_mwi(pdev);
2539ca7a8e85SJeff Kirsher 	pci_disable_device(pdev);
2540ca7a8e85SJeff Kirsher 	pci_set_drvdata(pdev, NULL);
2541ca7a8e85SJeff Kirsher 	free_netdev(dev);
2542ca7a8e85SJeff Kirsher }
2543ca7a8e85SJeff Kirsher 
2544ca7a8e85SJeff Kirsher static struct pci_driver typhoon_driver = {
2545ca7a8e85SJeff Kirsher 	.name		= KBUILD_MODNAME,
2546ca7a8e85SJeff Kirsher 	.id_table	= typhoon_pci_tbl,
2547ca7a8e85SJeff Kirsher 	.probe		= typhoon_init_one,
2548ca7a8e85SJeff Kirsher 	.remove		= __devexit_p(typhoon_remove_one),
2549ca7a8e85SJeff Kirsher #ifdef CONFIG_PM
2550ca7a8e85SJeff Kirsher 	.suspend	= typhoon_suspend,
2551ca7a8e85SJeff Kirsher 	.resume		= typhoon_resume,
2552ca7a8e85SJeff Kirsher #endif
2553ca7a8e85SJeff Kirsher };
2554ca7a8e85SJeff Kirsher 
2555ca7a8e85SJeff Kirsher static int __init
2556ca7a8e85SJeff Kirsher typhoon_init(void)
2557ca7a8e85SJeff Kirsher {
2558ca7a8e85SJeff Kirsher 	return pci_register_driver(&typhoon_driver);
2559ca7a8e85SJeff Kirsher }
2560ca7a8e85SJeff Kirsher 
2561ca7a8e85SJeff Kirsher static void __exit
2562ca7a8e85SJeff Kirsher typhoon_cleanup(void)
2563ca7a8e85SJeff Kirsher {
2564ca7a8e85SJeff Kirsher 	if (typhoon_fw)
2565ca7a8e85SJeff Kirsher 		release_firmware(typhoon_fw);
2566ca7a8e85SJeff Kirsher 	pci_unregister_driver(&typhoon_driver);
2567ca7a8e85SJeff Kirsher }
2568ca7a8e85SJeff Kirsher 
2569ca7a8e85SJeff Kirsher module_init(typhoon_init);
2570ca7a8e85SJeff Kirsher module_exit(typhoon_cleanup);
2571