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