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