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 */ 17121cf689bSBill Pemberton static struct typhoon_card_info typhoon_card_info[] = { 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 */ 2069baa3c34SBenoit Taine static const struct pci_device_id 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 { 3674907cb7bSAnatol Pomozov /* if we start using the Hi Tx ring, this needs updating */ 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 772df8a39deSJiri Pirko if (skb_vlan_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 |= 776df8a39deSJiri Pirko cpu_to_le32(htons(skb_vlan_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 void 970ca7a8e85SJeff Kirsher typhoon_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) 971ca7a8e85SJeff Kirsher { 972ca7a8e85SJeff Kirsher struct typhoon *tp = netdev_priv(dev); 973ca7a8e85SJeff Kirsher struct pci_dev *pci_dev = tp->pdev; 974ca7a8e85SJeff Kirsher struct cmd_desc xp_cmd; 975ca7a8e85SJeff Kirsher struct resp_desc xp_resp[3]; 976ca7a8e85SJeff Kirsher 977ca7a8e85SJeff Kirsher smp_rmb(); 978ca7a8e85SJeff Kirsher if(tp->card_state == Sleeping) { 97968aad78cSRick Jones strlcpy(info->fw_version, "Sleep image", 98068aad78cSRick Jones sizeof(info->fw_version)); 981ca7a8e85SJeff Kirsher } else { 982ca7a8e85SJeff Kirsher INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_VERSIONS); 983ca7a8e85SJeff Kirsher if(typhoon_issue_command(tp, 1, &xp_cmd, 3, xp_resp) < 0) { 98468aad78cSRick Jones strlcpy(info->fw_version, "Unknown runtime", 98568aad78cSRick Jones sizeof(info->fw_version)); 986ca7a8e85SJeff Kirsher } else { 987ca7a8e85SJeff Kirsher u32 sleep_ver = le32_to_cpu(xp_resp[0].parm2); 98868aad78cSRick Jones snprintf(info->fw_version, sizeof(info->fw_version), 98968aad78cSRick Jones "%02x.%03x.%03x", sleep_ver >> 24, 99068aad78cSRick Jones (sleep_ver >> 12) & 0xfff, sleep_ver & 0xfff); 991ca7a8e85SJeff Kirsher } 992ca7a8e85SJeff Kirsher } 993ca7a8e85SJeff Kirsher 99468aad78cSRick Jones strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); 99568aad78cSRick Jones strlcpy(info->bus_info, pci_name(pci_dev), sizeof(info->bus_info)); 996ca7a8e85SJeff Kirsher } 997ca7a8e85SJeff Kirsher 998ca7a8e85SJeff Kirsher static int 999f7a5537cSPhilippe Reynes typhoon_get_link_ksettings(struct net_device *dev, 1000f7a5537cSPhilippe Reynes struct ethtool_link_ksettings *cmd) 1001ca7a8e85SJeff Kirsher { 1002ca7a8e85SJeff Kirsher struct typhoon *tp = netdev_priv(dev); 1003b12ab9b1SPhilippe Reynes u32 supported, advertising = 0; 1004ca7a8e85SJeff Kirsher 1005f7a5537cSPhilippe Reynes supported = SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | 1006ca7a8e85SJeff Kirsher SUPPORTED_Autoneg; 1007ca7a8e85SJeff Kirsher 1008ca7a8e85SJeff Kirsher switch (tp->xcvr_select) { 1009ca7a8e85SJeff Kirsher case TYPHOON_XCVR_10HALF: 1010f7a5537cSPhilippe Reynes advertising = ADVERTISED_10baseT_Half; 1011ca7a8e85SJeff Kirsher break; 1012ca7a8e85SJeff Kirsher case TYPHOON_XCVR_10FULL: 1013f7a5537cSPhilippe Reynes advertising = ADVERTISED_10baseT_Full; 1014ca7a8e85SJeff Kirsher break; 1015ca7a8e85SJeff Kirsher case TYPHOON_XCVR_100HALF: 1016f7a5537cSPhilippe Reynes advertising = ADVERTISED_100baseT_Half; 1017ca7a8e85SJeff Kirsher break; 1018ca7a8e85SJeff Kirsher case TYPHOON_XCVR_100FULL: 1019f7a5537cSPhilippe Reynes advertising = ADVERTISED_100baseT_Full; 1020ca7a8e85SJeff Kirsher break; 1021ca7a8e85SJeff Kirsher case TYPHOON_XCVR_AUTONEG: 1022f7a5537cSPhilippe Reynes advertising = ADVERTISED_10baseT_Half | 1023ca7a8e85SJeff Kirsher ADVERTISED_10baseT_Full | 1024ca7a8e85SJeff Kirsher ADVERTISED_100baseT_Half | 1025ca7a8e85SJeff Kirsher ADVERTISED_100baseT_Full | 1026ca7a8e85SJeff Kirsher ADVERTISED_Autoneg; 1027ca7a8e85SJeff Kirsher break; 1028ca7a8e85SJeff Kirsher } 1029ca7a8e85SJeff Kirsher 1030ca7a8e85SJeff Kirsher if(tp->capabilities & TYPHOON_FIBER) { 1031f7a5537cSPhilippe Reynes supported |= SUPPORTED_FIBRE; 1032f7a5537cSPhilippe Reynes advertising |= ADVERTISED_FIBRE; 1033f7a5537cSPhilippe Reynes cmd->base.port = PORT_FIBRE; 1034ca7a8e85SJeff Kirsher } else { 1035f7a5537cSPhilippe Reynes supported |= SUPPORTED_10baseT_Half | 1036ca7a8e85SJeff Kirsher SUPPORTED_10baseT_Full | 1037ca7a8e85SJeff Kirsher SUPPORTED_TP; 1038f7a5537cSPhilippe Reynes advertising |= ADVERTISED_TP; 1039f7a5537cSPhilippe Reynes cmd->base.port = PORT_TP; 1040ca7a8e85SJeff Kirsher } 1041ca7a8e85SJeff Kirsher 1042ca7a8e85SJeff Kirsher /* need to get stats to make these link speed/duplex valid */ 1043ca7a8e85SJeff Kirsher typhoon_do_get_stats(tp); 1044f7a5537cSPhilippe Reynes cmd->base.speed = tp->speed; 1045f7a5537cSPhilippe Reynes cmd->base.duplex = tp->duplex; 1046f7a5537cSPhilippe Reynes cmd->base.phy_address = 0; 1047ca7a8e85SJeff Kirsher if(tp->xcvr_select == TYPHOON_XCVR_AUTONEG) 1048f7a5537cSPhilippe Reynes cmd->base.autoneg = AUTONEG_ENABLE; 1049ca7a8e85SJeff Kirsher else 1050f7a5537cSPhilippe Reynes cmd->base.autoneg = AUTONEG_DISABLE; 1051ca7a8e85SJeff Kirsher 1052b12ab9b1SPhilippe Reynes ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported, 1053b12ab9b1SPhilippe Reynes supported); 1054b12ab9b1SPhilippe Reynes ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising, 1055b12ab9b1SPhilippe Reynes advertising); 1056b12ab9b1SPhilippe Reynes 1057ca7a8e85SJeff Kirsher return 0; 1058ca7a8e85SJeff Kirsher } 1059ca7a8e85SJeff Kirsher 1060ca7a8e85SJeff Kirsher static int 1061f7a5537cSPhilippe Reynes typhoon_set_link_ksettings(struct net_device *dev, 1062f7a5537cSPhilippe Reynes const struct ethtool_link_ksettings *cmd) 1063ca7a8e85SJeff Kirsher { 1064ca7a8e85SJeff Kirsher struct typhoon *tp = netdev_priv(dev); 1065f7a5537cSPhilippe Reynes u32 speed = cmd->base.speed; 1066ca7a8e85SJeff Kirsher struct cmd_desc xp_cmd; 1067ca7a8e85SJeff Kirsher __le16 xcvr; 1068ca7a8e85SJeff Kirsher int err; 1069ca7a8e85SJeff Kirsher 1070ca7a8e85SJeff Kirsher err = -EINVAL; 1071f7a5537cSPhilippe Reynes if (cmd->base.autoneg == AUTONEG_ENABLE) { 1072ca7a8e85SJeff Kirsher xcvr = TYPHOON_XCVR_AUTONEG; 1073ca7a8e85SJeff Kirsher } else { 1074f7a5537cSPhilippe Reynes if (cmd->base.duplex == DUPLEX_HALF) { 1075ca7a8e85SJeff Kirsher if (speed == SPEED_10) 1076ca7a8e85SJeff Kirsher xcvr = TYPHOON_XCVR_10HALF; 1077ca7a8e85SJeff Kirsher else if (speed == SPEED_100) 1078ca7a8e85SJeff Kirsher xcvr = TYPHOON_XCVR_100HALF; 1079ca7a8e85SJeff Kirsher else 1080ca7a8e85SJeff Kirsher goto out; 1081f7a5537cSPhilippe Reynes } else if (cmd->base.duplex == DUPLEX_FULL) { 1082ca7a8e85SJeff Kirsher if (speed == SPEED_10) 1083ca7a8e85SJeff Kirsher xcvr = TYPHOON_XCVR_10FULL; 1084ca7a8e85SJeff Kirsher else if (speed == SPEED_100) 1085ca7a8e85SJeff Kirsher xcvr = TYPHOON_XCVR_100FULL; 1086ca7a8e85SJeff Kirsher else 1087ca7a8e85SJeff Kirsher goto out; 1088ca7a8e85SJeff Kirsher } else 1089ca7a8e85SJeff Kirsher goto out; 1090ca7a8e85SJeff Kirsher } 1091ca7a8e85SJeff Kirsher 1092ca7a8e85SJeff Kirsher INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_XCVR_SELECT); 1093ca7a8e85SJeff Kirsher xp_cmd.parm1 = xcvr; 1094ca7a8e85SJeff Kirsher err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); 1095ca7a8e85SJeff Kirsher if(err < 0) 1096ca7a8e85SJeff Kirsher goto out; 1097ca7a8e85SJeff Kirsher 1098ca7a8e85SJeff Kirsher tp->xcvr_select = xcvr; 1099f7a5537cSPhilippe Reynes if (cmd->base.autoneg == AUTONEG_ENABLE) { 1100ca7a8e85SJeff Kirsher tp->speed = 0xff; /* invalid */ 1101ca7a8e85SJeff Kirsher tp->duplex = 0xff; /* invalid */ 1102ca7a8e85SJeff Kirsher } else { 1103ca7a8e85SJeff Kirsher tp->speed = speed; 1104f7a5537cSPhilippe Reynes tp->duplex = cmd->base.duplex; 1105ca7a8e85SJeff Kirsher } 1106ca7a8e85SJeff Kirsher 1107ca7a8e85SJeff Kirsher out: 1108ca7a8e85SJeff Kirsher return err; 1109ca7a8e85SJeff Kirsher } 1110ca7a8e85SJeff Kirsher 1111ca7a8e85SJeff Kirsher static void 1112ca7a8e85SJeff Kirsher typhoon_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 1113ca7a8e85SJeff Kirsher { 1114ca7a8e85SJeff Kirsher struct typhoon *tp = netdev_priv(dev); 1115ca7a8e85SJeff Kirsher 1116ca7a8e85SJeff Kirsher wol->supported = WAKE_PHY | WAKE_MAGIC; 1117ca7a8e85SJeff Kirsher wol->wolopts = 0; 1118ca7a8e85SJeff Kirsher if(tp->wol_events & TYPHOON_WAKE_LINK_EVENT) 1119ca7a8e85SJeff Kirsher wol->wolopts |= WAKE_PHY; 1120ca7a8e85SJeff Kirsher if(tp->wol_events & TYPHOON_WAKE_MAGIC_PKT) 1121ca7a8e85SJeff Kirsher wol->wolopts |= WAKE_MAGIC; 1122ca7a8e85SJeff Kirsher memset(&wol->sopass, 0, sizeof(wol->sopass)); 1123ca7a8e85SJeff Kirsher } 1124ca7a8e85SJeff Kirsher 1125ca7a8e85SJeff Kirsher static int 1126ca7a8e85SJeff Kirsher typhoon_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 1127ca7a8e85SJeff Kirsher { 1128ca7a8e85SJeff Kirsher struct typhoon *tp = netdev_priv(dev); 1129ca7a8e85SJeff Kirsher 1130ca7a8e85SJeff Kirsher if(wol->wolopts & ~(WAKE_PHY | WAKE_MAGIC)) 1131ca7a8e85SJeff Kirsher return -EINVAL; 1132ca7a8e85SJeff Kirsher 1133ca7a8e85SJeff Kirsher tp->wol_events = 0; 1134ca7a8e85SJeff Kirsher if(wol->wolopts & WAKE_PHY) 1135ca7a8e85SJeff Kirsher tp->wol_events |= TYPHOON_WAKE_LINK_EVENT; 1136ca7a8e85SJeff Kirsher if(wol->wolopts & WAKE_MAGIC) 1137ca7a8e85SJeff Kirsher tp->wol_events |= TYPHOON_WAKE_MAGIC_PKT; 1138ca7a8e85SJeff Kirsher 1139ca7a8e85SJeff Kirsher return 0; 1140ca7a8e85SJeff Kirsher } 1141ca7a8e85SJeff Kirsher 1142ca7a8e85SJeff Kirsher static void 1143ca7a8e85SJeff Kirsher typhoon_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) 1144ca7a8e85SJeff Kirsher { 1145ca7a8e85SJeff Kirsher ering->rx_max_pending = RXENT_ENTRIES; 1146ca7a8e85SJeff Kirsher ering->tx_max_pending = TXLO_ENTRIES - 1; 1147ca7a8e85SJeff Kirsher 1148ca7a8e85SJeff Kirsher ering->rx_pending = RXENT_ENTRIES; 1149ca7a8e85SJeff Kirsher ering->tx_pending = TXLO_ENTRIES - 1; 1150ca7a8e85SJeff Kirsher } 1151ca7a8e85SJeff Kirsher 1152ca7a8e85SJeff Kirsher static const struct ethtool_ops typhoon_ethtool_ops = { 1153ca7a8e85SJeff Kirsher .get_drvinfo = typhoon_get_drvinfo, 1154ca7a8e85SJeff Kirsher .get_wol = typhoon_get_wol, 1155ca7a8e85SJeff Kirsher .set_wol = typhoon_set_wol, 1156ca7a8e85SJeff Kirsher .get_link = ethtool_op_get_link, 1157ca7a8e85SJeff Kirsher .get_ringparam = typhoon_get_ringparam, 1158f7a5537cSPhilippe Reynes .get_link_ksettings = typhoon_get_link_ksettings, 1159f7a5537cSPhilippe Reynes .set_link_ksettings = typhoon_set_link_ksettings, 1160ca7a8e85SJeff Kirsher }; 1161ca7a8e85SJeff Kirsher 1162ca7a8e85SJeff Kirsher static int 1163ca7a8e85SJeff Kirsher typhoon_wait_interrupt(void __iomem *ioaddr) 1164ca7a8e85SJeff Kirsher { 1165ca7a8e85SJeff Kirsher int i, err = 0; 1166ca7a8e85SJeff Kirsher 1167ca7a8e85SJeff Kirsher for(i = 0; i < TYPHOON_WAIT_TIMEOUT; i++) { 1168ca7a8e85SJeff Kirsher if(ioread32(ioaddr + TYPHOON_REG_INTR_STATUS) & 1169ca7a8e85SJeff Kirsher TYPHOON_INTR_BOOTCMD) 1170ca7a8e85SJeff Kirsher goto out; 1171ca7a8e85SJeff Kirsher udelay(TYPHOON_UDELAY); 1172ca7a8e85SJeff Kirsher } 1173ca7a8e85SJeff Kirsher 1174ca7a8e85SJeff Kirsher err = -ETIMEDOUT; 1175ca7a8e85SJeff Kirsher 1176ca7a8e85SJeff Kirsher out: 1177ca7a8e85SJeff Kirsher iowrite32(TYPHOON_INTR_BOOTCMD, ioaddr + TYPHOON_REG_INTR_STATUS); 1178ca7a8e85SJeff Kirsher return err; 1179ca7a8e85SJeff Kirsher } 1180ca7a8e85SJeff Kirsher 1181ca7a8e85SJeff Kirsher #define shared_offset(x) offsetof(struct typhoon_shared, x) 1182ca7a8e85SJeff Kirsher 1183ca7a8e85SJeff Kirsher static void 1184ca7a8e85SJeff Kirsher typhoon_init_interface(struct typhoon *tp) 1185ca7a8e85SJeff Kirsher { 1186ca7a8e85SJeff Kirsher struct typhoon_interface *iface = &tp->shared->iface; 1187ca7a8e85SJeff Kirsher dma_addr_t shared_dma; 1188ca7a8e85SJeff Kirsher 1189ca7a8e85SJeff Kirsher memset(tp->shared, 0, sizeof(struct typhoon_shared)); 1190ca7a8e85SJeff Kirsher 1191ca7a8e85SJeff Kirsher /* The *Hi members of iface are all init'd to zero by the memset(). 1192ca7a8e85SJeff Kirsher */ 1193ca7a8e85SJeff Kirsher shared_dma = tp->shared_dma + shared_offset(indexes); 1194ca7a8e85SJeff Kirsher iface->ringIndex = cpu_to_le32(shared_dma); 1195ca7a8e85SJeff Kirsher 1196ca7a8e85SJeff Kirsher shared_dma = tp->shared_dma + shared_offset(txLo); 1197ca7a8e85SJeff Kirsher iface->txLoAddr = cpu_to_le32(shared_dma); 1198ca7a8e85SJeff Kirsher iface->txLoSize = cpu_to_le32(TXLO_ENTRIES * sizeof(struct tx_desc)); 1199ca7a8e85SJeff Kirsher 1200ca7a8e85SJeff Kirsher shared_dma = tp->shared_dma + shared_offset(txHi); 1201ca7a8e85SJeff Kirsher iface->txHiAddr = cpu_to_le32(shared_dma); 1202ca7a8e85SJeff Kirsher iface->txHiSize = cpu_to_le32(TXHI_ENTRIES * sizeof(struct tx_desc)); 1203ca7a8e85SJeff Kirsher 1204ca7a8e85SJeff Kirsher shared_dma = tp->shared_dma + shared_offset(rxBuff); 1205ca7a8e85SJeff Kirsher iface->rxBuffAddr = cpu_to_le32(shared_dma); 1206ca7a8e85SJeff Kirsher iface->rxBuffSize = cpu_to_le32(RXFREE_ENTRIES * 1207ca7a8e85SJeff Kirsher sizeof(struct rx_free)); 1208ca7a8e85SJeff Kirsher 1209ca7a8e85SJeff Kirsher shared_dma = tp->shared_dma + shared_offset(rxLo); 1210ca7a8e85SJeff Kirsher iface->rxLoAddr = cpu_to_le32(shared_dma); 1211ca7a8e85SJeff Kirsher iface->rxLoSize = cpu_to_le32(RX_ENTRIES * sizeof(struct rx_desc)); 1212ca7a8e85SJeff Kirsher 1213ca7a8e85SJeff Kirsher shared_dma = tp->shared_dma + shared_offset(rxHi); 1214ca7a8e85SJeff Kirsher iface->rxHiAddr = cpu_to_le32(shared_dma); 1215ca7a8e85SJeff Kirsher iface->rxHiSize = cpu_to_le32(RX_ENTRIES * sizeof(struct rx_desc)); 1216ca7a8e85SJeff Kirsher 1217ca7a8e85SJeff Kirsher shared_dma = tp->shared_dma + shared_offset(cmd); 1218ca7a8e85SJeff Kirsher iface->cmdAddr = cpu_to_le32(shared_dma); 1219ca7a8e85SJeff Kirsher iface->cmdSize = cpu_to_le32(COMMAND_RING_SIZE); 1220ca7a8e85SJeff Kirsher 1221ca7a8e85SJeff Kirsher shared_dma = tp->shared_dma + shared_offset(resp); 1222ca7a8e85SJeff Kirsher iface->respAddr = cpu_to_le32(shared_dma); 1223ca7a8e85SJeff Kirsher iface->respSize = cpu_to_le32(RESPONSE_RING_SIZE); 1224ca7a8e85SJeff Kirsher 1225ca7a8e85SJeff Kirsher shared_dma = tp->shared_dma + shared_offset(zeroWord); 1226ca7a8e85SJeff Kirsher iface->zeroAddr = cpu_to_le32(shared_dma); 1227ca7a8e85SJeff Kirsher 1228ca7a8e85SJeff Kirsher tp->indexes = &tp->shared->indexes; 1229ca7a8e85SJeff Kirsher tp->txLoRing.ringBase = (u8 *) tp->shared->txLo; 1230ca7a8e85SJeff Kirsher tp->txHiRing.ringBase = (u8 *) tp->shared->txHi; 1231ca7a8e85SJeff Kirsher tp->rxLoRing.ringBase = (u8 *) tp->shared->rxLo; 1232ca7a8e85SJeff Kirsher tp->rxHiRing.ringBase = (u8 *) tp->shared->rxHi; 1233ca7a8e85SJeff Kirsher tp->rxBuffRing.ringBase = (u8 *) tp->shared->rxBuff; 1234ca7a8e85SJeff Kirsher tp->cmdRing.ringBase = (u8 *) tp->shared->cmd; 1235ca7a8e85SJeff Kirsher tp->respRing.ringBase = (u8 *) tp->shared->resp; 1236ca7a8e85SJeff Kirsher 1237ca7a8e85SJeff Kirsher tp->txLoRing.writeRegister = TYPHOON_REG_TX_LO_READY; 1238ca7a8e85SJeff Kirsher tp->txHiRing.writeRegister = TYPHOON_REG_TX_HI_READY; 1239ca7a8e85SJeff Kirsher 1240ca7a8e85SJeff Kirsher tp->txlo_dma_addr = le32_to_cpu(iface->txLoAddr); 1241ca7a8e85SJeff Kirsher tp->card_state = Sleeping; 1242ca7a8e85SJeff Kirsher 1243ca7a8e85SJeff Kirsher tp->offload = TYPHOON_OFFLOAD_IP_CHKSUM | TYPHOON_OFFLOAD_TCP_CHKSUM; 1244ca7a8e85SJeff Kirsher tp->offload |= TYPHOON_OFFLOAD_UDP_CHKSUM | TSO_OFFLOAD_ON; 1245ca7a8e85SJeff Kirsher tp->offload |= TYPHOON_OFFLOAD_VLAN; 1246ca7a8e85SJeff Kirsher 1247ca7a8e85SJeff Kirsher spin_lock_init(&tp->command_lock); 1248ca7a8e85SJeff Kirsher 1249ca7a8e85SJeff Kirsher /* Force the writes to the shared memory area out before continuing. */ 1250ca7a8e85SJeff Kirsher wmb(); 1251ca7a8e85SJeff Kirsher } 1252ca7a8e85SJeff Kirsher 1253ca7a8e85SJeff Kirsher static void 1254ca7a8e85SJeff Kirsher typhoon_init_rings(struct typhoon *tp) 1255ca7a8e85SJeff Kirsher { 1256ca7a8e85SJeff Kirsher memset(tp->indexes, 0, sizeof(struct typhoon_indexes)); 1257ca7a8e85SJeff Kirsher 1258ca7a8e85SJeff Kirsher tp->txLoRing.lastWrite = 0; 1259ca7a8e85SJeff Kirsher tp->txHiRing.lastWrite = 0; 1260ca7a8e85SJeff Kirsher tp->rxLoRing.lastWrite = 0; 1261ca7a8e85SJeff Kirsher tp->rxHiRing.lastWrite = 0; 1262ca7a8e85SJeff Kirsher tp->rxBuffRing.lastWrite = 0; 1263ca7a8e85SJeff Kirsher tp->cmdRing.lastWrite = 0; 1264ca7a8e85SJeff Kirsher tp->respRing.lastWrite = 0; 1265ca7a8e85SJeff Kirsher 1266ca7a8e85SJeff Kirsher tp->txLoRing.lastRead = 0; 1267ca7a8e85SJeff Kirsher tp->txHiRing.lastRead = 0; 1268ca7a8e85SJeff Kirsher } 1269ca7a8e85SJeff Kirsher 1270ca7a8e85SJeff Kirsher static const struct firmware *typhoon_fw; 1271ca7a8e85SJeff Kirsher 1272ca7a8e85SJeff Kirsher static int 1273ca7a8e85SJeff Kirsher typhoon_request_firmware(struct typhoon *tp) 1274ca7a8e85SJeff Kirsher { 1275ca7a8e85SJeff Kirsher const struct typhoon_file_header *fHdr; 1276ca7a8e85SJeff Kirsher const struct typhoon_section_header *sHdr; 1277ca7a8e85SJeff Kirsher const u8 *image_data; 1278ca7a8e85SJeff Kirsher u32 numSections; 1279ca7a8e85SJeff Kirsher u32 section_len; 1280ca7a8e85SJeff Kirsher u32 remaining; 1281ca7a8e85SJeff Kirsher int err; 1282ca7a8e85SJeff Kirsher 1283ca7a8e85SJeff Kirsher if (typhoon_fw) 1284ca7a8e85SJeff Kirsher return 0; 1285ca7a8e85SJeff Kirsher 1286ca7a8e85SJeff Kirsher err = request_firmware(&typhoon_fw, FIRMWARE_NAME, &tp->pdev->dev); 1287ca7a8e85SJeff Kirsher if (err) { 1288ca7a8e85SJeff Kirsher netdev_err(tp->dev, "Failed to load firmware \"%s\"\n", 1289ca7a8e85SJeff Kirsher FIRMWARE_NAME); 1290ca7a8e85SJeff Kirsher return err; 1291ca7a8e85SJeff Kirsher } 1292ca7a8e85SJeff Kirsher 129300fd5d94SRasmus Villemoes image_data = typhoon_fw->data; 1294ca7a8e85SJeff Kirsher remaining = typhoon_fw->size; 1295ca7a8e85SJeff Kirsher if (remaining < sizeof(struct typhoon_file_header)) 1296ca7a8e85SJeff Kirsher goto invalid_fw; 1297ca7a8e85SJeff Kirsher 1298ca7a8e85SJeff Kirsher fHdr = (struct typhoon_file_header *) image_data; 1299ca7a8e85SJeff Kirsher if (memcmp(fHdr->tag, "TYPHOON", 8)) 1300ca7a8e85SJeff Kirsher goto invalid_fw; 1301ca7a8e85SJeff Kirsher 1302ca7a8e85SJeff Kirsher numSections = le32_to_cpu(fHdr->numSections); 1303ca7a8e85SJeff Kirsher image_data += sizeof(struct typhoon_file_header); 1304ca7a8e85SJeff Kirsher remaining -= sizeof(struct typhoon_file_header); 1305ca7a8e85SJeff Kirsher 1306ca7a8e85SJeff Kirsher while (numSections--) { 1307ca7a8e85SJeff Kirsher if (remaining < sizeof(struct typhoon_section_header)) 1308ca7a8e85SJeff Kirsher goto invalid_fw; 1309ca7a8e85SJeff Kirsher 1310ca7a8e85SJeff Kirsher sHdr = (struct typhoon_section_header *) image_data; 1311ca7a8e85SJeff Kirsher image_data += sizeof(struct typhoon_section_header); 1312ca7a8e85SJeff Kirsher section_len = le32_to_cpu(sHdr->len); 1313ca7a8e85SJeff Kirsher 1314ca7a8e85SJeff Kirsher if (remaining < section_len) 1315ca7a8e85SJeff Kirsher goto invalid_fw; 1316ca7a8e85SJeff Kirsher 1317ca7a8e85SJeff Kirsher image_data += section_len; 1318ca7a8e85SJeff Kirsher remaining -= section_len; 1319ca7a8e85SJeff Kirsher } 1320ca7a8e85SJeff Kirsher 1321ca7a8e85SJeff Kirsher return 0; 1322ca7a8e85SJeff Kirsher 1323ca7a8e85SJeff Kirsher invalid_fw: 1324ca7a8e85SJeff Kirsher netdev_err(tp->dev, "Invalid firmware image\n"); 1325ca7a8e85SJeff Kirsher release_firmware(typhoon_fw); 1326ca7a8e85SJeff Kirsher typhoon_fw = NULL; 1327ca7a8e85SJeff Kirsher return -EINVAL; 1328ca7a8e85SJeff Kirsher } 1329ca7a8e85SJeff Kirsher 1330ca7a8e85SJeff Kirsher static int 1331ca7a8e85SJeff Kirsher typhoon_download_firmware(struct typhoon *tp) 1332ca7a8e85SJeff Kirsher { 1333ca7a8e85SJeff Kirsher void __iomem *ioaddr = tp->ioaddr; 1334ca7a8e85SJeff Kirsher struct pci_dev *pdev = tp->pdev; 1335ca7a8e85SJeff Kirsher const struct typhoon_file_header *fHdr; 1336ca7a8e85SJeff Kirsher const struct typhoon_section_header *sHdr; 1337ca7a8e85SJeff Kirsher const u8 *image_data; 1338ca7a8e85SJeff Kirsher void *dpage; 1339ca7a8e85SJeff Kirsher dma_addr_t dpage_dma; 1340ca7a8e85SJeff Kirsher __sum16 csum; 1341ca7a8e85SJeff Kirsher u32 irqEnabled; 1342ca7a8e85SJeff Kirsher u32 irqMasked; 1343ca7a8e85SJeff Kirsher u32 numSections; 1344ca7a8e85SJeff Kirsher u32 section_len; 1345ca7a8e85SJeff Kirsher u32 len; 1346ca7a8e85SJeff Kirsher u32 load_addr; 1347ca7a8e85SJeff Kirsher u32 hmac; 1348ca7a8e85SJeff Kirsher int i; 1349ca7a8e85SJeff Kirsher int err; 1350ca7a8e85SJeff Kirsher 135100fd5d94SRasmus Villemoes image_data = typhoon_fw->data; 1352ca7a8e85SJeff Kirsher fHdr = (struct typhoon_file_header *) image_data; 1353ca7a8e85SJeff Kirsher 1354ca7a8e85SJeff Kirsher /* Cannot just map the firmware image using pci_map_single() as 1355ca7a8e85SJeff Kirsher * the firmware is vmalloc()'d and may not be physically contiguous, 1356ca7a8e85SJeff Kirsher * so we allocate some consistent memory to copy the sections into. 1357ca7a8e85SJeff Kirsher */ 1358ca7a8e85SJeff Kirsher err = -ENOMEM; 1359ca7a8e85SJeff Kirsher dpage = pci_alloc_consistent(pdev, PAGE_SIZE, &dpage_dma); 1360ca7a8e85SJeff Kirsher if(!dpage) { 1361ca7a8e85SJeff Kirsher netdev_err(tp->dev, "no DMA mem for firmware\n"); 1362ca7a8e85SJeff Kirsher goto err_out; 1363ca7a8e85SJeff Kirsher } 1364ca7a8e85SJeff Kirsher 1365ca7a8e85SJeff Kirsher irqEnabled = ioread32(ioaddr + TYPHOON_REG_INTR_ENABLE); 1366ca7a8e85SJeff Kirsher iowrite32(irqEnabled | TYPHOON_INTR_BOOTCMD, 1367ca7a8e85SJeff Kirsher ioaddr + TYPHOON_REG_INTR_ENABLE); 1368ca7a8e85SJeff Kirsher irqMasked = ioread32(ioaddr + TYPHOON_REG_INTR_MASK); 1369ca7a8e85SJeff Kirsher iowrite32(irqMasked | TYPHOON_INTR_BOOTCMD, 1370ca7a8e85SJeff Kirsher ioaddr + TYPHOON_REG_INTR_MASK); 1371ca7a8e85SJeff Kirsher 1372ca7a8e85SJeff Kirsher err = -ETIMEDOUT; 1373ca7a8e85SJeff Kirsher if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) { 1374ca7a8e85SJeff Kirsher netdev_err(tp->dev, "card ready timeout\n"); 1375ca7a8e85SJeff Kirsher goto err_out_irq; 1376ca7a8e85SJeff Kirsher } 1377ca7a8e85SJeff Kirsher 1378ca7a8e85SJeff Kirsher numSections = le32_to_cpu(fHdr->numSections); 1379ca7a8e85SJeff Kirsher load_addr = le32_to_cpu(fHdr->startAddr); 1380ca7a8e85SJeff Kirsher 1381ca7a8e85SJeff Kirsher iowrite32(TYPHOON_INTR_BOOTCMD, ioaddr + TYPHOON_REG_INTR_STATUS); 1382ca7a8e85SJeff Kirsher iowrite32(load_addr, ioaddr + TYPHOON_REG_DOWNLOAD_BOOT_ADDR); 1383ca7a8e85SJeff Kirsher hmac = le32_to_cpu(fHdr->hmacDigest[0]); 1384ca7a8e85SJeff Kirsher iowrite32(hmac, ioaddr + TYPHOON_REG_DOWNLOAD_HMAC_0); 1385ca7a8e85SJeff Kirsher hmac = le32_to_cpu(fHdr->hmacDigest[1]); 1386ca7a8e85SJeff Kirsher iowrite32(hmac, ioaddr + TYPHOON_REG_DOWNLOAD_HMAC_1); 1387ca7a8e85SJeff Kirsher hmac = le32_to_cpu(fHdr->hmacDigest[2]); 1388ca7a8e85SJeff Kirsher iowrite32(hmac, ioaddr + TYPHOON_REG_DOWNLOAD_HMAC_2); 1389ca7a8e85SJeff Kirsher hmac = le32_to_cpu(fHdr->hmacDigest[3]); 1390ca7a8e85SJeff Kirsher iowrite32(hmac, ioaddr + TYPHOON_REG_DOWNLOAD_HMAC_3); 1391ca7a8e85SJeff Kirsher hmac = le32_to_cpu(fHdr->hmacDigest[4]); 1392ca7a8e85SJeff Kirsher iowrite32(hmac, ioaddr + TYPHOON_REG_DOWNLOAD_HMAC_4); 1393ca7a8e85SJeff Kirsher typhoon_post_pci_writes(ioaddr); 1394ca7a8e85SJeff Kirsher iowrite32(TYPHOON_BOOTCMD_RUNTIME_IMAGE, ioaddr + TYPHOON_REG_COMMAND); 1395ca7a8e85SJeff Kirsher 1396ca7a8e85SJeff Kirsher image_data += sizeof(struct typhoon_file_header); 1397ca7a8e85SJeff Kirsher 1398ca7a8e85SJeff Kirsher /* The ioread32() in typhoon_wait_interrupt() will force the 1399ca7a8e85SJeff Kirsher * last write to the command register to post, so 1400ca7a8e85SJeff Kirsher * we don't need a typhoon_post_pci_writes() after it. 1401ca7a8e85SJeff Kirsher */ 1402ca7a8e85SJeff Kirsher for(i = 0; i < numSections; i++) { 1403ca7a8e85SJeff Kirsher sHdr = (struct typhoon_section_header *) image_data; 1404ca7a8e85SJeff Kirsher image_data += sizeof(struct typhoon_section_header); 1405ca7a8e85SJeff Kirsher load_addr = le32_to_cpu(sHdr->startAddr); 1406ca7a8e85SJeff Kirsher section_len = le32_to_cpu(sHdr->len); 1407ca7a8e85SJeff Kirsher 1408ca7a8e85SJeff Kirsher while(section_len) { 1409ca7a8e85SJeff Kirsher len = min_t(u32, section_len, PAGE_SIZE); 1410ca7a8e85SJeff Kirsher 1411ca7a8e85SJeff Kirsher if(typhoon_wait_interrupt(ioaddr) < 0 || 1412ca7a8e85SJeff Kirsher ioread32(ioaddr + TYPHOON_REG_STATUS) != 1413ca7a8e85SJeff Kirsher TYPHOON_STATUS_WAITING_FOR_SEGMENT) { 1414ca7a8e85SJeff Kirsher netdev_err(tp->dev, "segment ready timeout\n"); 1415ca7a8e85SJeff Kirsher goto err_out_irq; 1416ca7a8e85SJeff Kirsher } 1417ca7a8e85SJeff Kirsher 1418ca7a8e85SJeff Kirsher /* Do an pseudo IPv4 checksum on the data -- first 1419ca7a8e85SJeff Kirsher * need to convert each u16 to cpu order before 1420ca7a8e85SJeff Kirsher * summing. Fortunately, due to the properties of 1421ca7a8e85SJeff Kirsher * the checksum, we can do this once, at the end. 1422ca7a8e85SJeff Kirsher */ 1423ca7a8e85SJeff Kirsher csum = csum_fold(csum_partial_copy_nocheck(image_data, 1424ca7a8e85SJeff Kirsher dpage, len, 1425ca7a8e85SJeff Kirsher 0)); 1426ca7a8e85SJeff Kirsher 1427ca7a8e85SJeff Kirsher iowrite32(len, ioaddr + TYPHOON_REG_BOOT_LENGTH); 1428ca7a8e85SJeff Kirsher iowrite32(le16_to_cpu((__force __le16)csum), 1429ca7a8e85SJeff Kirsher ioaddr + TYPHOON_REG_BOOT_CHECKSUM); 1430ca7a8e85SJeff Kirsher iowrite32(load_addr, 1431ca7a8e85SJeff Kirsher ioaddr + TYPHOON_REG_BOOT_DEST_ADDR); 1432ca7a8e85SJeff Kirsher iowrite32(0, ioaddr + TYPHOON_REG_BOOT_DATA_HI); 1433ca7a8e85SJeff Kirsher iowrite32(dpage_dma, ioaddr + TYPHOON_REG_BOOT_DATA_LO); 1434ca7a8e85SJeff Kirsher typhoon_post_pci_writes(ioaddr); 1435ca7a8e85SJeff Kirsher iowrite32(TYPHOON_BOOTCMD_SEG_AVAILABLE, 1436ca7a8e85SJeff Kirsher ioaddr + TYPHOON_REG_COMMAND); 1437ca7a8e85SJeff Kirsher 1438ca7a8e85SJeff Kirsher image_data += len; 1439ca7a8e85SJeff Kirsher load_addr += len; 1440ca7a8e85SJeff Kirsher section_len -= len; 1441ca7a8e85SJeff Kirsher } 1442ca7a8e85SJeff Kirsher } 1443ca7a8e85SJeff Kirsher 1444ca7a8e85SJeff Kirsher if(typhoon_wait_interrupt(ioaddr) < 0 || 1445ca7a8e85SJeff Kirsher ioread32(ioaddr + TYPHOON_REG_STATUS) != 1446ca7a8e85SJeff Kirsher TYPHOON_STATUS_WAITING_FOR_SEGMENT) { 1447ca7a8e85SJeff Kirsher netdev_err(tp->dev, "final segment ready timeout\n"); 1448ca7a8e85SJeff Kirsher goto err_out_irq; 1449ca7a8e85SJeff Kirsher } 1450ca7a8e85SJeff Kirsher 1451ca7a8e85SJeff Kirsher iowrite32(TYPHOON_BOOTCMD_DNLD_COMPLETE, ioaddr + TYPHOON_REG_COMMAND); 1452ca7a8e85SJeff Kirsher 1453ca7a8e85SJeff Kirsher if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_BOOT) < 0) { 1454ca7a8e85SJeff Kirsher netdev_err(tp->dev, "boot ready timeout, status 0x%0x\n", 1455ca7a8e85SJeff Kirsher ioread32(ioaddr + TYPHOON_REG_STATUS)); 1456ca7a8e85SJeff Kirsher goto err_out_irq; 1457ca7a8e85SJeff Kirsher } 1458ca7a8e85SJeff Kirsher 1459ca7a8e85SJeff Kirsher err = 0; 1460ca7a8e85SJeff Kirsher 1461ca7a8e85SJeff Kirsher err_out_irq: 1462ca7a8e85SJeff Kirsher iowrite32(irqMasked, ioaddr + TYPHOON_REG_INTR_MASK); 1463ca7a8e85SJeff Kirsher iowrite32(irqEnabled, ioaddr + TYPHOON_REG_INTR_ENABLE); 1464ca7a8e85SJeff Kirsher 1465ca7a8e85SJeff Kirsher pci_free_consistent(pdev, PAGE_SIZE, dpage, dpage_dma); 1466ca7a8e85SJeff Kirsher 1467ca7a8e85SJeff Kirsher err_out: 1468ca7a8e85SJeff Kirsher return err; 1469ca7a8e85SJeff Kirsher } 1470ca7a8e85SJeff Kirsher 1471ca7a8e85SJeff Kirsher static int 1472ca7a8e85SJeff Kirsher typhoon_boot_3XP(struct typhoon *tp, u32 initial_status) 1473ca7a8e85SJeff Kirsher { 1474ca7a8e85SJeff Kirsher void __iomem *ioaddr = tp->ioaddr; 1475ca7a8e85SJeff Kirsher 1476ca7a8e85SJeff Kirsher if(typhoon_wait_status(ioaddr, initial_status) < 0) { 1477ca7a8e85SJeff Kirsher netdev_err(tp->dev, "boot ready timeout\n"); 1478ca7a8e85SJeff Kirsher goto out_timeout; 1479ca7a8e85SJeff Kirsher } 1480ca7a8e85SJeff Kirsher 1481ca7a8e85SJeff Kirsher iowrite32(0, ioaddr + TYPHOON_REG_BOOT_RECORD_ADDR_HI); 1482ca7a8e85SJeff Kirsher iowrite32(tp->shared_dma, ioaddr + TYPHOON_REG_BOOT_RECORD_ADDR_LO); 1483ca7a8e85SJeff Kirsher typhoon_post_pci_writes(ioaddr); 1484ca7a8e85SJeff Kirsher iowrite32(TYPHOON_BOOTCMD_REG_BOOT_RECORD, 1485ca7a8e85SJeff Kirsher ioaddr + TYPHOON_REG_COMMAND); 1486ca7a8e85SJeff Kirsher 1487ca7a8e85SJeff Kirsher if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_RUNNING) < 0) { 1488ca7a8e85SJeff Kirsher netdev_err(tp->dev, "boot finish timeout (status 0x%x)\n", 1489ca7a8e85SJeff Kirsher ioread32(ioaddr + TYPHOON_REG_STATUS)); 1490ca7a8e85SJeff Kirsher goto out_timeout; 1491ca7a8e85SJeff Kirsher } 1492ca7a8e85SJeff Kirsher 1493ca7a8e85SJeff Kirsher /* Clear the Transmit and Command ready registers 1494ca7a8e85SJeff Kirsher */ 1495ca7a8e85SJeff Kirsher iowrite32(0, ioaddr + TYPHOON_REG_TX_HI_READY); 1496ca7a8e85SJeff Kirsher iowrite32(0, ioaddr + TYPHOON_REG_CMD_READY); 1497ca7a8e85SJeff Kirsher iowrite32(0, ioaddr + TYPHOON_REG_TX_LO_READY); 1498ca7a8e85SJeff Kirsher typhoon_post_pci_writes(ioaddr); 1499ca7a8e85SJeff Kirsher iowrite32(TYPHOON_BOOTCMD_BOOT, ioaddr + TYPHOON_REG_COMMAND); 1500ca7a8e85SJeff Kirsher 1501ca7a8e85SJeff Kirsher return 0; 1502ca7a8e85SJeff Kirsher 1503ca7a8e85SJeff Kirsher out_timeout: 1504ca7a8e85SJeff Kirsher return -ETIMEDOUT; 1505ca7a8e85SJeff Kirsher } 1506ca7a8e85SJeff Kirsher 1507ca7a8e85SJeff Kirsher static u32 1508ca7a8e85SJeff Kirsher typhoon_clean_tx(struct typhoon *tp, struct transmit_ring *txRing, 1509ca7a8e85SJeff Kirsher volatile __le32 * index) 1510ca7a8e85SJeff Kirsher { 1511ca7a8e85SJeff Kirsher u32 lastRead = txRing->lastRead; 1512ca7a8e85SJeff Kirsher struct tx_desc *tx; 1513ca7a8e85SJeff Kirsher dma_addr_t skb_dma; 1514ca7a8e85SJeff Kirsher int dma_len; 1515ca7a8e85SJeff Kirsher int type; 1516ca7a8e85SJeff Kirsher 1517ca7a8e85SJeff Kirsher while(lastRead != le32_to_cpu(*index)) { 1518ca7a8e85SJeff Kirsher tx = (struct tx_desc *) (txRing->ringBase + lastRead); 1519ca7a8e85SJeff Kirsher type = tx->flags & TYPHOON_TYPE_MASK; 1520ca7a8e85SJeff Kirsher 1521ca7a8e85SJeff Kirsher if(type == TYPHOON_TX_DESC) { 1522ca7a8e85SJeff Kirsher /* This tx_desc describes a packet. 1523ca7a8e85SJeff Kirsher */ 1524ca7a8e85SJeff Kirsher unsigned long ptr = tx->tx_addr; 1525ca7a8e85SJeff Kirsher struct sk_buff *skb = (struct sk_buff *) ptr; 1526ca7a8e85SJeff Kirsher dev_kfree_skb_irq(skb); 1527ca7a8e85SJeff Kirsher } else if(type == TYPHOON_FRAG_DESC) { 1528ca7a8e85SJeff Kirsher /* This tx_desc describes a memory mapping. Free it. 1529ca7a8e85SJeff Kirsher */ 1530ca7a8e85SJeff Kirsher skb_dma = (dma_addr_t) le32_to_cpu(tx->frag.addr); 1531ca7a8e85SJeff Kirsher dma_len = le16_to_cpu(tx->len); 1532ca7a8e85SJeff Kirsher pci_unmap_single(tp->pdev, skb_dma, dma_len, 1533ca7a8e85SJeff Kirsher PCI_DMA_TODEVICE); 1534ca7a8e85SJeff Kirsher } 1535ca7a8e85SJeff Kirsher 1536ca7a8e85SJeff Kirsher tx->flags = 0; 1537ca7a8e85SJeff Kirsher typhoon_inc_tx_index(&lastRead, 1); 1538ca7a8e85SJeff Kirsher } 1539ca7a8e85SJeff Kirsher 1540ca7a8e85SJeff Kirsher return lastRead; 1541ca7a8e85SJeff Kirsher } 1542ca7a8e85SJeff Kirsher 1543ca7a8e85SJeff Kirsher static void 1544ca7a8e85SJeff Kirsher typhoon_tx_complete(struct typhoon *tp, struct transmit_ring *txRing, 1545ca7a8e85SJeff Kirsher volatile __le32 * index) 1546ca7a8e85SJeff Kirsher { 1547ca7a8e85SJeff Kirsher u32 lastRead; 1548ca7a8e85SJeff Kirsher int numDesc = MAX_SKB_FRAGS + 1; 1549ca7a8e85SJeff Kirsher 1550ca7a8e85SJeff Kirsher /* This will need changing if we start to use the Hi Tx ring. */ 1551ca7a8e85SJeff Kirsher lastRead = typhoon_clean_tx(tp, txRing, index); 1552ca7a8e85SJeff Kirsher if(netif_queue_stopped(tp->dev) && typhoon_num_free(txRing->lastWrite, 1553ca7a8e85SJeff Kirsher lastRead, TXLO_ENTRIES) > (numDesc + 2)) 1554ca7a8e85SJeff Kirsher netif_wake_queue(tp->dev); 1555ca7a8e85SJeff Kirsher 1556ca7a8e85SJeff Kirsher txRing->lastRead = lastRead; 1557ca7a8e85SJeff Kirsher smp_wmb(); 1558ca7a8e85SJeff Kirsher } 1559ca7a8e85SJeff Kirsher 1560ca7a8e85SJeff Kirsher static void 1561ca7a8e85SJeff Kirsher typhoon_recycle_rx_skb(struct typhoon *tp, u32 idx) 1562ca7a8e85SJeff Kirsher { 1563ca7a8e85SJeff Kirsher struct typhoon_indexes *indexes = tp->indexes; 1564ca7a8e85SJeff Kirsher struct rxbuff_ent *rxb = &tp->rxbuffers[idx]; 1565ca7a8e85SJeff Kirsher struct basic_ring *ring = &tp->rxBuffRing; 1566ca7a8e85SJeff Kirsher struct rx_free *r; 1567ca7a8e85SJeff Kirsher 1568ca7a8e85SJeff Kirsher if((ring->lastWrite + sizeof(*r)) % (RXFREE_ENTRIES * sizeof(*r)) == 1569ca7a8e85SJeff Kirsher le32_to_cpu(indexes->rxBuffCleared)) { 1570ca7a8e85SJeff Kirsher /* no room in ring, just drop the skb 1571ca7a8e85SJeff Kirsher */ 1572ca7a8e85SJeff Kirsher dev_kfree_skb_any(rxb->skb); 1573ca7a8e85SJeff Kirsher rxb->skb = NULL; 1574ca7a8e85SJeff Kirsher return; 1575ca7a8e85SJeff Kirsher } 1576ca7a8e85SJeff Kirsher 1577ca7a8e85SJeff Kirsher r = (struct rx_free *) (ring->ringBase + ring->lastWrite); 1578ca7a8e85SJeff Kirsher typhoon_inc_rxfree_index(&ring->lastWrite, 1); 1579ca7a8e85SJeff Kirsher r->virtAddr = idx; 1580ca7a8e85SJeff Kirsher r->physAddr = cpu_to_le32(rxb->dma_addr); 1581ca7a8e85SJeff Kirsher 1582ca7a8e85SJeff Kirsher /* Tell the card about it */ 1583ca7a8e85SJeff Kirsher wmb(); 1584ca7a8e85SJeff Kirsher indexes->rxBuffReady = cpu_to_le32(ring->lastWrite); 1585ca7a8e85SJeff Kirsher } 1586ca7a8e85SJeff Kirsher 1587ca7a8e85SJeff Kirsher static int 1588ca7a8e85SJeff Kirsher typhoon_alloc_rx_skb(struct typhoon *tp, u32 idx) 1589ca7a8e85SJeff Kirsher { 1590ca7a8e85SJeff Kirsher struct typhoon_indexes *indexes = tp->indexes; 1591ca7a8e85SJeff Kirsher struct rxbuff_ent *rxb = &tp->rxbuffers[idx]; 1592ca7a8e85SJeff Kirsher struct basic_ring *ring = &tp->rxBuffRing; 1593ca7a8e85SJeff Kirsher struct rx_free *r; 1594ca7a8e85SJeff Kirsher struct sk_buff *skb; 1595ca7a8e85SJeff Kirsher dma_addr_t dma_addr; 1596ca7a8e85SJeff Kirsher 1597ca7a8e85SJeff Kirsher rxb->skb = NULL; 1598ca7a8e85SJeff Kirsher 1599ca7a8e85SJeff Kirsher if((ring->lastWrite + sizeof(*r)) % (RXFREE_ENTRIES * sizeof(*r)) == 1600ca7a8e85SJeff Kirsher le32_to_cpu(indexes->rxBuffCleared)) 1601ca7a8e85SJeff Kirsher return -ENOMEM; 1602ca7a8e85SJeff Kirsher 16031d266430SPradeep A Dalvi skb = netdev_alloc_skb(tp->dev, PKT_BUF_SZ); 1604ca7a8e85SJeff Kirsher if(!skb) 1605ca7a8e85SJeff Kirsher return -ENOMEM; 1606ca7a8e85SJeff Kirsher 1607ca7a8e85SJeff Kirsher #if 0 1608ca7a8e85SJeff Kirsher /* Please, 3com, fix the firmware to allow DMA to a unaligned 1609ca7a8e85SJeff Kirsher * address! Pretty please? 1610ca7a8e85SJeff Kirsher */ 1611ca7a8e85SJeff Kirsher skb_reserve(skb, 2); 1612ca7a8e85SJeff Kirsher #endif 1613ca7a8e85SJeff Kirsher 1614ca7a8e85SJeff Kirsher dma_addr = pci_map_single(tp->pdev, skb->data, 1615ca7a8e85SJeff Kirsher PKT_BUF_SZ, PCI_DMA_FROMDEVICE); 1616ca7a8e85SJeff Kirsher 1617ca7a8e85SJeff Kirsher /* Since no card does 64 bit DAC, the high bits will never 1618ca7a8e85SJeff Kirsher * change from zero. 1619ca7a8e85SJeff Kirsher */ 1620ca7a8e85SJeff Kirsher r = (struct rx_free *) (ring->ringBase + ring->lastWrite); 1621ca7a8e85SJeff Kirsher typhoon_inc_rxfree_index(&ring->lastWrite, 1); 1622ca7a8e85SJeff Kirsher r->virtAddr = idx; 1623ca7a8e85SJeff Kirsher r->physAddr = cpu_to_le32(dma_addr); 1624ca7a8e85SJeff Kirsher rxb->skb = skb; 1625ca7a8e85SJeff Kirsher rxb->dma_addr = dma_addr; 1626ca7a8e85SJeff Kirsher 1627ca7a8e85SJeff Kirsher /* Tell the card about it */ 1628ca7a8e85SJeff Kirsher wmb(); 1629ca7a8e85SJeff Kirsher indexes->rxBuffReady = cpu_to_le32(ring->lastWrite); 1630ca7a8e85SJeff Kirsher return 0; 1631ca7a8e85SJeff Kirsher } 1632ca7a8e85SJeff Kirsher 1633ca7a8e85SJeff Kirsher static int 1634ca7a8e85SJeff Kirsher typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile __le32 * ready, 1635ca7a8e85SJeff Kirsher volatile __le32 * cleared, int budget) 1636ca7a8e85SJeff Kirsher { 1637ca7a8e85SJeff Kirsher struct rx_desc *rx; 1638ca7a8e85SJeff Kirsher struct sk_buff *skb, *new_skb; 1639ca7a8e85SJeff Kirsher struct rxbuff_ent *rxb; 1640ca7a8e85SJeff Kirsher dma_addr_t dma_addr; 1641ca7a8e85SJeff Kirsher u32 local_ready; 1642ca7a8e85SJeff Kirsher u32 rxaddr; 1643ca7a8e85SJeff Kirsher int pkt_len; 1644ca7a8e85SJeff Kirsher u32 idx; 1645ca7a8e85SJeff Kirsher __le32 csum_bits; 1646ca7a8e85SJeff Kirsher int received; 1647ca7a8e85SJeff Kirsher 1648ca7a8e85SJeff Kirsher received = 0; 1649ca7a8e85SJeff Kirsher local_ready = le32_to_cpu(*ready); 1650ca7a8e85SJeff Kirsher rxaddr = le32_to_cpu(*cleared); 1651ca7a8e85SJeff Kirsher while(rxaddr != local_ready && budget > 0) { 1652ca7a8e85SJeff Kirsher rx = (struct rx_desc *) (rxRing->ringBase + rxaddr); 1653ca7a8e85SJeff Kirsher idx = rx->addr; 1654ca7a8e85SJeff Kirsher rxb = &tp->rxbuffers[idx]; 1655ca7a8e85SJeff Kirsher skb = rxb->skb; 1656ca7a8e85SJeff Kirsher dma_addr = rxb->dma_addr; 1657ca7a8e85SJeff Kirsher 1658ca7a8e85SJeff Kirsher typhoon_inc_rx_index(&rxaddr, 1); 1659ca7a8e85SJeff Kirsher 1660ca7a8e85SJeff Kirsher if(rx->flags & TYPHOON_RX_ERROR) { 1661ca7a8e85SJeff Kirsher typhoon_recycle_rx_skb(tp, idx); 1662ca7a8e85SJeff Kirsher continue; 1663ca7a8e85SJeff Kirsher } 1664ca7a8e85SJeff Kirsher 1665ca7a8e85SJeff Kirsher pkt_len = le16_to_cpu(rx->frameLen); 1666ca7a8e85SJeff Kirsher 1667ca7a8e85SJeff Kirsher if(pkt_len < rx_copybreak && 16681d266430SPradeep A Dalvi (new_skb = netdev_alloc_skb(tp->dev, pkt_len + 2)) != NULL) { 1669ca7a8e85SJeff Kirsher skb_reserve(new_skb, 2); 1670ca7a8e85SJeff Kirsher pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, 1671ca7a8e85SJeff Kirsher PKT_BUF_SZ, 1672ca7a8e85SJeff Kirsher PCI_DMA_FROMDEVICE); 1673ca7a8e85SJeff Kirsher skb_copy_to_linear_data(new_skb, skb->data, pkt_len); 1674ca7a8e85SJeff Kirsher pci_dma_sync_single_for_device(tp->pdev, dma_addr, 1675ca7a8e85SJeff Kirsher PKT_BUF_SZ, 1676ca7a8e85SJeff Kirsher PCI_DMA_FROMDEVICE); 1677ca7a8e85SJeff Kirsher skb_put(new_skb, pkt_len); 1678ca7a8e85SJeff Kirsher typhoon_recycle_rx_skb(tp, idx); 1679ca7a8e85SJeff Kirsher } else { 1680ca7a8e85SJeff Kirsher new_skb = skb; 1681ca7a8e85SJeff Kirsher skb_put(new_skb, pkt_len); 1682ca7a8e85SJeff Kirsher pci_unmap_single(tp->pdev, dma_addr, PKT_BUF_SZ, 1683ca7a8e85SJeff Kirsher PCI_DMA_FROMDEVICE); 1684ca7a8e85SJeff Kirsher typhoon_alloc_rx_skb(tp, idx); 1685ca7a8e85SJeff Kirsher } 1686ca7a8e85SJeff Kirsher new_skb->protocol = eth_type_trans(new_skb, tp->dev); 1687ca7a8e85SJeff Kirsher csum_bits = rx->rxStatus & (TYPHOON_RX_IP_CHK_GOOD | 1688ca7a8e85SJeff Kirsher TYPHOON_RX_UDP_CHK_GOOD | TYPHOON_RX_TCP_CHK_GOOD); 1689ca7a8e85SJeff Kirsher if(csum_bits == 1690ca7a8e85SJeff Kirsher (TYPHOON_RX_IP_CHK_GOOD | TYPHOON_RX_TCP_CHK_GOOD) || 1691ca7a8e85SJeff Kirsher csum_bits == 1692ca7a8e85SJeff Kirsher (TYPHOON_RX_IP_CHK_GOOD | TYPHOON_RX_UDP_CHK_GOOD)) { 1693ca7a8e85SJeff Kirsher new_skb->ip_summed = CHECKSUM_UNNECESSARY; 1694ca7a8e85SJeff Kirsher } else 1695ca7a8e85SJeff Kirsher skb_checksum_none_assert(new_skb); 1696ca7a8e85SJeff Kirsher 1697ca7a8e85SJeff Kirsher if (rx->rxStatus & TYPHOON_RX_VLAN) 169886a9bad3SPatrick McHardy __vlan_hwaccel_put_tag(new_skb, htons(ETH_P_8021Q), 1699ca7a8e85SJeff Kirsher ntohl(rx->vlanTag) & 0xffff); 1700ca7a8e85SJeff Kirsher netif_receive_skb(new_skb); 1701ca7a8e85SJeff Kirsher 1702ca7a8e85SJeff Kirsher received++; 1703ca7a8e85SJeff Kirsher budget--; 1704ca7a8e85SJeff Kirsher } 1705ca7a8e85SJeff Kirsher *cleared = cpu_to_le32(rxaddr); 1706ca7a8e85SJeff Kirsher 1707ca7a8e85SJeff Kirsher return received; 1708ca7a8e85SJeff Kirsher } 1709ca7a8e85SJeff Kirsher 1710ca7a8e85SJeff Kirsher static void 1711ca7a8e85SJeff Kirsher typhoon_fill_free_ring(struct typhoon *tp) 1712ca7a8e85SJeff Kirsher { 1713ca7a8e85SJeff Kirsher u32 i; 1714ca7a8e85SJeff Kirsher 1715ca7a8e85SJeff Kirsher for(i = 0; i < RXENT_ENTRIES; i++) { 1716ca7a8e85SJeff Kirsher struct rxbuff_ent *rxb = &tp->rxbuffers[i]; 1717ca7a8e85SJeff Kirsher if(rxb->skb) 1718ca7a8e85SJeff Kirsher continue; 1719ca7a8e85SJeff Kirsher if(typhoon_alloc_rx_skb(tp, i) < 0) 1720ca7a8e85SJeff Kirsher break; 1721ca7a8e85SJeff Kirsher } 1722ca7a8e85SJeff Kirsher } 1723ca7a8e85SJeff Kirsher 1724ca7a8e85SJeff Kirsher static int 1725ca7a8e85SJeff Kirsher typhoon_poll(struct napi_struct *napi, int budget) 1726ca7a8e85SJeff Kirsher { 1727ca7a8e85SJeff Kirsher struct typhoon *tp = container_of(napi, struct typhoon, napi); 1728ca7a8e85SJeff Kirsher struct typhoon_indexes *indexes = tp->indexes; 1729ca7a8e85SJeff Kirsher int work_done; 1730ca7a8e85SJeff Kirsher 1731ca7a8e85SJeff Kirsher rmb(); 1732ca7a8e85SJeff Kirsher if(!tp->awaiting_resp && indexes->respReady != indexes->respCleared) 1733ca7a8e85SJeff Kirsher typhoon_process_response(tp, 0, NULL); 1734ca7a8e85SJeff Kirsher 1735ca7a8e85SJeff Kirsher if(le32_to_cpu(indexes->txLoCleared) != tp->txLoRing.lastRead) 1736ca7a8e85SJeff Kirsher typhoon_tx_complete(tp, &tp->txLoRing, &indexes->txLoCleared); 1737ca7a8e85SJeff Kirsher 1738ca7a8e85SJeff Kirsher work_done = 0; 1739ca7a8e85SJeff Kirsher 1740ca7a8e85SJeff Kirsher if(indexes->rxHiCleared != indexes->rxHiReady) { 1741ca7a8e85SJeff Kirsher work_done += typhoon_rx(tp, &tp->rxHiRing, &indexes->rxHiReady, 1742ca7a8e85SJeff Kirsher &indexes->rxHiCleared, budget); 1743ca7a8e85SJeff Kirsher } 1744ca7a8e85SJeff Kirsher 1745ca7a8e85SJeff Kirsher if(indexes->rxLoCleared != indexes->rxLoReady) { 1746ca7a8e85SJeff Kirsher work_done += typhoon_rx(tp, &tp->rxLoRing, &indexes->rxLoReady, 1747ca7a8e85SJeff Kirsher &indexes->rxLoCleared, budget - work_done); 1748ca7a8e85SJeff Kirsher } 1749ca7a8e85SJeff Kirsher 1750ca7a8e85SJeff Kirsher if(le32_to_cpu(indexes->rxBuffCleared) == tp->rxBuffRing.lastWrite) { 1751ca7a8e85SJeff Kirsher /* rxBuff ring is empty, try to fill it. */ 1752ca7a8e85SJeff Kirsher typhoon_fill_free_ring(tp); 1753ca7a8e85SJeff Kirsher } 1754ca7a8e85SJeff Kirsher 1755ca7a8e85SJeff Kirsher if (work_done < budget) { 1756ca7a8e85SJeff Kirsher napi_complete(napi); 1757ca7a8e85SJeff Kirsher iowrite32(TYPHOON_INTR_NONE, 1758ca7a8e85SJeff Kirsher tp->ioaddr + TYPHOON_REG_INTR_MASK); 1759ca7a8e85SJeff Kirsher typhoon_post_pci_writes(tp->ioaddr); 1760ca7a8e85SJeff Kirsher } 1761ca7a8e85SJeff Kirsher 1762ca7a8e85SJeff Kirsher return work_done; 1763ca7a8e85SJeff Kirsher } 1764ca7a8e85SJeff Kirsher 1765ca7a8e85SJeff Kirsher static irqreturn_t 1766ca7a8e85SJeff Kirsher typhoon_interrupt(int irq, void *dev_instance) 1767ca7a8e85SJeff Kirsher { 1768ca7a8e85SJeff Kirsher struct net_device *dev = dev_instance; 1769ca7a8e85SJeff Kirsher struct typhoon *tp = netdev_priv(dev); 1770ca7a8e85SJeff Kirsher void __iomem *ioaddr = tp->ioaddr; 1771ca7a8e85SJeff Kirsher u32 intr_status; 1772ca7a8e85SJeff Kirsher 1773ca7a8e85SJeff Kirsher intr_status = ioread32(ioaddr + TYPHOON_REG_INTR_STATUS); 1774ca7a8e85SJeff Kirsher if(!(intr_status & TYPHOON_INTR_HOST_INT)) 1775ca7a8e85SJeff Kirsher return IRQ_NONE; 1776ca7a8e85SJeff Kirsher 1777ca7a8e85SJeff Kirsher iowrite32(intr_status, ioaddr + TYPHOON_REG_INTR_STATUS); 1778ca7a8e85SJeff Kirsher 1779ca7a8e85SJeff Kirsher if (napi_schedule_prep(&tp->napi)) { 1780ca7a8e85SJeff Kirsher iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK); 1781ca7a8e85SJeff Kirsher typhoon_post_pci_writes(ioaddr); 1782ca7a8e85SJeff Kirsher __napi_schedule(&tp->napi); 1783ca7a8e85SJeff Kirsher } else { 1784ca7a8e85SJeff Kirsher netdev_err(dev, "Error, poll already scheduled\n"); 1785ca7a8e85SJeff Kirsher } 1786ca7a8e85SJeff Kirsher return IRQ_HANDLED; 1787ca7a8e85SJeff Kirsher } 1788ca7a8e85SJeff Kirsher 1789ca7a8e85SJeff Kirsher static void 1790ca7a8e85SJeff Kirsher typhoon_free_rx_rings(struct typhoon *tp) 1791ca7a8e85SJeff Kirsher { 1792ca7a8e85SJeff Kirsher u32 i; 1793ca7a8e85SJeff Kirsher 1794ca7a8e85SJeff Kirsher for(i = 0; i < RXENT_ENTRIES; i++) { 1795ca7a8e85SJeff Kirsher struct rxbuff_ent *rxb = &tp->rxbuffers[i]; 1796ca7a8e85SJeff Kirsher if(rxb->skb) { 1797ca7a8e85SJeff Kirsher pci_unmap_single(tp->pdev, rxb->dma_addr, PKT_BUF_SZ, 1798ca7a8e85SJeff Kirsher PCI_DMA_FROMDEVICE); 1799ca7a8e85SJeff Kirsher dev_kfree_skb(rxb->skb); 1800ca7a8e85SJeff Kirsher rxb->skb = NULL; 1801ca7a8e85SJeff Kirsher } 1802ca7a8e85SJeff Kirsher } 1803ca7a8e85SJeff Kirsher } 1804ca7a8e85SJeff Kirsher 1805ca7a8e85SJeff Kirsher static int 1806ca7a8e85SJeff Kirsher typhoon_sleep(struct typhoon *tp, pci_power_t state, __le16 events) 1807ca7a8e85SJeff Kirsher { 1808ca7a8e85SJeff Kirsher struct pci_dev *pdev = tp->pdev; 1809ca7a8e85SJeff Kirsher void __iomem *ioaddr = tp->ioaddr; 1810ca7a8e85SJeff Kirsher struct cmd_desc xp_cmd; 1811ca7a8e85SJeff Kirsher int err; 1812ca7a8e85SJeff Kirsher 1813ca7a8e85SJeff Kirsher INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_ENABLE_WAKE_EVENTS); 1814ca7a8e85SJeff Kirsher xp_cmd.parm1 = events; 1815ca7a8e85SJeff Kirsher err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); 1816ca7a8e85SJeff Kirsher if(err < 0) { 1817ca7a8e85SJeff Kirsher netdev_err(tp->dev, "typhoon_sleep(): wake events cmd err %d\n", 1818ca7a8e85SJeff Kirsher err); 1819ca7a8e85SJeff Kirsher return err; 1820ca7a8e85SJeff Kirsher } 1821ca7a8e85SJeff Kirsher 1822ca7a8e85SJeff Kirsher INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_GOTO_SLEEP); 1823ca7a8e85SJeff Kirsher err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); 1824ca7a8e85SJeff Kirsher if(err < 0) { 1825ca7a8e85SJeff Kirsher netdev_err(tp->dev, "typhoon_sleep(): sleep cmd err %d\n", err); 1826ca7a8e85SJeff Kirsher return err; 1827ca7a8e85SJeff Kirsher } 1828ca7a8e85SJeff Kirsher 1829ca7a8e85SJeff Kirsher if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_SLEEPING) < 0) 1830ca7a8e85SJeff Kirsher return -ETIMEDOUT; 1831ca7a8e85SJeff Kirsher 1832ca7a8e85SJeff Kirsher /* Since we cannot monitor the status of the link while sleeping, 1833ca7a8e85SJeff Kirsher * tell the world it went away. 1834ca7a8e85SJeff Kirsher */ 1835ca7a8e85SJeff Kirsher netif_carrier_off(tp->dev); 1836ca7a8e85SJeff Kirsher 1837ca7a8e85SJeff Kirsher pci_enable_wake(tp->pdev, state, 1); 1838ca7a8e85SJeff Kirsher pci_disable_device(pdev); 1839ca7a8e85SJeff Kirsher return pci_set_power_state(pdev, state); 1840ca7a8e85SJeff Kirsher } 1841ca7a8e85SJeff Kirsher 1842ca7a8e85SJeff Kirsher static int 1843ca7a8e85SJeff Kirsher typhoon_wakeup(struct typhoon *tp, int wait_type) 1844ca7a8e85SJeff Kirsher { 1845ca7a8e85SJeff Kirsher struct pci_dev *pdev = tp->pdev; 1846ca7a8e85SJeff Kirsher void __iomem *ioaddr = tp->ioaddr; 1847ca7a8e85SJeff Kirsher 1848ca7a8e85SJeff Kirsher pci_set_power_state(pdev, PCI_D0); 1849ca7a8e85SJeff Kirsher pci_restore_state(pdev); 1850ca7a8e85SJeff Kirsher 1851ca7a8e85SJeff Kirsher /* Post 2.x.x versions of the Sleep Image require a reset before 1852ca7a8e85SJeff Kirsher * we can download the Runtime Image. But let's not make users of 1853ca7a8e85SJeff Kirsher * the old firmware pay for the reset. 1854ca7a8e85SJeff Kirsher */ 1855ca7a8e85SJeff Kirsher iowrite32(TYPHOON_BOOTCMD_WAKEUP, ioaddr + TYPHOON_REG_COMMAND); 1856ca7a8e85SJeff Kirsher if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_HOST) < 0 || 1857ca7a8e85SJeff Kirsher (tp->capabilities & TYPHOON_WAKEUP_NEEDS_RESET)) 1858ca7a8e85SJeff Kirsher return typhoon_reset(ioaddr, wait_type); 1859ca7a8e85SJeff Kirsher 1860ca7a8e85SJeff Kirsher return 0; 1861ca7a8e85SJeff Kirsher } 1862ca7a8e85SJeff Kirsher 1863ca7a8e85SJeff Kirsher static int 1864ca7a8e85SJeff Kirsher typhoon_start_runtime(struct typhoon *tp) 1865ca7a8e85SJeff Kirsher { 1866ca7a8e85SJeff Kirsher struct net_device *dev = tp->dev; 1867ca7a8e85SJeff Kirsher void __iomem *ioaddr = tp->ioaddr; 1868ca7a8e85SJeff Kirsher struct cmd_desc xp_cmd; 1869ca7a8e85SJeff Kirsher int err; 1870ca7a8e85SJeff Kirsher 1871ca7a8e85SJeff Kirsher typhoon_init_rings(tp); 1872ca7a8e85SJeff Kirsher typhoon_fill_free_ring(tp); 1873ca7a8e85SJeff Kirsher 1874ca7a8e85SJeff Kirsher err = typhoon_download_firmware(tp); 1875ca7a8e85SJeff Kirsher if(err < 0) { 1876ca7a8e85SJeff Kirsher netdev_err(tp->dev, "cannot load runtime on 3XP\n"); 1877ca7a8e85SJeff Kirsher goto error_out; 1878ca7a8e85SJeff Kirsher } 1879ca7a8e85SJeff Kirsher 1880ca7a8e85SJeff Kirsher if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_BOOT) < 0) { 1881ca7a8e85SJeff Kirsher netdev_err(tp->dev, "cannot boot 3XP\n"); 1882ca7a8e85SJeff Kirsher err = -EIO; 1883ca7a8e85SJeff Kirsher goto error_out; 1884ca7a8e85SJeff Kirsher } 1885ca7a8e85SJeff Kirsher 1886ca7a8e85SJeff Kirsher INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_MAX_PKT_SIZE); 1887ca7a8e85SJeff Kirsher xp_cmd.parm1 = cpu_to_le16(PKT_BUF_SZ); 1888ca7a8e85SJeff Kirsher err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); 1889ca7a8e85SJeff Kirsher if(err < 0) 1890ca7a8e85SJeff Kirsher goto error_out; 1891ca7a8e85SJeff Kirsher 1892ca7a8e85SJeff Kirsher INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_MAC_ADDRESS); 1893ca7a8e85SJeff Kirsher xp_cmd.parm1 = cpu_to_le16(ntohs(*(__be16 *)&dev->dev_addr[0])); 1894ca7a8e85SJeff Kirsher xp_cmd.parm2 = cpu_to_le32(ntohl(*(__be32 *)&dev->dev_addr[2])); 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 /* Disable IRQ coalescing -- we can reenable it when 3Com gives 1900ca7a8e85SJeff Kirsher * us some more information on how to control it. 1901ca7a8e85SJeff Kirsher */ 1902ca7a8e85SJeff Kirsher INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_IRQ_COALESCE_CTRL); 1903ca7a8e85SJeff Kirsher xp_cmd.parm1 = 0; 1904ca7a8e85SJeff Kirsher err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); 1905ca7a8e85SJeff Kirsher if(err < 0) 1906ca7a8e85SJeff Kirsher goto error_out; 1907ca7a8e85SJeff Kirsher 1908ca7a8e85SJeff Kirsher INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_XCVR_SELECT); 1909ca7a8e85SJeff Kirsher xp_cmd.parm1 = tp->xcvr_select; 1910ca7a8e85SJeff Kirsher err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); 1911ca7a8e85SJeff Kirsher if(err < 0) 1912ca7a8e85SJeff Kirsher goto error_out; 1913ca7a8e85SJeff Kirsher 1914ca7a8e85SJeff Kirsher INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_VLAN_TYPE_WRITE); 1915ca7a8e85SJeff Kirsher xp_cmd.parm1 = cpu_to_le16(ETH_P_8021Q); 1916ca7a8e85SJeff Kirsher err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); 1917ca7a8e85SJeff Kirsher if(err < 0) 1918ca7a8e85SJeff Kirsher goto error_out; 1919ca7a8e85SJeff Kirsher 1920ca7a8e85SJeff Kirsher INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_OFFLOAD_TASKS); 1921ca7a8e85SJeff Kirsher xp_cmd.parm2 = tp->offload; 1922ca7a8e85SJeff Kirsher xp_cmd.parm3 = tp->offload; 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 typhoon_set_rx_mode(dev); 1928ca7a8e85SJeff Kirsher 1929ca7a8e85SJeff Kirsher INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_TX_ENABLE); 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 INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_RX_ENABLE); 1935ca7a8e85SJeff Kirsher err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); 1936ca7a8e85SJeff Kirsher if(err < 0) 1937ca7a8e85SJeff Kirsher goto error_out; 1938ca7a8e85SJeff Kirsher 1939ca7a8e85SJeff Kirsher tp->card_state = Running; 1940ca7a8e85SJeff Kirsher smp_wmb(); 1941ca7a8e85SJeff Kirsher 1942ca7a8e85SJeff Kirsher iowrite32(TYPHOON_INTR_ENABLE_ALL, ioaddr + TYPHOON_REG_INTR_ENABLE); 1943ca7a8e85SJeff Kirsher iowrite32(TYPHOON_INTR_NONE, ioaddr + TYPHOON_REG_INTR_MASK); 1944ca7a8e85SJeff Kirsher typhoon_post_pci_writes(ioaddr); 1945ca7a8e85SJeff Kirsher 1946ca7a8e85SJeff Kirsher return 0; 1947ca7a8e85SJeff Kirsher 1948ca7a8e85SJeff Kirsher error_out: 1949ca7a8e85SJeff Kirsher typhoon_reset(ioaddr, WaitNoSleep); 1950ca7a8e85SJeff Kirsher typhoon_free_rx_rings(tp); 1951ca7a8e85SJeff Kirsher typhoon_init_rings(tp); 1952ca7a8e85SJeff Kirsher return err; 1953ca7a8e85SJeff Kirsher } 1954ca7a8e85SJeff Kirsher 1955ca7a8e85SJeff Kirsher static int 1956ca7a8e85SJeff Kirsher typhoon_stop_runtime(struct typhoon *tp, int wait_type) 1957ca7a8e85SJeff Kirsher { 1958ca7a8e85SJeff Kirsher struct typhoon_indexes *indexes = tp->indexes; 1959ca7a8e85SJeff Kirsher struct transmit_ring *txLo = &tp->txLoRing; 1960ca7a8e85SJeff Kirsher void __iomem *ioaddr = tp->ioaddr; 1961ca7a8e85SJeff Kirsher struct cmd_desc xp_cmd; 1962ca7a8e85SJeff Kirsher int i; 1963ca7a8e85SJeff Kirsher 1964ca7a8e85SJeff Kirsher /* Disable interrupts early, since we can't schedule a poll 1965ca7a8e85SJeff Kirsher * when called with !netif_running(). This will be posted 1966ca7a8e85SJeff Kirsher * when we force the posting of the command. 1967ca7a8e85SJeff Kirsher */ 1968ca7a8e85SJeff Kirsher iowrite32(TYPHOON_INTR_NONE, ioaddr + TYPHOON_REG_INTR_ENABLE); 1969ca7a8e85SJeff Kirsher 1970ca7a8e85SJeff Kirsher INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_RX_DISABLE); 1971ca7a8e85SJeff Kirsher typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); 1972ca7a8e85SJeff Kirsher 1973ca7a8e85SJeff Kirsher /* Wait 1/2 sec for any outstanding transmits to occur 1974ca7a8e85SJeff Kirsher * We'll cleanup after the reset if this times out. 1975ca7a8e85SJeff Kirsher */ 1976ca7a8e85SJeff Kirsher for(i = 0; i < TYPHOON_WAIT_TIMEOUT; i++) { 1977ca7a8e85SJeff Kirsher if(indexes->txLoCleared == cpu_to_le32(txLo->lastWrite)) 1978ca7a8e85SJeff Kirsher break; 1979ca7a8e85SJeff Kirsher udelay(TYPHOON_UDELAY); 1980ca7a8e85SJeff Kirsher } 1981ca7a8e85SJeff Kirsher 1982ca7a8e85SJeff Kirsher if(i == TYPHOON_WAIT_TIMEOUT) 1983ca7a8e85SJeff Kirsher netdev_err(tp->dev, "halt timed out waiting for Tx to complete\n"); 1984ca7a8e85SJeff Kirsher 1985ca7a8e85SJeff Kirsher INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_TX_DISABLE); 1986ca7a8e85SJeff Kirsher typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); 1987ca7a8e85SJeff Kirsher 1988ca7a8e85SJeff Kirsher /* save the statistics so when we bring the interface up again, 1989ca7a8e85SJeff Kirsher * the values reported to userspace are correct. 1990ca7a8e85SJeff Kirsher */ 1991ca7a8e85SJeff Kirsher tp->card_state = Sleeping; 1992ca7a8e85SJeff Kirsher smp_wmb(); 1993ca7a8e85SJeff Kirsher typhoon_do_get_stats(tp); 1994ca7a8e85SJeff Kirsher memcpy(&tp->stats_saved, &tp->stats, sizeof(struct net_device_stats)); 1995ca7a8e85SJeff Kirsher 1996ca7a8e85SJeff Kirsher INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_HALT); 1997ca7a8e85SJeff Kirsher typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL); 1998ca7a8e85SJeff Kirsher 1999ca7a8e85SJeff Kirsher if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_HALTED) < 0) 2000ca7a8e85SJeff Kirsher netdev_err(tp->dev, "timed out waiting for 3XP to halt\n"); 2001ca7a8e85SJeff Kirsher 2002ca7a8e85SJeff Kirsher if(typhoon_reset(ioaddr, wait_type) < 0) { 2003ca7a8e85SJeff Kirsher netdev_err(tp->dev, "unable to reset 3XP\n"); 2004ca7a8e85SJeff Kirsher return -ETIMEDOUT; 2005ca7a8e85SJeff Kirsher } 2006ca7a8e85SJeff Kirsher 2007ca7a8e85SJeff Kirsher /* cleanup any outstanding Tx packets */ 2008ca7a8e85SJeff Kirsher if(indexes->txLoCleared != cpu_to_le32(txLo->lastWrite)) { 2009ca7a8e85SJeff Kirsher indexes->txLoCleared = cpu_to_le32(txLo->lastWrite); 2010ca7a8e85SJeff Kirsher typhoon_clean_tx(tp, &tp->txLoRing, &indexes->txLoCleared); 2011ca7a8e85SJeff Kirsher } 2012ca7a8e85SJeff Kirsher 2013ca7a8e85SJeff Kirsher return 0; 2014ca7a8e85SJeff Kirsher } 2015ca7a8e85SJeff Kirsher 2016ca7a8e85SJeff Kirsher static void 2017ca7a8e85SJeff Kirsher typhoon_tx_timeout(struct net_device *dev) 2018ca7a8e85SJeff Kirsher { 2019ca7a8e85SJeff Kirsher struct typhoon *tp = netdev_priv(dev); 2020ca7a8e85SJeff Kirsher 2021ca7a8e85SJeff Kirsher if(typhoon_reset(tp->ioaddr, WaitNoSleep) < 0) { 2022ca7a8e85SJeff Kirsher netdev_warn(dev, "could not reset in tx timeout\n"); 2023ca7a8e85SJeff Kirsher goto truly_dead; 2024ca7a8e85SJeff Kirsher } 2025ca7a8e85SJeff Kirsher 2026ca7a8e85SJeff Kirsher /* If we ever start using the Hi ring, it will need cleaning too */ 2027ca7a8e85SJeff Kirsher typhoon_clean_tx(tp, &tp->txLoRing, &tp->indexes->txLoCleared); 2028ca7a8e85SJeff Kirsher typhoon_free_rx_rings(tp); 2029ca7a8e85SJeff Kirsher 2030ca7a8e85SJeff Kirsher if(typhoon_start_runtime(tp) < 0) { 2031ca7a8e85SJeff Kirsher netdev_err(dev, "could not start runtime in tx timeout\n"); 2032ca7a8e85SJeff Kirsher goto truly_dead; 2033ca7a8e85SJeff Kirsher } 2034ca7a8e85SJeff Kirsher 2035ca7a8e85SJeff Kirsher netif_wake_queue(dev); 2036ca7a8e85SJeff Kirsher return; 2037ca7a8e85SJeff Kirsher 2038ca7a8e85SJeff Kirsher truly_dead: 2039ca7a8e85SJeff Kirsher /* Reset the hardware, and turn off carrier to avoid more timeouts */ 2040ca7a8e85SJeff Kirsher typhoon_reset(tp->ioaddr, NoWait); 2041ca7a8e85SJeff Kirsher netif_carrier_off(dev); 2042ca7a8e85SJeff Kirsher } 2043ca7a8e85SJeff Kirsher 2044ca7a8e85SJeff Kirsher static int 2045ca7a8e85SJeff Kirsher typhoon_open(struct net_device *dev) 2046ca7a8e85SJeff Kirsher { 2047ca7a8e85SJeff Kirsher struct typhoon *tp = netdev_priv(dev); 2048ca7a8e85SJeff Kirsher int err; 2049ca7a8e85SJeff Kirsher 2050ca7a8e85SJeff Kirsher err = typhoon_request_firmware(tp); 2051ca7a8e85SJeff Kirsher if (err) 2052ca7a8e85SJeff Kirsher goto out; 2053ca7a8e85SJeff Kirsher 2054ca7a8e85SJeff Kirsher err = typhoon_wakeup(tp, WaitSleep); 2055ca7a8e85SJeff Kirsher if(err < 0) { 2056ca7a8e85SJeff Kirsher netdev_err(dev, "unable to wakeup device\n"); 2057ca7a8e85SJeff Kirsher goto out_sleep; 2058ca7a8e85SJeff Kirsher } 2059ca7a8e85SJeff Kirsher 2060ca7a8e85SJeff Kirsher err = request_irq(dev->irq, typhoon_interrupt, IRQF_SHARED, 2061ca7a8e85SJeff Kirsher dev->name, dev); 2062ca7a8e85SJeff Kirsher if(err < 0) 2063ca7a8e85SJeff Kirsher goto out_sleep; 2064ca7a8e85SJeff Kirsher 2065ca7a8e85SJeff Kirsher napi_enable(&tp->napi); 2066ca7a8e85SJeff Kirsher 2067ca7a8e85SJeff Kirsher err = typhoon_start_runtime(tp); 2068ca7a8e85SJeff Kirsher if(err < 0) { 2069ca7a8e85SJeff Kirsher napi_disable(&tp->napi); 2070ca7a8e85SJeff Kirsher goto out_irq; 2071ca7a8e85SJeff Kirsher } 2072ca7a8e85SJeff Kirsher 2073ca7a8e85SJeff Kirsher netif_start_queue(dev); 2074ca7a8e85SJeff Kirsher return 0; 2075ca7a8e85SJeff Kirsher 2076ca7a8e85SJeff Kirsher out_irq: 2077ca7a8e85SJeff Kirsher free_irq(dev->irq, dev); 2078ca7a8e85SJeff Kirsher 2079ca7a8e85SJeff Kirsher out_sleep: 2080ca7a8e85SJeff Kirsher if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) { 2081ca7a8e85SJeff Kirsher netdev_err(dev, "unable to reboot into sleep img\n"); 2082ca7a8e85SJeff Kirsher typhoon_reset(tp->ioaddr, NoWait); 2083ca7a8e85SJeff Kirsher goto out; 2084ca7a8e85SJeff Kirsher } 2085ca7a8e85SJeff Kirsher 2086ca7a8e85SJeff Kirsher if(typhoon_sleep(tp, PCI_D3hot, 0) < 0) 2087ca7a8e85SJeff Kirsher netdev_err(dev, "unable to go back to sleep\n"); 2088ca7a8e85SJeff Kirsher 2089ca7a8e85SJeff Kirsher out: 2090ca7a8e85SJeff Kirsher return err; 2091ca7a8e85SJeff Kirsher } 2092ca7a8e85SJeff Kirsher 2093ca7a8e85SJeff Kirsher static int 2094ca7a8e85SJeff Kirsher typhoon_close(struct net_device *dev) 2095ca7a8e85SJeff Kirsher { 2096ca7a8e85SJeff Kirsher struct typhoon *tp = netdev_priv(dev); 2097ca7a8e85SJeff Kirsher 2098ca7a8e85SJeff Kirsher netif_stop_queue(dev); 2099ca7a8e85SJeff Kirsher napi_disable(&tp->napi); 2100ca7a8e85SJeff Kirsher 2101ca7a8e85SJeff Kirsher if(typhoon_stop_runtime(tp, WaitSleep) < 0) 2102ca7a8e85SJeff Kirsher netdev_err(dev, "unable to stop runtime\n"); 2103ca7a8e85SJeff Kirsher 2104ca7a8e85SJeff Kirsher /* Make sure there is no irq handler running on a different CPU. */ 2105ca7a8e85SJeff Kirsher free_irq(dev->irq, dev); 2106ca7a8e85SJeff Kirsher 2107ca7a8e85SJeff Kirsher typhoon_free_rx_rings(tp); 2108ca7a8e85SJeff Kirsher typhoon_init_rings(tp); 2109ca7a8e85SJeff Kirsher 2110ca7a8e85SJeff Kirsher if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) 2111ca7a8e85SJeff Kirsher netdev_err(dev, "unable to boot sleep image\n"); 2112ca7a8e85SJeff Kirsher 2113ca7a8e85SJeff Kirsher if(typhoon_sleep(tp, PCI_D3hot, 0) < 0) 2114ca7a8e85SJeff Kirsher netdev_err(dev, "unable to put card to sleep\n"); 2115ca7a8e85SJeff Kirsher 2116ca7a8e85SJeff Kirsher return 0; 2117ca7a8e85SJeff Kirsher } 2118ca7a8e85SJeff Kirsher 2119ca7a8e85SJeff Kirsher #ifdef CONFIG_PM 2120ca7a8e85SJeff Kirsher static int 2121ca7a8e85SJeff Kirsher typhoon_resume(struct pci_dev *pdev) 2122ca7a8e85SJeff Kirsher { 2123ca7a8e85SJeff Kirsher struct net_device *dev = pci_get_drvdata(pdev); 2124ca7a8e85SJeff Kirsher struct typhoon *tp = netdev_priv(dev); 2125ca7a8e85SJeff Kirsher 2126ca7a8e85SJeff Kirsher /* If we're down, resume when we are upped. 2127ca7a8e85SJeff Kirsher */ 2128ca7a8e85SJeff Kirsher if(!netif_running(dev)) 2129ca7a8e85SJeff Kirsher return 0; 2130ca7a8e85SJeff Kirsher 2131ca7a8e85SJeff Kirsher if(typhoon_wakeup(tp, WaitNoSleep) < 0) { 2132ca7a8e85SJeff Kirsher netdev_err(dev, "critical: could not wake up in resume\n"); 2133ca7a8e85SJeff Kirsher goto reset; 2134ca7a8e85SJeff Kirsher } 2135ca7a8e85SJeff Kirsher 2136ca7a8e85SJeff Kirsher if(typhoon_start_runtime(tp) < 0) { 2137ca7a8e85SJeff Kirsher netdev_err(dev, "critical: could not start runtime in resume\n"); 2138ca7a8e85SJeff Kirsher goto reset; 2139ca7a8e85SJeff Kirsher } 2140ca7a8e85SJeff Kirsher 2141ca7a8e85SJeff Kirsher netif_device_attach(dev); 2142ca7a8e85SJeff Kirsher return 0; 2143ca7a8e85SJeff Kirsher 2144ca7a8e85SJeff Kirsher reset: 2145ca7a8e85SJeff Kirsher typhoon_reset(tp->ioaddr, NoWait); 2146ca7a8e85SJeff Kirsher return -EBUSY; 2147ca7a8e85SJeff Kirsher } 2148ca7a8e85SJeff Kirsher 2149ca7a8e85SJeff Kirsher static int 2150ca7a8e85SJeff Kirsher typhoon_suspend(struct pci_dev *pdev, pm_message_t state) 2151ca7a8e85SJeff Kirsher { 2152ca7a8e85SJeff Kirsher struct net_device *dev = pci_get_drvdata(pdev); 2153ca7a8e85SJeff Kirsher struct typhoon *tp = netdev_priv(dev); 2154ca7a8e85SJeff Kirsher struct cmd_desc xp_cmd; 2155ca7a8e85SJeff Kirsher 2156ca7a8e85SJeff Kirsher /* If we're down, we're already suspended. 2157ca7a8e85SJeff Kirsher */ 2158ca7a8e85SJeff Kirsher if(!netif_running(dev)) 2159ca7a8e85SJeff Kirsher return 0; 2160ca7a8e85SJeff Kirsher 2161ca7a8e85SJeff Kirsher /* TYPHOON_OFFLOAD_VLAN is always on now, so this doesn't work */ 2162ca7a8e85SJeff Kirsher if(tp->wol_events & TYPHOON_WAKE_MAGIC_PKT) 2163ca7a8e85SJeff Kirsher netdev_warn(dev, "cannot do WAKE_MAGIC with VLAN offloading\n"); 2164ca7a8e85SJeff Kirsher 2165ca7a8e85SJeff Kirsher netif_device_detach(dev); 2166ca7a8e85SJeff Kirsher 2167ca7a8e85SJeff Kirsher if(typhoon_stop_runtime(tp, WaitNoSleep) < 0) { 2168ca7a8e85SJeff Kirsher netdev_err(dev, "unable to stop runtime\n"); 2169ca7a8e85SJeff Kirsher goto need_resume; 2170ca7a8e85SJeff Kirsher } 2171ca7a8e85SJeff Kirsher 2172ca7a8e85SJeff Kirsher typhoon_free_rx_rings(tp); 2173ca7a8e85SJeff Kirsher typhoon_init_rings(tp); 2174ca7a8e85SJeff Kirsher 2175ca7a8e85SJeff Kirsher if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) { 2176ca7a8e85SJeff Kirsher netdev_err(dev, "unable to boot sleep image\n"); 2177ca7a8e85SJeff Kirsher goto need_resume; 2178ca7a8e85SJeff Kirsher } 2179ca7a8e85SJeff Kirsher 2180ca7a8e85SJeff Kirsher INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_MAC_ADDRESS); 2181ca7a8e85SJeff Kirsher xp_cmd.parm1 = cpu_to_le16(ntohs(*(__be16 *)&dev->dev_addr[0])); 2182ca7a8e85SJeff Kirsher xp_cmd.parm2 = cpu_to_le32(ntohl(*(__be32 *)&dev->dev_addr[2])); 2183ca7a8e85SJeff Kirsher if(typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL) < 0) { 2184ca7a8e85SJeff Kirsher netdev_err(dev, "unable to set mac address in suspend\n"); 2185ca7a8e85SJeff Kirsher goto need_resume; 2186ca7a8e85SJeff Kirsher } 2187ca7a8e85SJeff Kirsher 2188ca7a8e85SJeff Kirsher INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_RX_FILTER); 2189ca7a8e85SJeff Kirsher xp_cmd.parm1 = TYPHOON_RX_FILTER_DIRECTED | TYPHOON_RX_FILTER_BROADCAST; 2190ca7a8e85SJeff Kirsher if(typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL) < 0) { 2191ca7a8e85SJeff Kirsher netdev_err(dev, "unable to set rx filter in suspend\n"); 2192ca7a8e85SJeff Kirsher goto need_resume; 2193ca7a8e85SJeff Kirsher } 2194ca7a8e85SJeff Kirsher 2195ca7a8e85SJeff Kirsher if(typhoon_sleep(tp, pci_choose_state(pdev, state), tp->wol_events) < 0) { 2196ca7a8e85SJeff Kirsher netdev_err(dev, "unable to put card to sleep\n"); 2197ca7a8e85SJeff Kirsher goto need_resume; 2198ca7a8e85SJeff Kirsher } 2199ca7a8e85SJeff Kirsher 2200ca7a8e85SJeff Kirsher return 0; 2201ca7a8e85SJeff Kirsher 2202ca7a8e85SJeff Kirsher need_resume: 2203ca7a8e85SJeff Kirsher typhoon_resume(pdev); 2204ca7a8e85SJeff Kirsher return -EBUSY; 2205ca7a8e85SJeff Kirsher } 2206ca7a8e85SJeff Kirsher #endif 2207ca7a8e85SJeff Kirsher 220821cf689bSBill Pemberton static int 2209ca7a8e85SJeff Kirsher typhoon_test_mmio(struct pci_dev *pdev) 2210ca7a8e85SJeff Kirsher { 2211ca7a8e85SJeff Kirsher void __iomem *ioaddr = pci_iomap(pdev, 1, 128); 2212ca7a8e85SJeff Kirsher int mode = 0; 2213ca7a8e85SJeff Kirsher u32 val; 2214ca7a8e85SJeff Kirsher 2215ca7a8e85SJeff Kirsher if(!ioaddr) 2216ca7a8e85SJeff Kirsher goto out; 2217ca7a8e85SJeff Kirsher 2218ca7a8e85SJeff Kirsher if(ioread32(ioaddr + TYPHOON_REG_STATUS) != 2219ca7a8e85SJeff Kirsher TYPHOON_STATUS_WAITING_FOR_HOST) 2220ca7a8e85SJeff Kirsher goto out_unmap; 2221ca7a8e85SJeff Kirsher 2222ca7a8e85SJeff Kirsher iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK); 2223ca7a8e85SJeff Kirsher iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_STATUS); 2224ca7a8e85SJeff Kirsher iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_ENABLE); 2225ca7a8e85SJeff Kirsher 2226ca7a8e85SJeff Kirsher /* Ok, see if we can change our interrupt status register by 2227ca7a8e85SJeff Kirsher * sending ourselves an interrupt. If so, then MMIO works. 2228ca7a8e85SJeff Kirsher * The 50usec delay is arbitrary -- it could probably be smaller. 2229ca7a8e85SJeff Kirsher */ 2230ca7a8e85SJeff Kirsher val = ioread32(ioaddr + TYPHOON_REG_INTR_STATUS); 2231ca7a8e85SJeff Kirsher if((val & TYPHOON_INTR_SELF) == 0) { 2232ca7a8e85SJeff Kirsher iowrite32(1, ioaddr + TYPHOON_REG_SELF_INTERRUPT); 2233ca7a8e85SJeff Kirsher ioread32(ioaddr + TYPHOON_REG_INTR_STATUS); 2234ca7a8e85SJeff Kirsher udelay(50); 2235ca7a8e85SJeff Kirsher val = ioread32(ioaddr + TYPHOON_REG_INTR_STATUS); 2236ca7a8e85SJeff Kirsher if(val & TYPHOON_INTR_SELF) 2237ca7a8e85SJeff Kirsher mode = 1; 2238ca7a8e85SJeff Kirsher } 2239ca7a8e85SJeff Kirsher 2240ca7a8e85SJeff Kirsher iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK); 2241ca7a8e85SJeff Kirsher iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_STATUS); 2242ca7a8e85SJeff Kirsher iowrite32(TYPHOON_INTR_NONE, ioaddr + TYPHOON_REG_INTR_ENABLE); 2243ca7a8e85SJeff Kirsher ioread32(ioaddr + TYPHOON_REG_INTR_STATUS); 2244ca7a8e85SJeff Kirsher 2245ca7a8e85SJeff Kirsher out_unmap: 2246ca7a8e85SJeff Kirsher pci_iounmap(pdev, ioaddr); 2247ca7a8e85SJeff Kirsher 2248ca7a8e85SJeff Kirsher out: 2249ca7a8e85SJeff Kirsher if(!mode) 2250ca7a8e85SJeff Kirsher pr_info("%s: falling back to port IO\n", pci_name(pdev)); 2251ca7a8e85SJeff Kirsher return mode; 2252ca7a8e85SJeff Kirsher } 2253ca7a8e85SJeff Kirsher 2254ca7a8e85SJeff Kirsher static const struct net_device_ops typhoon_netdev_ops = { 2255ca7a8e85SJeff Kirsher .ndo_open = typhoon_open, 2256ca7a8e85SJeff Kirsher .ndo_stop = typhoon_close, 2257ca7a8e85SJeff Kirsher .ndo_start_xmit = typhoon_start_tx, 2258afc4b13dSJiri Pirko .ndo_set_rx_mode = typhoon_set_rx_mode, 2259ca7a8e85SJeff Kirsher .ndo_tx_timeout = typhoon_tx_timeout, 2260ca7a8e85SJeff Kirsher .ndo_get_stats = typhoon_get_stats, 2261ca7a8e85SJeff Kirsher .ndo_validate_addr = eth_validate_addr, 2262b049aadcSDanny Kukawka .ndo_set_mac_address = eth_mac_addr, 2263ca7a8e85SJeff Kirsher }; 2264ca7a8e85SJeff Kirsher 226521cf689bSBill Pemberton static int 2266ca7a8e85SJeff Kirsher typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 2267ca7a8e85SJeff Kirsher { 2268ca7a8e85SJeff Kirsher struct net_device *dev; 2269ca7a8e85SJeff Kirsher struct typhoon *tp; 2270ca7a8e85SJeff Kirsher int card_id = (int) ent->driver_data; 2271ca7a8e85SJeff Kirsher void __iomem *ioaddr; 2272ca7a8e85SJeff Kirsher void *shared; 2273ca7a8e85SJeff Kirsher dma_addr_t shared_dma; 2274ca7a8e85SJeff Kirsher struct cmd_desc xp_cmd; 2275ca7a8e85SJeff Kirsher struct resp_desc xp_resp[3]; 2276ca7a8e85SJeff Kirsher int err = 0; 2277ca7a8e85SJeff Kirsher const char *err_msg; 2278ca7a8e85SJeff Kirsher 2279ca7a8e85SJeff Kirsher dev = alloc_etherdev(sizeof(*tp)); 2280ca7a8e85SJeff Kirsher if(dev == NULL) { 2281ca7a8e85SJeff Kirsher err_msg = "unable to alloc new net device"; 2282ca7a8e85SJeff Kirsher err = -ENOMEM; 2283ca7a8e85SJeff Kirsher goto error_out; 2284ca7a8e85SJeff Kirsher } 2285ca7a8e85SJeff Kirsher SET_NETDEV_DEV(dev, &pdev->dev); 2286ca7a8e85SJeff Kirsher 2287ca7a8e85SJeff Kirsher err = pci_enable_device(pdev); 2288ca7a8e85SJeff Kirsher if(err < 0) { 2289ca7a8e85SJeff Kirsher err_msg = "unable to enable device"; 2290ca7a8e85SJeff Kirsher goto error_out_dev; 2291ca7a8e85SJeff Kirsher } 2292ca7a8e85SJeff Kirsher 2293ca7a8e85SJeff Kirsher err = pci_set_mwi(pdev); 2294ca7a8e85SJeff Kirsher if(err < 0) { 2295ca7a8e85SJeff Kirsher err_msg = "unable to set MWI"; 2296ca7a8e85SJeff Kirsher goto error_out_disable; 2297ca7a8e85SJeff Kirsher } 2298ca7a8e85SJeff Kirsher 2299ca7a8e85SJeff Kirsher err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); 2300ca7a8e85SJeff Kirsher if(err < 0) { 2301ca7a8e85SJeff Kirsher err_msg = "No usable DMA configuration"; 2302ca7a8e85SJeff Kirsher goto error_out_mwi; 2303ca7a8e85SJeff Kirsher } 2304ca7a8e85SJeff Kirsher 2305ca7a8e85SJeff Kirsher /* sanity checks on IO and MMIO BARs 2306ca7a8e85SJeff Kirsher */ 2307ca7a8e85SJeff Kirsher if(!(pci_resource_flags(pdev, 0) & IORESOURCE_IO)) { 2308ca7a8e85SJeff Kirsher err_msg = "region #1 not a PCI IO resource, aborting"; 2309ca7a8e85SJeff Kirsher err = -ENODEV; 2310ca7a8e85SJeff Kirsher goto error_out_mwi; 2311ca7a8e85SJeff Kirsher } 2312ca7a8e85SJeff Kirsher if(pci_resource_len(pdev, 0) < 128) { 2313ca7a8e85SJeff Kirsher err_msg = "Invalid PCI IO region size, aborting"; 2314ca7a8e85SJeff Kirsher err = -ENODEV; 2315ca7a8e85SJeff Kirsher goto error_out_mwi; 2316ca7a8e85SJeff Kirsher } 2317ca7a8e85SJeff Kirsher if(!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) { 2318ca7a8e85SJeff Kirsher err_msg = "region #1 not a PCI MMIO resource, aborting"; 2319ca7a8e85SJeff Kirsher err = -ENODEV; 2320ca7a8e85SJeff Kirsher goto error_out_mwi; 2321ca7a8e85SJeff Kirsher } 2322ca7a8e85SJeff Kirsher if(pci_resource_len(pdev, 1) < 128) { 2323ca7a8e85SJeff Kirsher err_msg = "Invalid PCI MMIO region size, aborting"; 2324ca7a8e85SJeff Kirsher err = -ENODEV; 2325ca7a8e85SJeff Kirsher goto error_out_mwi; 2326ca7a8e85SJeff Kirsher } 2327ca7a8e85SJeff Kirsher 2328ca7a8e85SJeff Kirsher err = pci_request_regions(pdev, KBUILD_MODNAME); 2329ca7a8e85SJeff Kirsher if(err < 0) { 2330ca7a8e85SJeff Kirsher err_msg = "could not request regions"; 2331ca7a8e85SJeff Kirsher goto error_out_mwi; 2332ca7a8e85SJeff Kirsher } 2333ca7a8e85SJeff Kirsher 2334ca7a8e85SJeff Kirsher /* map our registers 2335ca7a8e85SJeff Kirsher */ 2336ca7a8e85SJeff Kirsher if(use_mmio != 0 && use_mmio != 1) 2337ca7a8e85SJeff Kirsher use_mmio = typhoon_test_mmio(pdev); 2338ca7a8e85SJeff Kirsher 2339ca7a8e85SJeff Kirsher ioaddr = pci_iomap(pdev, use_mmio, 128); 2340ca7a8e85SJeff Kirsher if (!ioaddr) { 2341ca7a8e85SJeff Kirsher err_msg = "cannot remap registers, aborting"; 2342ca7a8e85SJeff Kirsher err = -EIO; 2343ca7a8e85SJeff Kirsher goto error_out_regions; 2344ca7a8e85SJeff Kirsher } 2345ca7a8e85SJeff Kirsher 2346ca7a8e85SJeff Kirsher /* allocate pci dma space for rx and tx descriptor rings 2347ca7a8e85SJeff Kirsher */ 2348ca7a8e85SJeff Kirsher shared = pci_alloc_consistent(pdev, sizeof(struct typhoon_shared), 2349ca7a8e85SJeff Kirsher &shared_dma); 2350ca7a8e85SJeff Kirsher if(!shared) { 2351ca7a8e85SJeff Kirsher err_msg = "could not allocate DMA memory"; 2352ca7a8e85SJeff Kirsher err = -ENOMEM; 2353ca7a8e85SJeff Kirsher goto error_out_remap; 2354ca7a8e85SJeff Kirsher } 2355ca7a8e85SJeff Kirsher 2356ca7a8e85SJeff Kirsher dev->irq = pdev->irq; 2357ca7a8e85SJeff Kirsher tp = netdev_priv(dev); 2358ca7a8e85SJeff Kirsher tp->shared = shared; 2359ca7a8e85SJeff Kirsher tp->shared_dma = shared_dma; 2360ca7a8e85SJeff Kirsher tp->pdev = pdev; 2361ca7a8e85SJeff Kirsher tp->tx_pdev = pdev; 2362ca7a8e85SJeff Kirsher tp->ioaddr = ioaddr; 2363ca7a8e85SJeff Kirsher tp->tx_ioaddr = ioaddr; 2364ca7a8e85SJeff Kirsher tp->dev = dev; 2365ca7a8e85SJeff Kirsher 2366ca7a8e85SJeff Kirsher /* Init sequence: 2367ca7a8e85SJeff Kirsher * 1) Reset the adapter to clear any bad juju 2368ca7a8e85SJeff Kirsher * 2) Reload the sleep image 2369ca7a8e85SJeff Kirsher * 3) Boot the sleep image 2370ca7a8e85SJeff Kirsher * 4) Get the hardware address. 2371ca7a8e85SJeff Kirsher * 5) Put the card to sleep. 2372ca7a8e85SJeff Kirsher */ 2373ca7a8e85SJeff Kirsher if (typhoon_reset(ioaddr, WaitSleep) < 0) { 2374ca7a8e85SJeff Kirsher err_msg = "could not reset 3XP"; 2375ca7a8e85SJeff Kirsher err = -EIO; 2376ca7a8e85SJeff Kirsher goto error_out_dma; 2377ca7a8e85SJeff Kirsher } 2378ca7a8e85SJeff Kirsher 2379ca7a8e85SJeff Kirsher /* Now that we've reset the 3XP and are sure it's not going to 2380ca7a8e85SJeff Kirsher * write all over memory, enable bus mastering, and save our 2381ca7a8e85SJeff Kirsher * state for resuming after a suspend. 2382ca7a8e85SJeff Kirsher */ 2383ca7a8e85SJeff Kirsher pci_set_master(pdev); 2384ca7a8e85SJeff Kirsher pci_save_state(pdev); 2385ca7a8e85SJeff Kirsher 2386ca7a8e85SJeff Kirsher typhoon_init_interface(tp); 2387ca7a8e85SJeff Kirsher typhoon_init_rings(tp); 2388ca7a8e85SJeff Kirsher 2389ca7a8e85SJeff Kirsher if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) { 2390ca7a8e85SJeff Kirsher err_msg = "cannot boot 3XP sleep image"; 2391ca7a8e85SJeff Kirsher err = -EIO; 2392ca7a8e85SJeff Kirsher goto error_out_reset; 2393ca7a8e85SJeff Kirsher } 2394ca7a8e85SJeff Kirsher 2395ca7a8e85SJeff Kirsher INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_MAC_ADDRESS); 2396ca7a8e85SJeff Kirsher if(typhoon_issue_command(tp, 1, &xp_cmd, 1, xp_resp) < 0) { 2397ca7a8e85SJeff Kirsher err_msg = "cannot read MAC address"; 2398ca7a8e85SJeff Kirsher err = -EIO; 2399ca7a8e85SJeff Kirsher goto error_out_reset; 2400ca7a8e85SJeff Kirsher } 2401ca7a8e85SJeff Kirsher 2402ca7a8e85SJeff Kirsher *(__be16 *)&dev->dev_addr[0] = htons(le16_to_cpu(xp_resp[0].parm1)); 2403ca7a8e85SJeff Kirsher *(__be32 *)&dev->dev_addr[2] = htonl(le32_to_cpu(xp_resp[0].parm2)); 2404ca7a8e85SJeff Kirsher 2405ca7a8e85SJeff Kirsher if(!is_valid_ether_addr(dev->dev_addr)) { 2406ca7a8e85SJeff Kirsher err_msg = "Could not obtain valid ethernet address, aborting"; 2407ca7a8e85SJeff Kirsher goto error_out_reset; 2408ca7a8e85SJeff Kirsher } 2409ca7a8e85SJeff Kirsher 2410ca7a8e85SJeff Kirsher /* Read the Sleep Image version last, so the response is valid 2411ca7a8e85SJeff Kirsher * later when we print out the version reported. 2412ca7a8e85SJeff Kirsher */ 2413ca7a8e85SJeff Kirsher INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_VERSIONS); 2414ca7a8e85SJeff Kirsher if(typhoon_issue_command(tp, 1, &xp_cmd, 3, xp_resp) < 0) { 2415ca7a8e85SJeff Kirsher err_msg = "Could not get Sleep Image version"; 2416ca7a8e85SJeff Kirsher goto error_out_reset; 2417ca7a8e85SJeff Kirsher } 2418ca7a8e85SJeff Kirsher 2419ca7a8e85SJeff Kirsher tp->capabilities = typhoon_card_info[card_id].capabilities; 2420ca7a8e85SJeff Kirsher tp->xcvr_select = TYPHOON_XCVR_AUTONEG; 2421ca7a8e85SJeff Kirsher 2422ca7a8e85SJeff Kirsher /* Typhoon 1.0 Sleep Images return one response descriptor to the 2423ca7a8e85SJeff Kirsher * READ_VERSIONS command. Those versions are OK after waking up 2424ca7a8e85SJeff Kirsher * from sleep without needing a reset. Typhoon 1.1+ Sleep Images 2425ca7a8e85SJeff Kirsher * seem to need a little extra help to get started. Since we don't 2426ca7a8e85SJeff Kirsher * know how to nudge it along, just kick it. 2427ca7a8e85SJeff Kirsher */ 2428ca7a8e85SJeff Kirsher if(xp_resp[0].numDesc != 0) 2429ca7a8e85SJeff Kirsher tp->capabilities |= TYPHOON_WAKEUP_NEEDS_RESET; 2430ca7a8e85SJeff Kirsher 2431ca7a8e85SJeff Kirsher if(typhoon_sleep(tp, PCI_D3hot, 0) < 0) { 2432ca7a8e85SJeff Kirsher err_msg = "cannot put adapter to sleep"; 2433ca7a8e85SJeff Kirsher err = -EIO; 2434ca7a8e85SJeff Kirsher goto error_out_reset; 2435ca7a8e85SJeff Kirsher } 2436ca7a8e85SJeff Kirsher 2437ca7a8e85SJeff Kirsher /* The chip-specific entries in the device structure. */ 2438ca7a8e85SJeff Kirsher dev->netdev_ops = &typhoon_netdev_ops; 2439ca7a8e85SJeff Kirsher netif_napi_add(dev, &tp->napi, typhoon_poll, 16); 2440ca7a8e85SJeff Kirsher dev->watchdog_timeo = TX_TIMEOUT; 2441ca7a8e85SJeff Kirsher 24427ad24ea4SWilfried Klaebe dev->ethtool_ops = &typhoon_ethtool_ops; 2443ca7a8e85SJeff Kirsher 2444ca7a8e85SJeff Kirsher /* We can handle scatter gather, up to 16 entries, and 2445ca7a8e85SJeff Kirsher * we can do IP checksumming (only version 4, doh...) 2446ca7a8e85SJeff Kirsher * 2447ca7a8e85SJeff Kirsher * There's no way to turn off the RX VLAN offloading and stripping 2448ca7a8e85SJeff Kirsher * on the current 3XP firmware -- it does not respect the offload 2449ca7a8e85SJeff Kirsher * settings -- so we only allow the user to toggle the TX processing. 2450ca7a8e85SJeff Kirsher */ 2451ca7a8e85SJeff Kirsher dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | 2452f646968fSPatrick McHardy NETIF_F_HW_VLAN_CTAG_TX; 2453ca7a8e85SJeff Kirsher dev->features = dev->hw_features | 2454f646968fSPatrick McHardy NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_RXCSUM; 2455ca7a8e85SJeff Kirsher 2456ca7a8e85SJeff Kirsher if(register_netdev(dev) < 0) { 2457ca7a8e85SJeff Kirsher err_msg = "unable to register netdev"; 2458ca7a8e85SJeff Kirsher goto error_out_reset; 2459ca7a8e85SJeff Kirsher } 2460ca7a8e85SJeff Kirsher 2461ca7a8e85SJeff Kirsher pci_set_drvdata(pdev, dev); 2462ca7a8e85SJeff Kirsher 2463ca7a8e85SJeff Kirsher netdev_info(dev, "%s at %s 0x%llx, %pM\n", 2464ca7a8e85SJeff Kirsher typhoon_card_info[card_id].name, 2465ca7a8e85SJeff Kirsher use_mmio ? "MMIO" : "IO", 2466ca7a8e85SJeff Kirsher (unsigned long long)pci_resource_start(pdev, use_mmio), 2467ca7a8e85SJeff Kirsher dev->dev_addr); 2468ca7a8e85SJeff Kirsher 2469ca7a8e85SJeff Kirsher /* xp_resp still contains the response to the READ_VERSIONS command. 2470ca7a8e85SJeff Kirsher * For debugging, let the user know what version he has. 2471ca7a8e85SJeff Kirsher */ 2472ca7a8e85SJeff Kirsher if(xp_resp[0].numDesc == 0) { 2473ca7a8e85SJeff Kirsher /* This is the Typhoon 1.0 type Sleep Image, last 16 bits 2474ca7a8e85SJeff Kirsher * of version is Month/Day of build. 2475ca7a8e85SJeff Kirsher */ 2476ca7a8e85SJeff Kirsher u16 monthday = le32_to_cpu(xp_resp[0].parm2) & 0xffff; 2477ca7a8e85SJeff Kirsher netdev_info(dev, "Typhoon 1.0 Sleep Image built %02u/%02u/2000\n", 2478ca7a8e85SJeff Kirsher monthday >> 8, monthday & 0xff); 2479ca7a8e85SJeff Kirsher } else if(xp_resp[0].numDesc == 2) { 2480ca7a8e85SJeff Kirsher /* This is the Typhoon 1.1+ type Sleep Image 2481ca7a8e85SJeff Kirsher */ 2482ca7a8e85SJeff Kirsher u32 sleep_ver = le32_to_cpu(xp_resp[0].parm2); 2483ca7a8e85SJeff Kirsher u8 *ver_string = (u8 *) &xp_resp[1]; 2484ca7a8e85SJeff Kirsher ver_string[25] = 0; 2485ca7a8e85SJeff Kirsher netdev_info(dev, "Typhoon 1.1+ Sleep Image version %02x.%03x.%03x %s\n", 2486ca7a8e85SJeff Kirsher sleep_ver >> 24, (sleep_ver >> 12) & 0xfff, 2487ca7a8e85SJeff Kirsher sleep_ver & 0xfff, ver_string); 2488ca7a8e85SJeff Kirsher } else { 2489ca7a8e85SJeff Kirsher netdev_warn(dev, "Unknown Sleep Image version (%u:%04x)\n", 2490ca7a8e85SJeff Kirsher xp_resp[0].numDesc, le32_to_cpu(xp_resp[0].parm2)); 2491ca7a8e85SJeff Kirsher } 2492ca7a8e85SJeff Kirsher 2493ca7a8e85SJeff Kirsher return 0; 2494ca7a8e85SJeff Kirsher 2495ca7a8e85SJeff Kirsher error_out_reset: 2496ca7a8e85SJeff Kirsher typhoon_reset(ioaddr, NoWait); 2497ca7a8e85SJeff Kirsher 2498ca7a8e85SJeff Kirsher error_out_dma: 2499ca7a8e85SJeff Kirsher pci_free_consistent(pdev, sizeof(struct typhoon_shared), 2500ca7a8e85SJeff Kirsher shared, shared_dma); 2501ca7a8e85SJeff Kirsher error_out_remap: 2502ca7a8e85SJeff Kirsher pci_iounmap(pdev, ioaddr); 2503ca7a8e85SJeff Kirsher error_out_regions: 2504ca7a8e85SJeff Kirsher pci_release_regions(pdev); 2505ca7a8e85SJeff Kirsher error_out_mwi: 2506ca7a8e85SJeff Kirsher pci_clear_mwi(pdev); 2507ca7a8e85SJeff Kirsher error_out_disable: 2508ca7a8e85SJeff Kirsher pci_disable_device(pdev); 2509ca7a8e85SJeff Kirsher error_out_dev: 2510ca7a8e85SJeff Kirsher free_netdev(dev); 2511ca7a8e85SJeff Kirsher error_out: 2512ca7a8e85SJeff Kirsher pr_err("%s: %s\n", pci_name(pdev), err_msg); 2513ca7a8e85SJeff Kirsher return err; 2514ca7a8e85SJeff Kirsher } 2515ca7a8e85SJeff Kirsher 251621cf689bSBill Pemberton static void 2517ca7a8e85SJeff Kirsher typhoon_remove_one(struct pci_dev *pdev) 2518ca7a8e85SJeff Kirsher { 2519ca7a8e85SJeff Kirsher struct net_device *dev = pci_get_drvdata(pdev); 2520ca7a8e85SJeff Kirsher struct typhoon *tp = netdev_priv(dev); 2521ca7a8e85SJeff Kirsher 2522ca7a8e85SJeff Kirsher unregister_netdev(dev); 2523ca7a8e85SJeff Kirsher pci_set_power_state(pdev, PCI_D0); 2524ca7a8e85SJeff Kirsher pci_restore_state(pdev); 2525ca7a8e85SJeff Kirsher typhoon_reset(tp->ioaddr, NoWait); 2526ca7a8e85SJeff Kirsher pci_iounmap(pdev, tp->ioaddr); 2527ca7a8e85SJeff Kirsher pci_free_consistent(pdev, sizeof(struct typhoon_shared), 2528ca7a8e85SJeff Kirsher tp->shared, tp->shared_dma); 2529ca7a8e85SJeff Kirsher pci_release_regions(pdev); 2530ca7a8e85SJeff Kirsher pci_clear_mwi(pdev); 2531ca7a8e85SJeff Kirsher pci_disable_device(pdev); 2532ca7a8e85SJeff Kirsher free_netdev(dev); 2533ca7a8e85SJeff Kirsher } 2534ca7a8e85SJeff Kirsher 2535ca7a8e85SJeff Kirsher static struct pci_driver typhoon_driver = { 2536ca7a8e85SJeff Kirsher .name = KBUILD_MODNAME, 2537ca7a8e85SJeff Kirsher .id_table = typhoon_pci_tbl, 2538ca7a8e85SJeff Kirsher .probe = typhoon_init_one, 253921cf689bSBill Pemberton .remove = typhoon_remove_one, 2540ca7a8e85SJeff Kirsher #ifdef CONFIG_PM 2541ca7a8e85SJeff Kirsher .suspend = typhoon_suspend, 2542ca7a8e85SJeff Kirsher .resume = typhoon_resume, 2543ca7a8e85SJeff Kirsher #endif 2544ca7a8e85SJeff Kirsher }; 2545ca7a8e85SJeff Kirsher 2546ca7a8e85SJeff Kirsher static int __init 2547ca7a8e85SJeff Kirsher typhoon_init(void) 2548ca7a8e85SJeff Kirsher { 2549ca7a8e85SJeff Kirsher return pci_register_driver(&typhoon_driver); 2550ca7a8e85SJeff Kirsher } 2551ca7a8e85SJeff Kirsher 2552ca7a8e85SJeff Kirsher static void __exit 2553ca7a8e85SJeff Kirsher typhoon_cleanup(void) 2554ca7a8e85SJeff Kirsher { 2555ca7a8e85SJeff Kirsher release_firmware(typhoon_fw); 2556ca7a8e85SJeff Kirsher pci_unregister_driver(&typhoon_driver); 2557ca7a8e85SJeff Kirsher } 2558ca7a8e85SJeff Kirsher 2559ca7a8e85SJeff Kirsher module_init(typhoon_init); 2560ca7a8e85SJeff Kirsher module_exit(typhoon_cleanup); 2561