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