From: Andy Gospodarek <gospo@redhat.com> Subject: [RHEL5.1 PATCH] tg3: update to driver version 3.77 Date: Mon, 4 Jun 2007 13:51:35 -0400 Bugzilla: 225466 228125 Message-Id: <20070604175134.GH5927@gospo.rdu.redhat.com> Changelog: [net] tg3: update to driver version 3.77 This is an update to the tg3 driver that brings the RHEL5 version of the driver to 3.76. It includes several bug fixes as well as support for some new hardware that partners will be shipping before 5.2 is released. This resolves at least BZ 225466 and 228125 (probably a few others as well) and I've gotten positive feedback from customers/partners. --- drivers/net/tg3.c | 1290 ++++++++++++++++++++++++++++++----------------- drivers/net/tg3.h | 76 ++ include/linux/pci_ids.h | 5 include/linux/pci_regs.h | 1 4 files changed, 909 insertions(+), 463 deletions(-) --- linux-2.6.18.x86_64/drivers/net/tg3.c.gospo 2007-05-24 14:50:12.676901000 -0400 +++ linux-2.6.18.x86_64/drivers/net/tg3.c 2007-05-24 14:50:41.755794000 -0400 @@ -4,7 +4,7 @@ * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com) * Copyright (C) 2004 Sun Microsystems Inc. - * Copyright (C) 2005 Broadcom Corporation. + * Copyright (C) 2005-2007 Broadcom Corporation. * * Firmware is: * Derived from proprietary unpublished source code, @@ -46,10 +46,9 @@ #include <asm/byteorder.h> #include <asm/uaccess.h> -#ifdef CONFIG_SPARC64 +#ifdef CONFIG_SPARC #include <asm/idprom.h> -#include <asm/oplib.h> -#include <asm/pbm.h> +#include <asm/prom.h> #endif #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) @@ -58,18 +57,14 @@ #define TG3_VLAN_TAG_USED 0 #endif -#ifdef NETIF_F_TSO #define TG3_TSO_SUPPORT 1 -#else -#define TG3_TSO_SUPPORT 0 -#endif #include "tg3.h" #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.65-rh" -#define DRV_MODULE_RELDATE "November 20, 2006" +#define DRV_MODULE_VERSION "3.76" +#define DRV_MODULE_RELDATE "May 5, 2007" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -129,7 +124,7 @@ #define RX_JUMBO_PKT_BUF_SZ (9046 + tp->rx_offset + 64) /* minimum number of free TX descriptors required to wake up TX process */ -#define TG3_TX_WAKEUP_THRESH (TG3_TX_RING_SIZE / 4) +#define TG3_TX_WAKEUP_THRESH(tp) ((tp)->tx_pending / 4) /* number of ETHTOOL_GSTATS u64's */ #define TG3_NUM_STATS (sizeof(struct tg3_ethtool_stats)/sizeof(u64)) @@ -235,6 +230,8 @@ static struct pci_device_id tg3_pci_tbl[ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787M, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787F, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714S, @@ -268,7 +265,7 @@ static struct pci_device_id tg3_pci_tbl[ MODULE_DEVICE_TABLE(pci, tg3_pci_tbl); -static struct { +static const struct { const char string[ETH_GSTRING_LEN]; } ethtool_stats_keys[TG3_NUM_STATS] = { { "rx_octets" }, @@ -349,7 +346,7 @@ static struct { { "nic_tx_threshold_hit" } }; -static struct { +static const struct { const char string[ETH_GSTRING_LEN]; } ethtool_test_keys[TG3_NUM_TEST] = { { "nvram test (online) " }, @@ -367,7 +364,7 @@ static void tg3_write32(struct tg3 *tp, static u32 tg3_read32(struct tg3 *tp, u32 off) { - return (readl(tp->regs + off)); + return (readl(tp->regs + off)); } static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) @@ -483,6 +480,16 @@ static void tg3_write32_tx_mbox(struct t readl(mbox); } +static u32 tg3_read32_mbox_5906(struct tg3 *tp, u32 off) +{ + return (readl(tp->regs + off + GRCMBOX_BASE)); +} + +static void tg3_write32_mbox_5906(struct tg3 *tp, u32 off, u32 val) +{ + writel(val, tp->regs + off + GRCMBOX_BASE); +} + #define tw32_mailbox(reg, val) tp->write32_mbox(tp, reg, val) #define tw32_mailbox_f(reg, val) tw32_mailbox_flush(tp, (reg), (val)) #define tw32_rx_mbox(reg, val) tp->write32_rx_mbox(tp, reg, val) @@ -498,6 +505,10 @@ static void tg3_write_mem(struct tg3 *tp { unsigned long flags; + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) && + (off >= NIC_SRAM_STATS_BLK) && (off < NIC_SRAM_TX_BUFFER_DESC)) + return; + spin_lock_irqsave(&tp->indirect_lock, flags); if (tp->tg3_flags & TG3_FLAG_SRAM_USE_CONFIG) { pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); @@ -548,6 +559,9 @@ static inline void tg3_cond_int(struct t if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) && (tp->hw_status->status & SD_STATUS_UPDATED)) tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT); + else + tw32(HOSTCC_MODE, tp->coalesce_mode | + (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW)); } static void tg3_enable_ints(struct tg3 *tp) @@ -588,7 +602,7 @@ static inline unsigned int tg3_has_work( /* tg3_restart_ints * similar to tg3_enable_ints, but it accurately determines whether there * is new work pending and can return without flushing the PIO write - * which reenables interrupts + * which reenables interrupts */ static void tg3_restart_ints(struct tg3 *tp) { @@ -664,6 +678,10 @@ static int tg3_readphy(struct tg3 *tp, i unsigned int loops; int ret; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 && + (reg == MII_TG3_CTRL || reg == MII_TG3_AUX_CTRL)) + return 0; + if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) { tw32_f(MAC_MI_MODE, (tp->mi_mode & ~MAC_MI_MODE_AUTO_POLL)); @@ -677,7 +695,7 @@ static int tg3_readphy(struct tg3 *tp, i frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) & MI_COM_REG_ADDR_MASK); frame_val |= (MI_COM_CMD_READ | MI_COM_START); - + tw32_f(MAC_MI_COM, frame_val); loops = PHY_BUSY_LOOPS; @@ -725,7 +743,7 @@ static int tg3_writephy(struct tg3 *tp, MI_COM_REG_ADDR_MASK); frame_val |= (val & MI_COM_DATA_MASK); frame_val |= (MI_COM_CMD_WRITE | MI_COM_START); - + tw32_f(MAC_MI_COM, frame_val); loops = PHY_BUSY_LOOPS; @@ -986,6 +1004,13 @@ static int tg3_phy_reset(struct tg3 *tp) u32 phy_status; int err; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + u32 val; + + val = tr32(GRC_MISC_CFG); + tw32_f(GRC_MISC_CFG, val & ~GRC_MISC_CFG_EPHY_IDDQ); + udelay(40); + } err = tg3_readphy(tp, MII_BMSR, &phy_status); err |= tg3_readphy(tp, MII_BMSR, &phy_status); if (err != 0) @@ -1035,7 +1060,12 @@ out: else if (tp->tg3_flags2 & TG3_FLG2_PHY_JITTER_BUG) { tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00); tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a); - tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x010b); + if (tp->tg3_flags2 & TG3_FLG2_PHY_ADJUST_TRIM) { + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x110b); + tg3_writephy(tp, MII_TG3_TEST1, + MII_TG3_TEST1_TRIM_EN | 0x4); + } else + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x010b); tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400); } /* Set Extended packet length bit (bit 14) on all chips that */ @@ -1063,6 +1093,24 @@ out: phy_reg | MII_TG3_EXT_CTRL_FIFO_ELASTIC); } + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + u32 phy_reg; + + /* adjust output voltage */ + tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x12); + + if (!tg3_readphy(tp, MII_TG3_EPHY_TEST, &phy_reg)) { + u32 phy_reg2; + + tg3_writephy(tp, MII_TG3_EPHY_TEST, + phy_reg | MII_TG3_EPHY_SHADOW_EN); + /* Enable auto-MDIX */ + if (!tg3_readphy(tp, 0x10, &phy_reg2)) + tg3_writephy(tp, 0x10, phy_reg2 | 0x4000); + tg3_writephy(tp, MII_TG3_EPHY_TEST, phy_reg); + } + } + tg3_phy_set_wirespeed(tp); return 0; } @@ -1071,7 +1119,7 @@ static void tg3_frob_aux_power(struct tg { struct tg3 *tp_peer = tp; - if ((tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) != 0) + if ((tp->tg3_flags2 & TG3_FLG2_IS_NIC) == 0) return; if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) || @@ -1176,6 +1224,33 @@ static void tg3_nvram_unlock(struct tg3 static void tg3_power_down_phy(struct tg3 *tp) { + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { + u32 sg_dig_ctrl = tr32(SG_DIG_CTRL); + u32 serdes_cfg = tr32(MAC_SERDES_CFG); + + sg_dig_ctrl |= + SG_DIG_USING_HW_AUTONEG | SG_DIG_SOFT_RESET; + tw32(SG_DIG_CTRL, sg_dig_ctrl); + tw32(MAC_SERDES_CFG, serdes_cfg | (1 << 15)); + } + return; + } + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + u32 val; + + tg3_bmcr_reset(tp); + val = tr32(GRC_MISC_CFG); + tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ); + udelay(40); + return; + } else { + tg3_writephy(tp, MII_TG3_EXT_CTRL, + MII_TG3_EXT_CTRL_FORCE_LED_OFF); + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2); + } + /* The PHY should not be powered down on some chips because * of bugs. */ @@ -1213,8 +1288,8 @@ static int tg3_set_power_state(struct tg power_control); udelay(100); /* Delay after power state change */ - /* Switch out of Vaux if it is not a LOM */ - if (!(tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT)) + /* Switch out of Vaux if it is a NIC */ + if (tp->tg3_flags2 & TG3_FLG2_IS_NIC) tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 100); return 0; @@ -1258,7 +1333,12 @@ static int tg3_set_power_state(struct tg tg3_setup_phy(tp, 0); } - if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + u32 val; + + val = tr32(GRC_VCPU_EXT_CTRL); + tw32(GRC_VCPU_EXT_CTRL, val | GRC_VCPU_EXT_CTRL_DISABLE_WOL); + } else if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { int i; u32 val; @@ -1269,9 +1349,11 @@ static int tg3_set_power_state(struct tg msleep(1); } } - tg3_write_mem(tp, NIC_SRAM_WOL_MBOX, WOL_SIGNATURE | - WOL_DRV_STATE_SHUTDOWN | - WOL_DRV_WOL | WOL_SET_MAGIC_PKT); + if (tp->tg3_flags & TG3_FLAG_WOL_CAP) + tg3_write_mem(tp, NIC_SRAM_WOL_MBOX, WOL_SIGNATURE | + WOL_DRV_STATE_SHUTDOWN | + WOL_DRV_WOL | + WOL_SET_MAGIC_PKT); pci_read_config_word(tp->pdev, pm + PCI_PM_PMC, &power_caps); @@ -1282,7 +1364,10 @@ static int tg3_set_power_state(struct tg tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a); udelay(40); - mac_mode = MAC_MODE_PORT_MODE_MII; + if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) + mac_mode = MAC_MODE_PORT_MODE_GMII; + else + mac_mode = MAC_MODE_PORT_MODE_MII; if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 || !(tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB)) @@ -1316,7 +1401,8 @@ static int tg3_set_power_state(struct tg tw32_wait_f(TG3PCI_CLOCK_CTRL, base_val | CLOCK_CTRL_ALTCLK | CLOCK_CTRL_PWRDOWN_PLL133, 40); - } else if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) { + } else if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)) { /* do nothing */ } else if (!((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) && (tp->tg3_flags & TG3_FLAG_ENABLE_ASF))) { @@ -1360,15 +1446,8 @@ static int tg3_set_power_state(struct tg } if (!(tp->tg3_flags & TG3_FLAG_WOL_ENABLE) && - !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { - /* Turn off the PHY */ - if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { - tg3_writephy(tp, MII_TG3_EXT_CTRL, - MII_TG3_EXT_CTRL_FORCE_LED_OFF); - tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2); - tg3_power_down_phy(tp); - } - } + !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) + tg3_power_down_phy(tp); tg3_frob_aux_power(tp); @@ -1401,8 +1480,10 @@ static int tg3_set_power_state(struct tg static void tg3_link_report(struct tg3 *tp) { if (!netif_carrier_ok(tp->dev)) { - printk(KERN_INFO PFX "%s: Link is down.\n", tp->dev->name); - } else { + if (netif_msg_link(tp)) + printk(KERN_INFO PFX "%s: Link is down.\n", + tp->dev->name); + } else if (netif_msg_link(tp)) { printk(KERN_INFO PFX "%s: Link is up at %d Mbps, %s duplex.\n", tp->dev->name, (tp->link_config.active_speed == SPEED_1000 ? @@ -1481,7 +1562,7 @@ static void tg3_setup_flow_control(struc if (old_rx_mode != tp->rx_mode) { tw32_f(MAC_RX_MODE, tp->rx_mode); } - + if (new_tg3_flags & TG3_FLAG_TX_PAUSE) tp->tx_mode |= TX_MODE_FLOW_CTRL_ENABLE; else @@ -1526,6 +1607,13 @@ static void tg3_aux_stat_to_speed_duplex break; default: + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + *speed = (val & MII_TG3_AUX_STAT_100) ? SPEED_100 : + SPEED_10; + *duplex = (val & MII_TG3_AUX_STAT_FULL) ? DUPLEX_FULL : + DUPLEX_HALF; + break; + } *speed = SPEED_INVALID; *duplex = DUPLEX_INVALID; break; @@ -1550,12 +1638,6 @@ static void tg3_phy_copper_begin(struct tg3_writephy(tp, MII_ADVERTISE, new_adv); } else if (tp->link_config.speed == SPEED_INVALID) { - tp->link_config.advertising = - (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | - ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full | - ADVERTISED_Autoneg | ADVERTISED_MII); - if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) tp->link_config.advertising &= ~(ADVERTISED_1000baseT_Half | @@ -1699,25 +1781,36 @@ static int tg3_init_5401phy_dsp(struct t return err; } -static int tg3_copper_is_advertising_all(struct tg3 *tp) +static int tg3_copper_is_advertising_all(struct tg3 *tp, u32 mask) { - u32 adv_reg, all_mask; + u32 adv_reg, all_mask = 0; + + if (mask & ADVERTISED_10baseT_Half) + all_mask |= ADVERTISE_10HALF; + if (mask & ADVERTISED_10baseT_Full) + all_mask |= ADVERTISE_10FULL; + if (mask & ADVERTISED_100baseT_Half) + all_mask |= ADVERTISE_100HALF; + if (mask & ADVERTISED_100baseT_Full) + all_mask |= ADVERTISE_100FULL; if (tg3_readphy(tp, MII_ADVERTISE, &adv_reg)) return 0; - all_mask = (ADVERTISE_10HALF | ADVERTISE_10FULL | - ADVERTISE_100HALF | ADVERTISE_100FULL); if ((adv_reg & all_mask) != all_mask) return 0; if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) { u32 tg3_ctrl; + all_mask = 0; + if (mask & ADVERTISED_1000baseT_Half) + all_mask |= ADVERTISE_1000HALF; + if (mask & ADVERTISED_1000baseT_Full) + all_mask |= ADVERTISE_1000FULL; + if (tg3_readphy(tp, MII_TG3_CTRL, &tg3_ctrl)) return 0; - all_mask = (MII_TG3_CTRL_ADV_1000_HALF | - MII_TG3_CTRL_ADV_1000_FULL); if ((tg3_ctrl & all_mask) != all_mask) return 0; } @@ -1808,7 +1901,7 @@ static int tg3_setup_copper_phy(struct t if (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) tg3_writephy(tp, MII_TG3_IMASK, ~MII_TG3_INT_LINKCHG); - else + else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) tg3_writephy(tp, MII_TG3_IMASK, ~0); if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || @@ -1877,7 +1970,8 @@ static int tg3_setup_copper_phy(struct t /* Force autoneg restart if we are exiting * low power mode. */ - if (!tg3_copper_is_advertising_all(tp)) + if (!tg3_copper_is_advertising_all(tp, + tp->link_config.advertising)) current_link_up = 0; } else { current_link_up = 0; @@ -2465,24 +2559,27 @@ static int tg3_setup_fiber_hw_autoneg(st expected_sg_dig_ctrl |= (1 << 12); if (sg_dig_ctrl != expected_sg_dig_ctrl) { + if ((tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT) && + tp->serdes_counter && + ((mac_status & (MAC_STATUS_PCS_SYNCED | + MAC_STATUS_RCVD_CFG)) == + MAC_STATUS_PCS_SYNCED)) { + tp->serdes_counter--; + current_link_up = 1; + goto out; + } +restart_autoneg: if (workaround) tw32_f(MAC_SERDES_CFG, serdes_cfg | 0xc011000); tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl | (1 << 30)); udelay(5); tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl); - tp->tg3_flags2 |= TG3_FLG2_PHY_JUST_INITTED; + tp->serdes_counter = SERDES_AN_TIMEOUT_5704S; + tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT; } else if (mac_status & (MAC_STATUS_PCS_SYNCED | MAC_STATUS_SIGNAL_DET)) { - int i; - - /* Giver time to negotiate (~200ms) */ - for (i = 0; i < 40000; i++) { - sg_dig_status = tr32(SG_DIG_STATUS); - if (sg_dig_status & (0x3)) - break; - udelay(5); - } + sg_dig_status = tr32(SG_DIG_STATUS); mac_status = tr32(MAC_STATUS); if ((sg_dig_status & (1 << 1)) && @@ -2498,10 +2595,11 @@ static int tg3_setup_fiber_hw_autoneg(st tg3_setup_flow_control(tp, local_adv, remote_adv); current_link_up = 1; - tp->tg3_flags2 &= ~TG3_FLG2_PHY_JUST_INITTED; + tp->serdes_counter = 0; + tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT; } else if (!(sg_dig_status & (1 << 1))) { - if (tp->tg3_flags2 & TG3_FLG2_PHY_JUST_INITTED) - tp->tg3_flags2 &= ~TG3_FLG2_PHY_JUST_INITTED; + if (tp->serdes_counter) + tp->serdes_counter--; else { if (workaround) { u32 val = serdes_cfg; @@ -2525,9 +2623,17 @@ static int tg3_setup_fiber_hw_autoneg(st !(mac_status & MAC_STATUS_RCVD_CFG)) { tg3_setup_flow_control(tp, 0, 0); current_link_up = 1; - } + tp->tg3_flags2 |= + TG3_FLG2_PARALLEL_DETECT; + tp->serdes_counter = + SERDES_PARALLEL_DET_TIMEOUT; + } else + goto restart_autoneg; } } + } else { + tp->serdes_counter = SERDES_AN_TIMEOUT_5704S; + tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT; } out: @@ -2538,15 +2644,13 @@ static int tg3_setup_fiber_by_hand(struc { int current_link_up = 0; - if (!(mac_status & MAC_STATUS_PCS_SYNCED)) { - tp->tg3_flags &= ~TG3_FLAG_GOT_SERDES_FLOWCTL; + if (!(mac_status & MAC_STATUS_PCS_SYNCED)) goto out; - } if (tp->link_config.autoneg == AUTONEG_ENABLE) { u32 flags; int i; - + if (fiber_autoneg(tp, &flags)) { u32 local_adv, remote_adv; @@ -2559,7 +2663,6 @@ static int tg3_setup_fiber_by_hand(struc tg3_setup_flow_control(tp, local_adv, remote_adv); - tp->tg3_flags |= TG3_FLAG_GOT_SERDES_FLOWCTL; current_link_up = 1; } for (i = 0; i < 30; i++) { @@ -2582,7 +2685,6 @@ static int tg3_setup_fiber_by_hand(struc } else { /* Forcing 1000FD link up. */ current_link_up = 1; - tp->tg3_flags |= TG3_FLAG_GOT_SERDES_FLOWCTL; tw32_f(MAC_MODE, (tp->mac_mode | MAC_MODE_SEND_CONFIGS)); udelay(40); @@ -2658,14 +2760,16 @@ static int tg3_setup_fiber_phy(struct tg MAC_STATUS_CFG_CHANGED)); udelay(5); if ((tr32(MAC_STATUS) & (MAC_STATUS_SYNC_CHANGED | - MAC_STATUS_CFG_CHANGED)) == 0) + MAC_STATUS_CFG_CHANGED | + MAC_STATUS_LNKSTATE_CHANGED)) == 0) break; } mac_status = tr32(MAC_STATUS); if ((mac_status & MAC_STATUS_PCS_SYNCED) == 0) { current_link_up = 0; - if (tp->link_config.autoneg == AUTONEG_ENABLE) { + if (tp->link_config.autoneg == AUTONEG_ENABLE && + tp->serdes_counter == 0) { tw32_f(MAC_MODE, (tp->mac_mode | MAC_MODE_SEND_CONFIGS)); udelay(1); @@ -2770,7 +2874,7 @@ static int tg3_setup_fiber_mii_phy(struc tg3_writephy(tp, MII_BMCR, bmcr); tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED); - tp->tg3_flags2 |= TG3_FLG2_PHY_JUST_INITTED; + tp->serdes_counter = SERDES_AN_TIMEOUT_5714S; tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT; return err; @@ -2875,9 +2979,9 @@ static int tg3_setup_fiber_mii_phy(struc static void tg3_serdes_parallel_detect(struct tg3 *tp) { - if (tp->tg3_flags2 & TG3_FLG2_PHY_JUST_INITTED) { + if (tp->serdes_counter) { /* Give autoneg time to complete. */ - tp->tg3_flags2 &= ~TG3_FLG2_PHY_JUST_INITTED; + tp->serdes_counter--; return; } if (!netif_carrier_ok(tp->dev) && @@ -2964,6 +3068,16 @@ static int tg3_setup_phy(struct tg3 *tp, } } + if (tp->tg3_flags & TG3_FLAG_ASPM_WORKAROUND) { + u32 val = tr32(PCIE_PWR_MGMT_THRESH); + if (!netif_carrier_ok(tp->dev)) + val = (val & ~PCIE_PWR_MGMT_L1_THRESH_MSK) | + tp->pwrmgmt_thresh; + else + val |= PCIE_PWR_MGMT_L1_THRESH_MSK; + tw32(PCIE_PWR_MGMT_THRESH, val); + } + return err; } @@ -3054,10 +3168,10 @@ static void tg3_tx(struct tg3 *tp) smp_mb(); if (unlikely(netif_queue_stopped(tp->dev) && - (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH))) { + (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp)))) { netif_tx_lock(tp->dev); if (netif_queue_stopped(tp->dev) && - (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH)) + (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp))) netif_wake_queue(tp->dev); netif_tx_unlock(tp->dev); } @@ -3262,7 +3376,7 @@ static int tg3_rx(struct tg3 *tp, int bu len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - 4; /* omit crc */ - if (len > RX_COPY_THRESHOLD + if (len > RX_COPY_THRESHOLD && tp->rx_offset == 2 /* rx_offset != 2 iff this is a 5701 card running * in PCI-X mode [see tg3_get_invariants()] */ @@ -3334,7 +3448,7 @@ next_pkt: } next_pkt_nopost: sw_idx++; - sw_idx %= TG3_RX_RCB_RING_SIZE(tp); + sw_idx &= (TG3_RX_RCB_RING_SIZE(tp) - 1); /* Refresh hw_idx to see if there is new work */ if (sw_idx == hw_idx) { @@ -3511,32 +3625,38 @@ static irqreturn_t tg3_interrupt(int irq * Reading the PCI State register will confirm whether the * interrupt is ours and will flush the status block. */ - if ((sblk->status & SD_STATUS_UPDATED) || - !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { - /* - * Writing any value to intr-mbox-0 clears PCI INTA# and - * chip-internal interrupt pending events. - * Writing non-zero to intr-mbox-0 additional tells the - * NIC to stop sending us irqs, engaging "in-intr-handler" - * event coalescing. - */ - tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, - 0x00000001); - if (tg3_irq_sync(tp)) + if (unlikely(!(sblk->status & SD_STATUS_UPDATED))) { + if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) || + (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { + handled = 0; goto out; - sblk->status &= ~SD_STATUS_UPDATED; - if (likely(tg3_has_work(tp))) { - prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); - netif_rx_schedule(dev); /* schedule NAPI poll */ - } else { - /* No work, shared interrupt perhaps? re-enable - * interrupts, and flush that PCI write - */ - tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, - 0x00000000); } - } else { /* shared interrupt */ - handled = 0; + } + + /* + * Writing any value to intr-mbox-0 clears PCI INTA# and + * chip-internal interrupt pending events. + * Writing non-zero to intr-mbox-0 additional tells the + * NIC to stop sending us irqs, engaging "in-intr-handler" + * event coalescing. + * + * Flush the mailbox to de-assert the IRQ immediately to prevent + * spurious interrupts. The flush impacts performance but + * excessive spurious interrupts can be worse in some cases. + */ + tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); + if (tg3_irq_sync(tp)) + goto out; + sblk->status &= ~SD_STATUS_UPDATED; + if (likely(tg3_has_work(tp))) { + prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); + netif_rx_schedule(dev); /* schedule NAPI poll */ + } else { + /* No work, shared interrupt perhaps? re-enable + * interrupts, and flush that PCI write + */ + tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, + 0x00000000); } out: return IRQ_RETVAL(handled); @@ -3554,31 +3674,37 @@ static irqreturn_t tg3_interrupt_tagged( * Reading the PCI State register will confirm whether the * interrupt is ours and will flush the status block. */ - if ((sblk->status_tag != tp->last_tag) || - !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { - /* - * writing any value to intr-mbox-0 clears PCI INTA# and - * chip-internal interrupt pending events. - * writing non-zero to intr-mbox-0 additional tells the - * NIC to stop sending us irqs, engaging "in-intr-handler" - * event coalescing. - */ - tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, - 0x00000001); - if (tg3_irq_sync(tp)) + if (unlikely(sblk->status_tag == tp->last_tag)) { + if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) || + (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { + handled = 0; goto out; - if (netif_rx_schedule_prep(dev)) { - prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); - /* Update last_tag to mark that this status has been - * seen. Because interrupt may be shared, we may be - * racing with tg3_poll(), so only update last_tag - * if tg3_poll() is not scheduled. - */ - tp->last_tag = sblk->status_tag; - __netif_rx_schedule(dev); } - } else { /* shared interrupt */ - handled = 0; + } + + /* + * writing any value to intr-mbox-0 clears PCI INTA# and + * chip-internal interrupt pending events. + * writing non-zero to intr-mbox-0 additional tells the + * NIC to stop sending us irqs, engaging "in-intr-handler" + * event coalescing. + * + * Flush the mailbox to de-assert the IRQ immediately to prevent + * spurious interrupts. The flush impacts performance but + * excessive spurious interrupts can be worse in some cases. + */ + tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); + if (tg3_irq_sync(tp)) + goto out; + if (netif_rx_schedule_prep(dev)) { + prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); + /* Update last_tag to mark that this status has been + * seen. Because interrupt may be shared, we may be + * racing with tg3_poll(), so only update last_tag + * if tg3_poll() is not scheduled. + */ + tp->last_tag = sblk->status_tag; + __netif_rx_schedule(dev); } out: return IRQ_RETVAL(handled); @@ -3594,8 +3720,7 @@ static irqreturn_t tg3_test_isr(int irq, if ((sblk->status & SD_STATUS_UPDATED) || !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { - tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, - 0x00000001); + tg3_disable_ints(tp); return IRQ_RETVAL(1); } return IRQ_RETVAL(0); @@ -3680,12 +3805,23 @@ out: tg3_full_unlock(tp); } +static void tg3_dump_short_state(struct tg3 *tp) +{ + printk(KERN_ERR PFX "DEBUG: MAC_TX_STATUS[%08x] MAC_RX_STATUS[%08x]\n", + tr32(MAC_TX_STATUS), tr32(MAC_RX_STATUS)); + printk(KERN_ERR PFX "DEBUG: RDMAC_STATUS[%08x] WDMAC_STATUS[%08x]\n", + tr32(RDMAC_STATUS), tr32(WDMAC_STATUS)); +} + static void tg3_tx_timeout(struct net_device *dev) { struct tg3 *tp = netdev_priv(dev); - printk(KERN_ERR PFX "%s: transmit timed out, resetting\n", - dev->name); + if (netif_msg_tx_err(tp)) { + printk(KERN_ERR PFX "%s: transmit timed out, resetting\n", + dev->name); + tg3_dump_short_state(tp); + } schedule_work(&tp->reset_task); } @@ -3824,10 +3960,8 @@ static int tg3_start_xmit(struct sk_buff entry = tp->tx_prod; base_flags = 0; -#if TG3_TSO_SUPPORT != 0 mss = 0; - if (skb->len > (tp->dev->mtu + ETH_HLEN) && - (mss = skb_shinfo(skb)->gso_size) != 0) { + if ((mss = skb_shinfo(skb)->gso_size) != 0) { int tcp_opt_len, ip_tcp_len; if (skb_header_cloned(skb) && @@ -3857,11 +3991,6 @@ static int tg3_start_xmit(struct sk_buff } else if (skb->ip_summed == CHECKSUM_HW) base_flags |= TXD_FLAG_TCPUDP_CSUM; -#else - mss = 0; - if (skb->ip_summed == CHECKSUM_HW) - base_flags |= TXD_FLAG_TCPUDP_CSUM; -#endif #if TG3_VLAN_TAG_USED if (tp->vlgrp != NULL && vlan_tx_tag_present(skb)) base_flags |= (TXD_FLAG_VLAN | @@ -3909,7 +4038,7 @@ static int tg3_start_xmit(struct sk_buff tp->tx_prod = entry; if (unlikely(tg3_tx_avail(tp) <= (MAX_SKB_FRAGS + 1))) { netif_stop_queue(dev); - if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH) + if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp)) netif_wake_queue(tp->dev); } @@ -3921,7 +4050,6 @@ out_unlock: return NETDEV_TX_OK; } -#if TG3_TSO_SUPPORT != 0 static int tg3_start_xmit_dma_bug(struct sk_buff *, struct net_device *); /* Use GSO to workaround a rare TSO bug that may be triggered when the @@ -3934,7 +4062,10 @@ static int tg3_tso_bug(struct tg3 *tp, s /* Estimate the number of fragments in the worst case */ if (unlikely(tg3_tx_avail(tp) <= (skb_shinfo(skb)->gso_segs * 3))) { netif_stop_queue(tp->dev); - return NETDEV_TX_BUSY; + if (tg3_tx_avail(tp) <= (skb_shinfo(skb)->gso_segs * 3)) + return NETDEV_TX_BUSY; + + netif_wake_queue(tp->dev); } segs = skb_gso_segment(skb, tp->dev->features & ~NETIF_F_TSO); @@ -3953,7 +4084,6 @@ tg3_tso_bug_end: return NETDEV_TX_OK; } -#endif /* hard_start_xmit for devices that have the 4G bug and/or 40-bit bug and * support TG3_FLG2_HW_TSO_1 or firmware TSO only. @@ -3987,10 +4117,8 @@ static int tg3_start_xmit_dma_bug(struct base_flags = 0; if (skb->ip_summed == CHECKSUM_HW) base_flags |= TXD_FLAG_TCPUDP_CSUM; -#if TG3_TSO_SUPPORT != 0 mss = 0; - if (skb->len > (tp->dev->mtu + ETH_HLEN) && - (mss = skb_shinfo(skb)->gso_size) != 0) { + if ((mss = skb_shinfo(skb)->gso_size) != 0) { int tcp_opt_len, ip_tcp_len, hdr_len; if (skb_header_cloned(skb) && @@ -4004,7 +4132,7 @@ static int tg3_start_xmit_dma_bug(struct hdr_len = ip_tcp_len + tcp_opt_len; if (unlikely((ETH_HLEN + hdr_len) > 80) && - (tp->tg3_flags2 & TG3_FLG2_HW_TSO_1_BUG)) + (tp->tg3_flags2 & TG3_FLG2_TSO_BUG)) return (tg3_tso_bug(tp, skb)); base_flags |= (TXD_FLAG_CPU_PRE_DMA | @@ -4042,9 +4170,6 @@ static int tg3_start_xmit_dma_bug(struct } } } -#else - mss = 0; -#endif #if TG3_VLAN_TAG_USED if (tp->vlgrp != NULL && vlan_tx_tag_present(skb)) base_flags |= (TXD_FLAG_VLAN | @@ -4124,7 +4249,7 @@ static int tg3_start_xmit_dma_bug(struct tp->tx_prod = entry; if (unlikely(tg3_tx_avail(tp) <= (MAX_SKB_FRAGS + 1))) { netif_stop_queue(dev); - if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH) + if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp)) netif_wake_queue(tp->dev); } @@ -4397,7 +4522,7 @@ static void tg3_free_consistent(struct t */ static int tg3_alloc_consistent(struct tg3 *tp) { - tp->rx_std_buffers = kmalloc((sizeof(struct ring_info) * + tp->rx_std_buffers = kzalloc((sizeof(struct ring_info) * (TG3_RX_RING_SIZE + TG3_RX_JUMBO_RING_SIZE)) + (sizeof(struct tx_ring_info) * @@ -4406,13 +4531,6 @@ static int tg3_alloc_consistent(struct t if (!tp->rx_std_buffers) return -ENOMEM; - memset(tp->rx_std_buffers, 0, - (sizeof(struct ring_info) * - (TG3_RX_RING_SIZE + - TG3_RX_JUMBO_RING_SIZE)) + - (sizeof(struct tx_ring_info) * - TG3_TX_RING_SIZE)); - tp->rx_jumbo_buffers = &tp->rx_std_buffers[TG3_RX_RING_SIZE]; tp->tx_buffers = (struct tx_ring_info *) &tp->rx_jumbo_buffers[TG3_RX_JUMBO_RING_SIZE]; @@ -4703,6 +4821,45 @@ static void tg3_write_sig_legacy(struct } } +static int tg3_poll_fw(struct tg3 *tp) +{ + int i; + u32 val; + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + /* Wait up to 20ms for init done. */ + for (i = 0; i < 200; i++) { + if (tr32(VCPU_STATUS) & VCPU_STATUS_INIT_DONE) + return 0; + udelay(100); + } + return -ENODEV; + } + + /* Wait for firmware initialization to complete. */ + for (i = 0; i < 100000; i++) { + tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); + if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) + break; + udelay(10); + } + + /* Chip might not be fitted with firmware. Some Sun onboard + * parts are configured like that. So don't signal the timeout + * of the above loop as an error, but do report the lack of + * running firmware once. + */ + if (i >= 100000 && + !(tp->tg3_flags2 & TG3_FLG2_NO_FWARE_REPORTED)) { + tp->tg3_flags2 |= TG3_FLG2_NO_FWARE_REPORTED; + + printk(KERN_INFO PFX "%s: No firmware running.\n", + tp->dev->name); + } + + return 0; +} + static void tg3_stop_fw(struct tg3 *); /* tp->lock is held. */ @@ -4710,7 +4867,7 @@ static int tg3_chip_reset(struct tg3 *tp { u32 val; void (*write_op)(struct tg3 *, u32, u32); - int i; + int err; tg3_nvram_lock(tp); @@ -4734,6 +4891,21 @@ static int tg3_chip_reset(struct tg3 *tp if (write_op == tg3_write_flush_reg32) tp->write32 = tg3_write32; + /* Prevent the irq handler from reading or writing PCI registers + * during chip reset when the memory enable bit in the PCI command + * register may be cleared. The chip does not generate interrupt + * at this time, but the irq handler may still be called due to irq + * sharing or irqpoll. + */ + tp->tg3_flags |= TG3_FLAG_CHIP_RESETTING; + if (tp->hw_status) { + tp->hw_status->status = 0; + tp->hw_status->status_tag = 0; + } + tp->last_tag = 0; + smp_mb(); + synchronize_irq(tp->pdev->irq); + /* do the reset */ val = GRC_MISC_CFG_CORECLK_RESET; @@ -4747,6 +4919,12 @@ static int tg3_chip_reset(struct tg3 *tp } } + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + tw32(VCPU_STATUS, tr32(VCPU_STATUS) | VCPU_STATUS_DRV_RESET); + tw32(GRC_VCPU_EXT_CTRL, + tr32(GRC_VCPU_EXT_CTRL) & ~GRC_VCPU_EXT_CTRL_HALT_CPU); + } + if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) val |= GRC_MISC_CFG_KEEP_GPHY_POWER; tw32(GRC_MISC_CFG, val); @@ -4809,6 +4987,8 @@ static int tg3_chip_reset(struct tg3 *tp pci_restore_state(tp->pdev); + tp->tg3_flags &= ~TG3_FLAG_CHIP_RESETTING; + /* Make sure PCI-X relaxed ordering bit is clear. */ pci_read_config_dword(tp->pdev, TG3PCI_X_CAPS, &val); val &= ~PCIX_CAPS_RELAXED_ORDERING; @@ -4870,26 +5050,9 @@ static int tg3_chip_reset(struct tg3 *tp tw32_f(MAC_MODE, 0); udelay(40); - /* Wait for firmware initialization to complete. */ - for (i = 0; i < 100000; i++) { - tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); - if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) - break; - udelay(10); - } - - /* Chip might not be fitted with firmare. Some Sun onboard - * parts are configured like that. So don't signal the timeout - * of the above loop as an error, but do report the lack of - * running firmware once. - */ - if (i >= 100000 && - !(tp->tg3_flags2 & TG3_FLG2_NO_FWARE_REPORTED)) { - tp->tg3_flags2 |= TG3_FLG2_NO_FWARE_REPORTED; - - printk(KERN_INFO PFX "%s: No firmware running.\n", - tp->dev->name); - } + err = tg3_poll_fw(tp); + if (err) + return err; if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && tp->pci_chip_rev_id != CHIPREV_ID_5750_A0) { @@ -4973,7 +5136,7 @@ static int tg3_halt(struct tg3 *tp, int #define TG3_FW_BSS_ADDR 0x08000a70 #define TG3_FW_BSS_LEN 0x10 -static u32 tg3FwText[(TG3_FW_TEXT_LEN / sizeof(u32)) + 1] = { +static const u32 tg3FwText[(TG3_FW_TEXT_LEN / sizeof(u32)) + 1] = { 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c1d0800, 0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100000, 0x0e000018, 0x00000000, 0x0000000d, 0x3c1d0800, 0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100034, @@ -5067,7 +5230,7 @@ static u32 tg3FwText[(TG3_FW_TEXT_LEN / 0x27bd0008, 0x03e00008, 0x00000000, 0x00000000, 0x00000000 }; -static u32 tg3FwRodata[(TG3_FW_RODATA_LEN / sizeof(u32)) + 1] = { +static const u32 tg3FwRodata[(TG3_FW_RODATA_LEN / sizeof(u32)) + 1] = { 0x35373031, 0x726c7341, 0x00000000, 0x00000000, 0x53774576, 0x656e7430, 0x00000000, 0x726c7045, 0x76656e74, 0x31000000, 0x556e6b6e, 0x45766e74, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x66617461, 0x6c457272, @@ -5095,6 +5258,12 @@ static int tg3_halt_cpu(struct tg3 *tp, BUG_ON(offset == TX_CPU_BASE && (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + u32 val = tr32(GRC_VCPU_EXT_CTRL); + + tw32(GRC_VCPU_EXT_CTRL, val | GRC_VCPU_EXT_CTRL_HALT_CPU); + return 0; + } if (offset == RX_CPU_BASE) { for (i = 0; i < 10000; i++) { tw32(offset + CPU_STATE, 0xffffffff); @@ -5132,13 +5301,13 @@ static int tg3_halt_cpu(struct tg3 *tp, struct fw_info { unsigned int text_base; unsigned int text_len; - u32 *text_data; + const u32 *text_data; unsigned int rodata_base; unsigned int rodata_len; - u32 *rodata_data; + const u32 *rodata_data; unsigned int data_base; unsigned int data_len; - u32 *data_data; + const u32 *data_data; }; /* tp->lock is held. */ @@ -5253,7 +5422,6 @@ static int tg3_load_5701_a0_firmware_fix return 0; } -#if TG3_TSO_SUPPORT != 0 #define TG3_TSO_FW_RELEASE_MAJOR 0x1 #define TG3_TSO_FW_RELASE_MINOR 0x6 @@ -5270,7 +5438,7 @@ static int tg3_load_5701_a0_firmware_fix #define TG3_TSO_FW_BSS_ADDR 0x08001b80 #define TG3_TSO_FW_BSS_LEN 0x894 -static u32 tg3TsoFwText[(TG3_TSO_FW_TEXT_LEN / 4) + 1] = { +static const u32 tg3TsoFwText[(TG3_TSO_FW_TEXT_LEN / 4) + 1] = { 0x0e000003, 0x00000000, 0x08001b24, 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c1d0800, 0x37bd4000, 0x03a0f021, 0x3c100800, 0x26100000, 0x0e000010, 0x00000000, 0x0000000d, 0x27bdffe0, 0x3c04fefe, @@ -5557,7 +5725,7 @@ static u32 tg3TsoFwText[(TG3_TSO_FW_TEXT 0xac470014, 0xac4a0018, 0x03e00008, 0xac4b001c, 0x00000000, 0x00000000, }; -static u32 tg3TsoFwRodata[] = { +static const u32 tg3TsoFwRodata[] = { 0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541, 0x00000000, 0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, 0x496e0000, 0x73746b6f, 0x66662a2a, 0x00000000, 0x53774576, 0x656e7430, 0x00000000, 0x00000000, @@ -5565,7 +5733,7 @@ static u32 tg3TsoFwRodata[] = { 0x00000000, }; -static u32 tg3TsoFwData[] = { +static const u32 tg3TsoFwData[] = { 0x00000000, 0x73746b6f, 0x66666c64, 0x5f76312e, 0x362e3000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -5587,7 +5755,7 @@ static u32 tg3TsoFwData[] = { #define TG3_TSO5_FW_BSS_ADDR 0x00010f50 #define TG3_TSO5_FW_BSS_LEN 0x88 -static u32 tg3Tso5FwText[(TG3_TSO5_FW_TEXT_LEN / 4) + 1] = { +static const u32 tg3Tso5FwText[(TG3_TSO5_FW_TEXT_LEN / 4) + 1] = { 0x0c004003, 0x00000000, 0x00010f04, 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c1d0001, 0x37bde000, 0x03a0f021, 0x3c100001, 0x26100000, 0x0c004010, 0x00000000, 0x0000000d, 0x27bdffe0, 0x3c04fefe, @@ -5746,14 +5914,14 @@ static u32 tg3Tso5FwText[(TG3_TSO5_FW_TE 0x00000000, 0x00000000, 0x00000000, }; -static u32 tg3Tso5FwRodata[(TG3_TSO5_FW_RODATA_LEN / 4) + 1] = { +static const u32 tg3Tso5FwRodata[(TG3_TSO5_FW_RODATA_LEN / 4) + 1] = { 0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541, 0x00000000, 0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, 0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, 0x00000000, 0x00000000, 0x66617461, 0x6c457272, 0x00000000, 0x00000000, 0x00000000, }; -static u32 tg3Tso5FwData[(TG3_TSO5_FW_DATA_LEN / 4) + 1] = { +static const u32 tg3Tso5FwData[(TG3_TSO5_FW_DATA_LEN / 4) + 1] = { 0x00000000, 0x73746b6f, 0x66666c64, 0x5f76312e, 0x322e3000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }; @@ -5830,10 +5998,9 @@ static int tg3_load_tso_firmware(struct return 0; } -#endif /* TG3_TSO_SUPPORT != 0 */ /* tp->lock is held. */ -static void __tg3_set_mac_addr(struct tg3 *tp) +static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1) { u32 addr_high, addr_low; int i; @@ -5845,6 +6012,8 @@ static void __tg3_set_mac_addr(struct tg (tp->dev->dev_addr[4] << 8) | (tp->dev->dev_addr[5] << 0)); for (i = 0; i < 4; i++) { + if (i == 1 && skip_mac_1) + continue; tw32(MAC_ADDR_0_HIGH + (i * 8), addr_high); tw32(MAC_ADDR_0_LOW + (i * 8), addr_low); } @@ -5871,7 +6040,7 @@ static int tg3_set_mac_addr(struct net_d { struct tg3 *tp = netdev_priv(dev); struct sockaddr *addr = p; - int err = 0; + int err = 0, skip_mac_1 = 0; if (!is_valid_ether_addr(addr->sa_data)) return -EINVAL; @@ -5882,22 +6051,21 @@ static int tg3_set_mac_addr(struct net_d return 0; if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { - /* Reset chip so that ASF can re-init any MAC addresses it - * needs. - */ - tg3_netif_stop(tp); - tg3_full_lock(tp, 1); + u32 addr0_high, addr0_low, addr1_high, addr1_low; - tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); - err = tg3_restart_hw(tp, 0); - if (!err) - tg3_netif_start(tp); - tg3_full_unlock(tp); - } else { - spin_lock_bh(&tp->lock); - __tg3_set_mac_addr(tp); - spin_unlock_bh(&tp->lock); + addr0_high = tr32(MAC_ADDR_0_HIGH); + addr0_low = tr32(MAC_ADDR_0_LOW); + addr1_high = tr32(MAC_ADDR_1_HIGH); + addr1_low = tr32(MAC_ADDR_1_LOW); + + /* Skip MAC addr 1 if ASF is using it. */ + if ((addr0_high != addr1_high || addr0_low != addr1_low) && + !(addr1_high == 0 && addr1_low == 0)) + skip_mac_1 = 1; } + spin_lock_bh(&tp->lock); + __tg3_set_mac_addr(tp, skip_mac_1); + spin_unlock_bh(&tp->lock); return err; } @@ -6044,7 +6212,6 @@ static int tg3_reset_hw(struct tg3 *tp, tw32(BUFMGR_DMA_DESC_POOL_ADDR, NIC_SRAM_DMA_DESC_POOL_BASE); tw32(BUFMGR_DMA_DESC_POOL_SIZE, NIC_SRAM_DMA_DESC_POOL_SIZE); } -#if TG3_TSO_SUPPORT != 0 else if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) { int fw_len; @@ -6059,7 +6226,6 @@ static int tg3_reset_hw(struct tg3 *tp, tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE5705 - fw_len - 0xa00); } -#endif if (tp->dev->mtu <= ETH_DATA_LEN) { tw32(BUFMGR_MB_RDMA_LOW_WATER, @@ -6099,6 +6265,13 @@ static int tg3_reset_hw(struct tg3 *tp, val = 1; else if (val > tp->rx_std_max_post) val = tp->rx_std_max_post; + else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + if (tp->pci_chip_rev_id == CHIPREV_ID_5906_A1) + tw32(ISO_PKT_TX, (tr32(ISO_PKT_TX) & ~0x3) | 0x2); + + if (val > (TG3_RX_INTERNAL_RING_SZ_5906 / 2)) + val = TG3_RX_INTERNAL_RING_SZ_5906 / 2; + } tw32(RCVBDI_STD_THRESH, val); @@ -6209,7 +6382,7 @@ static int tg3_reset_hw(struct tg3 *tp, tp->rx_jumbo_ptr); /* Initialize MAC address and backoff seed. */ - __tg3_set_mac_addr(tp); + __tg3_set_mac_addr(tp, 0); /* MTU + ethernet header + FCS + optional VLAN tag */ tw32(MAC_RX_MTU_SIZE, tp->dev->mtu + ETH_HLEN + 8); @@ -6234,16 +6407,13 @@ static int tg3_reset_hw(struct tg3 *tp, RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB | RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB | RDMAC_MODE_LNGREAD_ENAB); - if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) - rdmac_mode |= RDMAC_MODE_SPLIT_ENABLE; /* If statement applies to 5705 and 5750 PCI devices only */ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) || (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)) { if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE && - (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 || - tp->pci_chip_rev_id == CHIPREV_ID_5705_A2)) { + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { rdmac_mode |= RDMAC_MODE_FIFO_SIZE_128; } else if (!(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) && !(tp->tg3_flags2 & TG3_FLG2_IS_5788)) { @@ -6254,10 +6424,8 @@ static int tg3_reset_hw(struct tg3 *tp, if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST; -#if TG3_TSO_SUPPORT != 0 if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) rdmac_mode |= (1 << 27); -#endif /* Receive/send statistics. */ if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) { @@ -6336,16 +6504,17 @@ static int tg3_reset_hw(struct tg3 *tp, udelay(40); /* tp->grc_local_ctrl is partially set up during tg3_get_invariants(). - * If TG3_FLAG_EEPROM_WRITE_PROT is set, we should read the + * If TG3_FLG2_IS_NIC is zero, we should read the * register to preserve the GPIO settings for LOMs. The GPIOs, * whether used as inputs or outputs, are set by boot code after * reset. */ - if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) { + if (!(tp->tg3_flags2 & TG3_FLG2_IS_NIC)) { u32 gpio_mask; - gpio_mask = GRC_LCLCTRL_GPIO_OE0 | GRC_LCLCTRL_GPIO_OE2 | - GRC_LCLCTRL_GPIO_OUTPUT0 | GRC_LCLCTRL_GPIO_OUTPUT2; + gpio_mask = GRC_LCLCTRL_GPIO_OE0 | GRC_LCLCTRL_GPIO_OE1 | + GRC_LCLCTRL_GPIO_OE2 | GRC_LCLCTRL_GPIO_OUTPUT0 | + GRC_LCLCTRL_GPIO_OUTPUT1 | GRC_LCLCTRL_GPIO_OUTPUT2; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752) gpio_mask |= GRC_LCLCTRL_GPIO_OE3 | @@ -6354,11 +6523,13 @@ static int tg3_reset_hw(struct tg3 *tp, if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) gpio_mask |= GRC_LCLCTRL_GPIO_UART_SEL; + tp->grc_local_ctrl &= ~gpio_mask; tp->grc_local_ctrl |= tr32(GRC_LOCAL_CTRL) & gpio_mask; /* GPIO1 must be driven high for eeprom write protect */ - tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 | - GRC_LCLCTRL_GPIO_OUTPUT1); + if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) + tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 | + GRC_LCLCTRL_GPIO_OUTPUT1); } tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl); udelay(100); @@ -6408,9 +6579,6 @@ static int tg3_reset_hw(struct tg3 *tp, } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { val &= ~(PCIX_CAPS_SPLIT_MASK | PCIX_CAPS_BURST_MASK); val |= (PCIX_CAPS_MAX_BURST_CPIOB << PCIX_CAPS_BURST_SHIFT); - if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) - val |= (tp->split_mode_max_reqs << - PCIX_CAPS_SPLIT_SHIFT); } tw32(TG3PCI_X_CAPS, val); } @@ -6426,10 +6594,8 @@ static int tg3_reset_hw(struct tg3 *tp, tw32(RCVBDI_MODE, RCVBDI_MODE_ENABLE | RCVBDI_MODE_RCB_ATTN_ENAB); tw32(RCVDBDI_MODE, RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ); tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE); -#if TG3_TSO_SUPPORT != 0 if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE | 0x8); -#endif tw32(SNDBDI_MODE, SNDBDI_MODE_ENABLE | SNDBDI_MODE_ATTN_ENABLE); tw32(SNDBDS_MODE, SNDBDS_MODE_ENABLE | SNDBDS_MODE_ATTN_ENABLE); @@ -6439,13 +6605,11 @@ static int tg3_reset_hw(struct tg3 *tp, return err; } -#if TG3_TSO_SUPPORT != 0 if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) { err = tg3_load_tso_firmware(tp); if (err) return err; } -#endif tp->tx_mode = TX_MODE_ENABLE; tw32_f(MAC_TX_MODE, tp->tx_mode); @@ -6519,12 +6683,14 @@ static int tg3_reset_hw(struct tg3 *tp, if (err) return err; - if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { + if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) { u32 tmp; /* Clear CRC stats. */ - if (!tg3_readphy(tp, 0x1e, &tmp)) { - tg3_writephy(tp, 0x1e, tmp | 0x8000); + if (!tg3_readphy(tp, MII_TG3_TEST1, &tmp)) { + tg3_writephy(tp, MII_TG3_TEST1, + tmp | MII_TG3_TEST1_CRC_EN); tg3_readphy(tp, 0x14, &tmp); } } @@ -6719,12 +6885,14 @@ static void tg3_timer(unsigned long __op need_setup = 1; } if (need_setup) { - tw32_f(MAC_MODE, - (tp->mac_mode & - ~MAC_MODE_PORT_MODE_MASK)); - udelay(40); - tw32_f(MAC_MODE, tp->mac_mode); - udelay(40); + if (!tp->serdes_counter) { + tw32_f(MAC_MODE, + (tp->mac_mode & + ~MAC_MODE_PORT_MODE_MASK)); + udelay(40); + tw32_f(MAC_MODE, tp->mac_mode); + udelay(40); + } tg3_setup_phy(tp, 0); } } else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) @@ -6733,13 +6901,29 @@ static void tg3_timer(unsigned long __op tp->timer_counter = tp->timer_multiplier; } - /* Heartbeat is only sent once every 2 seconds. */ + /* Heartbeat is only sent once every 2 seconds. + * + * The heartbeat is to tell the ASF firmware that the host + * driver is still alive. In the event that the OS crashes, + * ASF needs to reset the hardware to free up the FIFO space + * that may be filled with rx packets destined for the host. + * If the FIFO is full, ASF will no longer function properly. + * + * Unintended resets have been reported on real time kernels + * where the timer doesn't run on time. Netpoll will also have + * same problem. + * + * The new FWCMD_NICDRV_ALIVE3 command tells the ASF firmware + * to check the ring condition when the heartbeat is expiring + * before doing the reset. This will prevent most unintended + * resets. + */ if (!--tp->asf_counter) { if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { u32 val; tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, - FWCMD_NICDRV_ALIVE2); + FWCMD_NICDRV_ALIVE3); tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); /* 5 seconds timeout */ tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); @@ -6780,8 +6964,7 @@ static int tg3_request_irq(struct tg3 *t static int tg3_test_interrupt(struct tg3 *tp) { struct net_device *dev = tp->dev; - int err, i; - u32 int_mbox = 0; + int err, i, intr_ok = 0; if (!netif_running(dev)) return -ENODEV; @@ -6802,23 +6985,31 @@ static int tg3_test_interrupt(struct tg3 HOSTCC_MODE_NOW); for (i = 0; i < 5; i++) { + u32 int_mbox, misc_host_ctrl; + int_mbox = tr32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); - if (int_mbox != 0) + misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL); + + if ((int_mbox != 0) || + (misc_host_ctrl & MISC_HOST_CTRL_MASK_PCI_INT)) { + intr_ok = 1; break; + } + msleep(10); } tg3_disable_ints(tp); free_irq(tp->pdev->irq, dev); - + err = tg3_request_irq(tp); if (err) return err; - if (int_mbox != 0) + if (intr_ok) return 0; return -EIO; @@ -6890,11 +7081,15 @@ static int tg3_open(struct net_device *d struct tg3 *tp = netdev_priv(dev); int err; + netif_carrier_off(tp->dev); + tg3_full_lock(tp, 0); err = tg3_set_power_state(tp, PCI_D0); - if (err) + if (err) { + tg3_full_unlock(tp); return err; + } tg3_disable_ints(tp); tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; @@ -6908,11 +7103,7 @@ static int tg3_open(struct net_device *d if (err) return err; - if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) && - (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_AX) && - (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_BX) && - !((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) && - (tp->pdev_peer == tp->pdev))) { + if (tp->tg3_flags & TG3_FLAG_SUPPORT_MSI) { /* All MSI supporting chips should support tagged * status. Assert that this is the case. */ @@ -6995,9 +7186,10 @@ static int tg3_open(struct net_device *d if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI) { - u32 val = tr32(0x7c04); + u32 val = tr32(PCIE_TRANSACTION_CFG); - tw32(0x7c04, val | (1 << 29)); + tw32(PCIE_TRANSACTION_CFG, + val | PCIE_TRANS_CFG_1SHOT_MSI); } } } @@ -7270,9 +7462,7 @@ static int tg3_close(struct net_device * tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); tg3_free_rings(tp); - tp->tg3_flags &= - ~(TG3_FLAG_INIT_COMPLETE | - TG3_FLAG_GOT_SERDES_FLOWCTL); + tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; tg3_full_unlock(tp); @@ -7318,8 +7508,9 @@ static unsigned long calc_crc_errors(str u32 val; spin_lock_bh(&tp->lock); - if (!tg3_readphy(tp, 0x1e, &val)) { - tg3_writephy(tp, 0x1e, val | 0x8000); + if (!tg3_readphy(tp, MII_TG3_TEST1, &val)) { + tg3_writephy(tp, MII_TG3_TEST1, + val | MII_TG3_TEST1_CRC_EN); tg3_readphy(tp, 0x14, &val); } else val = 0; @@ -7439,7 +7630,7 @@ static struct net_device_stats *tg3_get_ get_stat64(&hw_stats->rx_ucast_packets) + get_stat64(&hw_stats->rx_mcast_packets) + get_stat64(&hw_stats->rx_bcast_packets); - + stats->tx_packets = old_stats->tx_packets + get_stat64(&hw_stats->tx_ucast_packets) + get_stat64(&hw_stats->tx_mcast_packets) + @@ -7747,7 +7938,7 @@ static int tg3_get_eeprom(struct net_dev return 0; } -static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf); +static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf); static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) { @@ -7811,7 +8002,7 @@ static int tg3_set_eeprom(struct net_dev static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct tg3 *tp = netdev_priv(dev); - + cmd->supported = (SUPPORTED_Autoneg); if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) @@ -7829,7 +8020,7 @@ static int tg3_get_settings(struct net_d cmd->supported |= SUPPORTED_FIBRE; cmd->port = PORT_FIBRE; } - + cmd->advertising = tp->link_config.advertising; if (netif_running(dev)) { cmd->speed = tp->link_config.active_speed; @@ -7842,12 +8033,12 @@ static int tg3_get_settings(struct net_d cmd->maxrxpkt = 0; return 0; } - + static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct tg3 *tp = netdev_priv(dev); - - if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) { + + if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) { /* These are the only valid advertisement bits allowed. */ if (cmd->autoneg == AUTONEG_ENABLE && (cmd->advertising & ~(ADVERTISED_1000baseT_Half | @@ -7879,70 +8070,75 @@ static int tg3_set_settings(struct net_d tp->link_config.speed = cmd->speed; tp->link_config.duplex = cmd->duplex; } - + + tp->link_config.orig_speed = tp->link_config.speed; + tp->link_config.orig_duplex = tp->link_config.duplex; + tp->link_config.orig_autoneg = tp->link_config.autoneg; + if (netif_running(dev)) tg3_setup_phy(tp, 1); tg3_full_unlock(tp); - + return 0; } - + static void tg3_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { struct tg3 *tp = netdev_priv(dev); - + strcpy(info->driver, DRV_MODULE_NAME); strcpy(info->version, DRV_MODULE_VERSION); strcpy(info->fw_version, tp->fw_ver); strcpy(info->bus_info, pci_name(tp->pdev)); } - + static void tg3_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct tg3 *tp = netdev_priv(dev); - - wol->supported = WAKE_MAGIC; + + if (tp->tg3_flags & TG3_FLAG_WOL_CAP) + wol->supported = WAKE_MAGIC; + else + wol->supported = 0; wol->wolopts = 0; if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) wol->wolopts = WAKE_MAGIC; memset(&wol->sopass, 0, sizeof(wol->sopass)); } - + static int tg3_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct tg3 *tp = netdev_priv(dev); - + if (wol->wolopts & ~WAKE_MAGIC) return -EINVAL; if ((wol->wolopts & WAKE_MAGIC) && - tp->tg3_flags2 & TG3_FLG2_PHY_SERDES && - !(tp->tg3_flags & TG3_FLAG_SERDES_WOL_CAP)) + !(tp->tg3_flags & TG3_FLAG_WOL_CAP)) return -EINVAL; - + spin_lock_bh(&tp->lock); if (wol->wolopts & WAKE_MAGIC) tp->tg3_flags |= TG3_FLAG_WOL_ENABLE; else tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE; spin_unlock_bh(&tp->lock); - + return 0; } - + static u32 tg3_get_msglevel(struct net_device *dev) { struct tg3 *tp = netdev_priv(dev); return tp->msg_enable; } - + static void tg3_set_msglevel(struct net_device *dev, u32 value) { struct tg3 *tp = netdev_priv(dev); tp->msg_enable = value; } - -#if TG3_TSO_SUPPORT != 0 + static int tg3_set_tso(struct net_device *dev, u32 value) { struct tg3 *tp = netdev_priv(dev); @@ -7952,7 +8148,8 @@ static int tg3_set_tso(struct net_device return -EINVAL; return 0; } - if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) { + if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) && + (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)) { if (value) dev->features |= NETIF_F_TSO6; else @@ -7960,14 +8157,13 @@ static int tg3_set_tso(struct net_device } return ethtool_op_set_tso(dev, value); } -#endif - + static int tg3_nway_reset(struct net_device *dev) { struct tg3 *tp = netdev_priv(dev); u32 bmcr; int r; - + if (!netif_running(dev)) return -EAGAIN; @@ -7985,14 +8181,14 @@ static int tg3_nway_reset(struct net_dev r = 0; } spin_unlock_bh(&tp->lock); - + return r; } - + static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) { struct tg3 *tp = netdev_priv(dev); - + ering->rx_max_pending = TG3_RX_RING_SIZE - 1; ering->rx_mini_max_pending = 0; if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) @@ -8011,24 +8207,27 @@ static void tg3_get_ringparam(struct net ering->tx_pending = tp->tx_pending; } - + static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) { struct tg3 *tp = netdev_priv(dev); int irq_sync = 0, err = 0; - + if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) || (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) || - (ering->tx_pending > TG3_TX_RING_SIZE - 1)) + (ering->tx_pending > TG3_TX_RING_SIZE - 1) || + (ering->tx_pending <= MAX_SKB_FRAGS) || + ((tp->tg3_flags2 & TG3_FLG2_TSO_BUG) && + (ering->tx_pending <= (MAX_SKB_FRAGS * 3)))) return -EINVAL; - + if (netif_running(dev)) { tg3_netif_stop(tp); irq_sync = 1; } tg3_full_lock(tp, irq_sync); - + tp->rx_pending = ering->rx_pending; if ((tp->tg3_flags2 & TG3_FLG2_MAX_RXPEND_64) && @@ -8045,24 +8244,24 @@ static int tg3_set_ringparam(struct net_ } tg3_full_unlock(tp); - + return err; } - + static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) { struct tg3 *tp = netdev_priv(dev); - + epause->autoneg = (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) != 0; epause->rx_pause = (tp->tg3_flags & TG3_FLAG_RX_PAUSE) != 0; epause->tx_pause = (tp->tg3_flags & TG3_FLAG_TX_PAUSE) != 0; } - + static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) { struct tg3 *tp = netdev_priv(dev); int irq_sync = 0, err = 0; - + if (netif_running(dev)) { tg3_netif_stop(tp); irq_sync = 1; @@ -8091,46 +8290,46 @@ static int tg3_set_pauseparam(struct net } tg3_full_unlock(tp); - + return err; } - + static u32 tg3_get_rx_csum(struct net_device *dev) { struct tg3 *tp = netdev_priv(dev); return (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0; } - + static int tg3_set_rx_csum(struct net_device *dev, u32 data) { struct tg3 *tp = netdev_priv(dev); - + if (tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) { if (data != 0) return -EINVAL; return 0; } - + spin_lock_bh(&tp->lock); if (data) tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS; else tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS; spin_unlock_bh(&tp->lock); - + return 0; } - + static int tg3_set_tx_csum(struct net_device *dev, u32 data) { struct tg3 *tp = netdev_priv(dev); - + if (tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) { if (data != 0) return -EINVAL; return 0; } - + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) ethtool_op_set_tx_hw_csum(dev, data); @@ -8185,7 +8384,7 @@ static int tg3_phys_id(struct net_device LED_CTRL_TRAFFIC_OVERRIDE | LED_CTRL_TRAFFIC_BLINK | LED_CTRL_TRAFFIC_LED); - + else tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE | LED_CTRL_TRAFFIC_OVERRIDE); @@ -8206,6 +8405,8 @@ static void tg3_get_ethtool_stats (struc #define NVRAM_TEST_SIZE 0x100 #define NVRAM_SELFBOOT_FORMAT1_SIZE 0x14 +#define NVRAM_SELFBOOT_HW_SIZE 0x20 +#define NVRAM_SELFBOOT_DATA_SIZE 0x1c static int tg3_test_nvram(struct tg3 *tp) { @@ -8217,12 +8418,14 @@ static int tg3_test_nvram(struct tg3 *tp if (magic == TG3_EEPROM_MAGIC) size = NVRAM_TEST_SIZE; - else if ((magic & 0xff000000) == 0xa5000000) { + else if ((magic & TG3_EEPROM_MAGIC_FW_MSK) == TG3_EEPROM_MAGIC_FW) { if ((magic & 0xe00000) == 0x200000) size = NVRAM_SELFBOOT_FORMAT1_SIZE; else return 0; - } else + } else if ((magic & TG3_EEPROM_MAGIC_HW_MSK) == TG3_EEPROM_MAGIC_HW) + size = NVRAM_SELFBOOT_HW_SIZE; + else return -EIO; buf = kmalloc(size, GFP_KERNEL); @@ -8241,7 +8444,8 @@ static int tg3_test_nvram(struct tg3 *tp goto out; /* Selfboot format */ - if (cpu_to_be32(buf[0]) != TG3_EEPROM_MAGIC) { + if ((cpu_to_be32(buf[0]) & TG3_EEPROM_MAGIC_FW_MSK) == + TG3_EEPROM_MAGIC_FW) { u8 *buf8 = (u8 *) buf, csum8 = 0; for (i = 0; i < size; i++) @@ -8256,6 +8460,51 @@ static int tg3_test_nvram(struct tg3 *tp goto out; } + if ((cpu_to_be32(buf[0]) & TG3_EEPROM_MAGIC_HW_MSK) == + TG3_EEPROM_MAGIC_HW) { + u8 data[NVRAM_SELFBOOT_DATA_SIZE]; + u8 parity[NVRAM_SELFBOOT_DATA_SIZE]; + u8 *buf8 = (u8 *) buf; + int j, k; + + /* Separate the parity bits and the data bytes. */ + for (i = 0, j = 0, k = 0; i < NVRAM_SELFBOOT_HW_SIZE; i++) { + if ((i == 0) || (i == 8)) { + int l; + u8 msk; + + for (l = 0, msk = 0x80; l < 7; l++, msk >>= 1) + parity[k++] = buf8[i] & msk; + i++; + } + else if (i == 16) { + int l; + u8 msk; + + for (l = 0, msk = 0x20; l < 6; l++, msk >>= 1) + parity[k++] = buf8[i] & msk; + i++; + + for (l = 0, msk = 0x80; l < 8; l++, msk >>= 1) + parity[k++] = buf8[i] & msk; + i++; + } + data[j++] = buf8[i]; + } + + err = -EIO; + for (i = 0; i < NVRAM_SELFBOOT_DATA_SIZE; i++) { + u8 hw8 = hweight8(data[i]); + + if ((hw8 & 0x1) && parity[i]) + goto out; + else if (!(hw8 & 0x1) && !parity[i]) + goto out; + } + err = 0; + goto out; + } + /* Bootstrap checksum at offset 0x10 */ csum = calc_crc((unsigned char *) buf, 0x10); if(csum != cpu_to_le32(buf[0x10/4])) @@ -8302,7 +8551,7 @@ static int tg3_test_link(struct tg3 *tp) /* Only test the commonly used registers */ static int tg3_test_registers(struct tg3 *tp) { - int i, is_5705; + int i, is_5705, is_5750; u32 offset, read_mask, write_mask, val, save_val, read_val; static struct { u16 offset; @@ -8310,6 +8559,7 @@ static int tg3_test_registers(struct tg3 #define TG3_FL_5705 0x1 #define TG3_FL_NOT_5705 0x2 #define TG3_FL_NOT_5788 0x4 +#define TG3_FL_NOT_5750 0x8 u32 read_mask; u32 write_mask; } reg_tbl[] = { @@ -8362,7 +8612,7 @@ static int tg3_test_registers(struct tg3 0x00000000, 0xffff0002 }, { RCVDBDI_STD_BD+0xc, 0x0000, 0x00000000, 0xffffffff }, - + /* Receive BD Initiator Control Registers. */ { RCVBDI_STD_THRESH, TG3_FL_NOT_5705, 0x00000000, 0xffffffff }, @@ -8370,7 +8620,7 @@ static int tg3_test_registers(struct tg3 0x00000000, 0x000003ff }, { RCVBDI_JUMBO_THRESH, TG3_FL_NOT_5705, 0x00000000, 0xffffffff }, - + /* Host Coalescing Control Registers. */ { HOSTCC_MODE, TG3_FL_NOT_5705, 0x00000000, 0x00000004 }, @@ -8420,9 +8670,9 @@ static int tg3_test_registers(struct tg3 0xffffffff, 0x00000000 }, /* Buffer Manager Control Registers. */ - { BUFMGR_MB_POOL_ADDR, 0x0000, + { BUFMGR_MB_POOL_ADDR, TG3_FL_NOT_5750, 0x00000000, 0x007fff80 }, - { BUFMGR_MB_POOL_SIZE, 0x0000, + { BUFMGR_MB_POOL_SIZE, TG3_FL_NOT_5750, 0x00000000, 0x007fffff }, { BUFMGR_MB_RDMA_LOW_WATER, 0x0000, 0x00000000, 0x0000003f }, @@ -8434,7 +8684,7 @@ static int tg3_test_registers(struct tg3 0xffffffff, 0x00000000 }, { BUFMGR_DMA_DESC_POOL_SIZE, TG3_FL_NOT_5705, 0xffffffff, 0x00000000 }, - + /* Mailbox Registers */ { GRCMBOX_RCVSTD_PROD_IDX+4, 0x0000, 0x00000000, 0x000001ff }, @@ -8448,10 +8698,12 @@ static int tg3_test_registers(struct tg3 { 0xffff, 0x0000, 0x00000000, 0x00000000 }, }; - if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) + is_5705 = is_5750 = 0; + if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) { is_5705 = 1; - else - is_5705 = 0; + if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) + is_5750 = 1; + } for (i = 0; reg_tbl[i].offset != 0xffff; i++) { if (is_5705 && (reg_tbl[i].flags & TG3_FL_NOT_5705)) @@ -8464,6 +8716,9 @@ static int tg3_test_registers(struct tg3 (reg_tbl[i].flags & TG3_FL_NOT_5788)) continue; + if (is_5750 && (reg_tbl[i].flags & TG3_FL_NOT_5750)) + continue; + offset = (u32) reg_tbl[i].offset; read_mask = reg_tbl[i].read_mask; write_mask = reg_tbl[i].write_mask; @@ -8507,7 +8762,9 @@ static int tg3_test_registers(struct tg3 return 0; out: - printk(KERN_ERR PFX "Register test failed at offset %x\n", offset); + if (netif_msg_hw(tp)) + printk(KERN_ERR PFX "Register test failed at offset %x\n", + offset); tw32(offset, save_val); return -EIO; } @@ -8555,6 +8812,13 @@ static int tg3_test_memory(struct tg3 *t { 0x00008000, 0x02000}, { 0x00010000, 0x0c000}, { 0xffffffff, 0x00000} + }, mem_tbl_5906[] = { + { 0x00000200, 0x00008}, + { 0x00004000, 0x00400}, + { 0x00006000, 0x00400}, + { 0x00008000, 0x01000}, + { 0x00010000, 0x01000}, + { 0xffffffff, 0x00000} }; struct mem_entry *mem_tbl; int err = 0; @@ -8564,6 +8828,8 @@ static int tg3_test_memory(struct tg3 *t if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) mem_tbl = mem_tbl_5755; + else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) + mem_tbl = mem_tbl_5906; else mem_tbl = mem_tbl_5705; } else @@ -8574,7 +8840,7 @@ static int tg3_test_memory(struct tg3 *t mem_tbl[i].len)) != 0) break; } - + return err; } @@ -8600,21 +8866,50 @@ static int tg3_run_loopback(struct tg3 * return 0; mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | - MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY | - MAC_MODE_PORT_MODE_GMII; + MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY; + if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) + mac_mode |= MAC_MODE_PORT_MODE_MII; + else + mac_mode |= MAC_MODE_PORT_MODE_GMII; tw32(MAC_MODE, mac_mode); } else if (loopback_mode == TG3_PHY_LOOPBACK) { - tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX | - BMCR_SPEED1000); + u32 val; + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + u32 phytest; + + if (!tg3_readphy(tp, MII_TG3_EPHY_TEST, &phytest)) { + u32 phy; + + tg3_writephy(tp, MII_TG3_EPHY_TEST, + phytest | MII_TG3_EPHY_SHADOW_EN); + if (!tg3_readphy(tp, 0x1b, &phy)) + tg3_writephy(tp, 0x1b, phy & ~0x20); + if (!tg3_readphy(tp, 0x10, &phy)) + tg3_writephy(tp, 0x10, phy & ~0x4000); + tg3_writephy(tp, MII_TG3_EPHY_TEST, phytest); + } + val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED100; + } else + val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED1000; + + tg3_writephy(tp, MII_BMCR, val); udelay(40); + + mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | + MAC_MODE_LINK_POLARITY; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x1800); + mac_mode |= MAC_MODE_PORT_MODE_MII; + } else + mac_mode |= MAC_MODE_PORT_MODE_GMII; + /* reset to prevent losing 1st rx packet intermittently */ if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) { tw32_f(MAC_RX_MODE, RX_MODE_RESET); udelay(10); tw32_f(MAC_RX_MODE, tp->rx_mode); } - mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | - MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII; if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) { mac_mode &= ~MAC_MODE_LINK_POLARITY; tg3_writephy(tp, MII_TG3_EXT_CTRL, @@ -8663,7 +8958,8 @@ static int tg3_run_loopback(struct tg3 * udelay(10); - for (i = 0; i < 10; i++) { + /* 250 usec to allow enough time on some 10/100 Mbps devices. */ + for (i = 0; i < 25; i++) { tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW); @@ -8709,7 +9005,7 @@ static int tg3_run_loopback(struct tg3 * goto out; } err = 0; - + /* tg3_free_rings will unmap and free the rx_skb */ out: return err; @@ -8991,10 +9287,8 @@ static struct ethtool_ops tg3_ethtool_op .set_tx_csum = tg3_set_tx_csum, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, -#if TG3_TSO_SUPPORT != 0 .get_tso = ethtool_op_get_tso, .set_tso = tg3_set_tso, -#endif .self_test_count = tg3_get_test_count, .self_test = tg3_self_test, .get_strings = tg3_get_strings, @@ -9015,7 +9309,9 @@ static void __devinit tg3_get_eeprom_siz if (tg3_nvram_read_swab(tp, 0, &magic) != 0) return; - if ((magic != TG3_EEPROM_MAGIC) && ((magic & 0xff000000) != 0xa5000000)) + if ((magic != TG3_EEPROM_MAGIC) && + ((magic & TG3_EEPROM_MAGIC_FW_MSK) != TG3_EEPROM_MAGIC_FW) && + ((magic & TG3_EEPROM_MAGIC_HW_MSK) != TG3_EEPROM_MAGIC_HW)) return; /* @@ -9037,7 +9333,7 @@ static void __devinit tg3_get_eeprom_siz tp->nvram_size = cursize; } - + static void __devinit tg3_get_nvram_size(struct tg3 *tp) { u32 val; @@ -9057,7 +9353,7 @@ static void __devinit tg3_get_nvram_size return; } } - tp->nvram_size = 0x20000; + tp->nvram_size = 0x80000; } static void __devinit tg3_get_nvram_info(struct tg3 *tp) @@ -9176,33 +9472,31 @@ static void __devinit tg3_get_5752_nvram static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp) { - u32 nvcfg1; + u32 nvcfg1, protect = 0; nvcfg1 = tr32(NVRAM_CFG1); /* NVRAM protection for TPM */ - if (nvcfg1 & (1 << 27)) + if (nvcfg1 & (1 << 27)) { tp->tg3_flags2 |= TG3_FLG2_PROTECTED_NVRAM; + protect = 1; + } - switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) { - case FLASH_5755VENDOR_ATMEL_EEPROM_64KHZ: - case FLASH_5755VENDOR_ATMEL_EEPROM_376KHZ: - tp->nvram_jedecnum = JEDEC_ATMEL; - tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; - tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE; - - nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS; - tw32(NVRAM_CFG1, nvcfg1); - break; - case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED: + nvcfg1 &= NVRAM_CFG1_5752VENDOR_MASK; + switch (nvcfg1) { case FLASH_5755VENDOR_ATMEL_FLASH_1: case FLASH_5755VENDOR_ATMEL_FLASH_2: case FLASH_5755VENDOR_ATMEL_FLASH_3: - case FLASH_5755VENDOR_ATMEL_FLASH_4: tp->nvram_jedecnum = JEDEC_ATMEL; tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; tp->tg3_flags2 |= TG3_FLG2_FLASH; tp->nvram_pagesize = 264; + if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_1) + tp->nvram_size = (protect ? 0x3e200 : 0x80000); + else if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_2) + tp->nvram_size = (protect ? 0x1f200 : 0x40000); + else + tp->nvram_size = (protect ? 0x1f200 : 0x20000); break; case FLASH_5752VENDOR_ST_M45PE10: case FLASH_5752VENDOR_ST_M45PE20: @@ -9211,6 +9505,12 @@ static void __devinit tg3_get_5755_nvram tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; tp->tg3_flags2 |= TG3_FLG2_FLASH; tp->nvram_pagesize = 256; + if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE10) + tp->nvram_size = (protect ? 0x10000 : 0x20000); + else if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE20) + tp->nvram_size = (protect ? 0x10000 : 0x40000); + else + tp->nvram_size = (protect ? 0x20000 : 0x80000); break; } } @@ -9253,19 +9553,22 @@ static void __devinit tg3_get_5787_nvram } } +static void __devinit tg3_get_5906_nvram_info(struct tg3 *tp) +{ + tp->nvram_jedecnum = JEDEC_ATMEL; + tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; + tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE; +} + /* Chips other than 5700/5701 use the NVRAM for fetching info. */ static void __devinit tg3_nvram_init(struct tg3 *tp) { - int j; - tw32_f(GRC_EEPROM_ADDR, (EEPROM_ADDR_FSM_RESET | (EEPROM_DEFAULT_CLOCK_PERIOD << EEPROM_ADDR_CLKPERD_SHIFT))); - /* XXX schedule_timeout() ... */ - for (j = 0; j < 100; j++) - udelay(10); + msleep(1); /* Enable seeprom accesses. */ tw32_f(GRC_LOCAL_CTRL, @@ -9283,16 +9586,21 @@ static void __devinit tg3_nvram_init(str } tg3_enable_nvram_access(tp); + tp->nvram_size = 0; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752) tg3_get_5752_nvram_info(tp); else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) tg3_get_5755_nvram_info(tp); else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) tg3_get_5787_nvram_info(tp); + else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) + tg3_get_5906_nvram_info(tp); else tg3_get_nvram_info(tp); - tg3_get_nvram_size(tp); + if (tp->nvram_size == 0) + tg3_get_nvram_size(tp); tg3_disable_nvram_access(tp); tg3_nvram_unlock(tp); @@ -9324,12 +9632,12 @@ static int tg3_nvram_read_using_eeprom(s EEPROM_ADDR_ADDR_MASK) | EEPROM_ADDR_READ | EEPROM_ADDR_START); - for (i = 0; i < 10000; i++) { + for (i = 0; i < 1000; i++) { tmp = tr32(GRC_EEPROM_ADDR); if (tmp & EEPROM_ADDR_COMPLETE) break; - udelay(100); + msleep(1); } if (!(tmp & EEPROM_ADDR_COMPLETE)) return -EBUSY; @@ -9453,13 +9761,13 @@ static int tg3_nvram_write_block_using_e (addr & EEPROM_ADDR_ADDR_MASK) | EEPROM_ADDR_START | EEPROM_ADDR_WRITE); - - for (j = 0; j < 10000; j++) { + + for (j = 0; j < 1000; j++) { val = tr32(GRC_EEPROM_ADDR); if (val & EEPROM_ADDR_COMPLETE) break; - udelay(100); + msleep(1); } if (!(val & EEPROM_ADDR_COMPLETE)) { rc = -EBUSY; @@ -9489,7 +9797,7 @@ static int tg3_nvram_write_block_unbuffe u32 phy_addr, page_off, size; phy_addr = offset & ~pagemask; - + for (j = 0; j < pagesize; j += 4) { if ((ret = tg3_nvram_read(tp, phy_addr + j, (u32 *) (tmp + j)))) @@ -9759,8 +10067,18 @@ static void __devinit tg3_get_eeprom_hw_ tp->phy_id = PHY_ID_INVALID; tp->led_ctrl = LED_CTRL_MODE_PHY_1; - /* Assume an onboard device by default. */ - tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; + /* Assume an onboard device and WOL capable by default. */ + tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT | TG3_FLAG_WOL_CAP; + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + if (!(tr32(PCIE_TRANSACTION_CFG) & PCIE_TRANS_CFG_LOM)) { + tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT; + tp->tg3_flags2 |= TG3_FLG2_IS_NIC; + } + if (tr32(VCPU_CFGSHDW) & VCPU_CFGSHDW_ASPM_DBNC) + tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND; + return; + } tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val); if (val == NIC_SRAM_DATA_SIG_MAGIC) { @@ -9858,18 +10176,26 @@ static void __devinit tg3_get_eeprom_hw_ tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL) tp->led_ctrl = LED_CTRL_MODE_PHY_2; - if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP) + if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP) { tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; - else + if ((tp->pdev->subsystem_vendor == + PCI_VENDOR_ID_ARIMA) && + (tp->pdev->subsystem_device == 0x205a || + tp->pdev->subsystem_device == 0x2063)) + tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT; + } else { tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT; + tp->tg3_flags2 |= TG3_FLG2_IS_NIC; + } if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) { tp->tg3_flags |= TG3_FLAG_ENABLE_ASF; if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE; } - if (nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL) - tp->tg3_flags |= TG3_FLAG_SERDES_WOL_CAP; + if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES && + !(nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL)) + tp->tg3_flags &= ~TG3_FLAG_WOL_CAP; if (cfg2 & (1 << 17)) tp->tg3_flags2 |= TG3_FLG2_CAPACITIVE_COUPLING; @@ -9878,6 +10204,14 @@ static void __devinit tg3_get_eeprom_hw_ /* bootcode if bit 18 is set */ if (cfg2 & (1 << 18)) tp->tg3_flags2 |= TG3_FLG2_SERDES_PREEMPHASIS; + + if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) { + u32 cfg3; + + tg3_read_mem(tp, NIC_SRAM_DATA_CFG_3, &cfg3); + if (cfg3 & NIC_SRAM_ASPM_DEBOUNCE) + tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND; + } } } @@ -9939,13 +10273,13 @@ static int __devinit tg3_phy_probe(struc if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) && !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { - u32 bmsr, adv_reg, tg3_ctrl; + u32 bmsr, adv_reg, tg3_ctrl, mask; tg3_readphy(tp, MII_BMSR, &bmsr); if (!tg3_readphy(tp, MII_BMSR, &bmsr) && (bmsr & BMSR_LSTATUS)) goto skip_phy_reset; - + err = tg3_phy_reset(tp); if (err) return err; @@ -9963,7 +10297,10 @@ static int __devinit tg3_phy_probe(struc MII_TG3_CTRL_ENABLE_AS_MASTER); } - if (!tg3_copper_is_advertising_all(tp)) { + mask = (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | + ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full); + if (!tg3_copper_is_advertising_all(tp, mask)) { tg3_writephy(tp, MII_ADVERTISE, adv_reg); if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) @@ -10007,7 +10344,7 @@ skip_phy_reset: static void __devinit tg3_read_partno(struct tg3 *tp) { unsigned char vpd_data[256]; - int i; + unsigned int i; u32 magic; if (tg3_nvram_read_swab(tp, 0x0, &magic)) @@ -10053,9 +10390,9 @@ static void __devinit tg3_read_partno(st } /* Now parse and find the part number. */ - for (i = 0; i < 256; ) { + for (i = 0; i < 254; ) { unsigned char val = vpd_data[i]; - int block_end; + unsigned int block_end; if (val == 0x82 || val == 0x91) { i = (i + 3 + @@ -10071,21 +10408,26 @@ static void __devinit tg3_read_partno(st (vpd_data[i + 1] + (vpd_data[i + 2] << 8))); i += 3; - while (i < block_end) { + + if (block_end > 256) + goto out_not_found; + + while (i < (block_end - 2)) { if (vpd_data[i + 0] == 'P' && vpd_data[i + 1] == 'N') { int partno_len = vpd_data[i + 2]; - if (partno_len > 24) + i += 3; + if (partno_len > 24 || (partno_len + i) > 256) goto out_not_found; memcpy(tp->board_part_number, - &vpd_data[i + 3], - partno_len); + &vpd_data[i], partno_len); /* Success. */ return; } + i += 3 + vpd_data[i + 2]; } /* Part number not found. */ @@ -10093,7 +10435,10 @@ static void __devinit tg3_read_partno(st } out_not_found: - strcpy(tp->board_part_number, "none"); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) + strcpy(tp->board_part_number, "BCM95906"); + else + strcpy(tp->board_part_number, "none"); } static void __devinit tg3_read_fw_ver(struct tg3 *tp) @@ -10136,6 +10481,8 @@ static void __devinit tg3_read_fw_ver(st } } +static struct pci_dev * __devinit tg3_find_peer(struct tg3 *); + static int __devinit tg3_get_invariants(struct tg3 *tp) { static struct pci_device_id write_reorder_chipsets[] = { @@ -10152,7 +10499,7 @@ static int __devinit tg3_get_invariants( u32 pci_state_reg, grc_misc_cfg; u32 val; u16 pci_cmd; - int err; + int err, pcie_cap; /* Force memory write invalidate off. If we leave it on, * then on 5700_BX chips we have to enable a workaround. @@ -10291,10 +10638,15 @@ static int __devinit tg3_get_invariants( tp->pci_hdr_type = (cacheline_sz_reg >> 16) & 0xff; tp->pci_bist = (cacheline_sz_reg >> 24) & 0xff; + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)) + tp->pdev_peer = tg3_find_peer(tp); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 || (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) tp->tg3_flags2 |= TG3_FLG2_5750_PLUS; @@ -10303,17 +10655,25 @@ static int __devinit tg3_get_invariants( tp->tg3_flags2 |= TG3_FLG2_5705_PLUS; if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) { + tp->tg3_flags |= TG3_FLAG_SUPPORT_MSI; + if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX || + GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_BX || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 && + tp->pci_chip_rev_id <= CHIPREV_ID_5714_A2 && + tp->pdev_peer == tp->pdev)) + tp->tg3_flags &= ~TG3_FLAG_SUPPORT_MSI; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) { + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2; tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI; } else { - tp->tg3_flags2 |= TG3_FLG2_HW_TSO_1 | - TG3_FLG2_HW_TSO_1_BUG; + tp->tg3_flags2 |= TG3_FLG2_HW_TSO_1 | TG3_FLG2_TSO_BUG; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 && tp->pci_chip_rev_id >= CHIPREV_ID_5750_C2) - tp->tg3_flags2 &= ~TG3_FLG2_HW_TSO_1_BUG; + tp->tg3_flags2 &= ~TG3_FLG2_TSO_BUG; } } @@ -10321,11 +10681,23 @@ static int __devinit tg3_get_invariants( GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755 && - GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787) + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) tp->tg3_flags2 |= TG3_FLG2_JUMBO_CAPABLE; - if (pci_find_capability(tp->pdev, PCI_CAP_ID_EXP) != 0) + pcie_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_EXP); + if (pcie_cap != 0) { tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + u16 lnkctl; + + pci_read_config_word(tp->pdev, + pcie_cap + PCI_EXP_LNKCTL, + &lnkctl); + if (lnkctl & PCI_EXP_LNKCTL_CLKREQ_EN) + tp->tg3_flags2 &= ~TG3_FLG2_HW_TSO_2; + } + } /* If we have an AMD 762 or VIA K8T800 chipset, write * reordering to the mailbox registers done by the host @@ -10392,17 +10764,6 @@ static int __devinit tg3_get_invariants( if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5700_BX) tp->tg3_flags |= TG3_FLAG_TXD_MBOX_HWBUG; - /* Back to back register writes can cause problems on this chip, - * the workaround is to read back all reg writes except those to - * mailbox regs. See tg3_write_indirect_reg32(). - * - * PCI Express 5750_A0 rev chips need this workaround too. - */ - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 || - ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && - tp->pci_chip_rev_id == CHIPREV_ID_5750_A0)) - tp->tg3_flags |= TG3_FLAG_5701_REG_WRITE_BUG; - if ((pci_state_reg & PCISTATE_BUS_SPEED_HIGH) != 0) tp->tg3_flags |= TG3_FLAG_PCI_HIGH_SPEED; if ((pci_state_reg & PCISTATE_BUS_32BIT) != 0) @@ -10426,8 +10787,19 @@ static int __devinit tg3_get_invariants( /* Various workaround register access methods */ if (tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) tp->write32 = tg3_write_indirect_reg32; - else if (tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) + else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 || + ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && + tp->pci_chip_rev_id == CHIPREV_ID_5750_A0)) { + /* + * Back to back register writes can cause problems on these + * chips, the workaround is to read back all reg writes + * except those to mailbox regs. + * + * See tg3_write_indirect_reg32(). + */ tp->write32 = tg3_write_flush_reg32; + } + if ((tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG) || (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)) { @@ -10451,6 +10823,12 @@ static int __devinit tg3_get_invariants( pci_cmd &= ~PCI_COMMAND_MEMORY; pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd); } + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + tp->read32_mbox = tg3_read32_mbox_5906; + tp->write32_mbox = tg3_write32_mbox_5906; + tp->write32_tx_mbox = tg3_write32_mbox_5906; + tp->write32_rx_mbox = tg3_write32_mbox_5906; + } if (tp->write32 == tg3_write_indirect_reg32 || ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) && @@ -10459,13 +10837,13 @@ static int __devinit tg3_get_invariants( tp->tg3_flags |= TG3_FLAG_SRAM_USE_CONFIG; /* Get eeprom hw config before calling tg3_set_power_state(). - * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be + * In particular, the TG3_FLG2_IS_NIC flag must be * determined before calling tg3_set_power_state() so that * we know whether or not to switch out of Vaux power. * When the flag is set, it means that GPIO1 is used for eeprom * write protect and also implies that it is a LOM where GPIOs * are not used to switch power. - */ + */ tg3_get_eeprom_hw_cfg(tp); /* Set up tp->grc_local_ctrl before calling tg3_set_power_state(). @@ -10522,6 +10900,7 @@ static int __devinit tg3_get_invariants( ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) && (tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) && (tp->pci_chip_rev_id != CHIPREV_ID_5705_A1)) || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) || (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) tp->tg3_flags2 |= TG3_FLG2_NO_ETH_WIRE_SPEED; @@ -10533,9 +10912,13 @@ static int __devinit tg3_get_invariants( if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) - tp->tg3_flags2 |= TG3_FLG2_PHY_JITTER_BUG; - else + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) { + if (tp->pdev->device != PCI_DEVICE_ID_TIGON3_5756 && + tp->pdev->device != PCI_DEVICE_ID_TIGON3_5722) + tp->tg3_flags2 |= TG3_FLG2_PHY_JITTER_BUG; + if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5755M) + tp->tg3_flags2 |= TG3_FLG2_PHY_ADJUST_TRIM; + } else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG; } @@ -10590,14 +10973,6 @@ static int __devinit tg3_get_invariants( grc_misc_cfg = tr32(GRC_MISC_CFG); grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK; - /* Broadcom's driver says that CIOBE multisplit has a bug */ -#if 0 - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 && - grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5704CIOBE) { - tp->tg3_flags |= TG3_FLAG_SPLIT_MODE; - tp->split_mode_max_reqs = SPLIT_MODE_5704_MAX_REQ; - } -#endif if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && (grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788 || grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M)) @@ -10625,7 +11000,9 @@ static int __devinit tg3_get_invariants( tp->pdev->device == PCI_DEVICE_ID_TIGON3_5705F)) || (tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM && (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5751F || - tp->pdev->device == PCI_DEVICE_ID_TIGON3_5753F))) + tp->pdev->device == PCI_DEVICE_ID_TIGON3_5753F || + tp->pdev->device == PCI_DEVICE_ID_TIGON3_5787F)) || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) tp->tg3_flags |= TG3_FLAG_10_100_ONLY; err = tg3_phy_probe(tp); @@ -10676,7 +11053,8 @@ static int __devinit tg3_get_invariants( * straddle the 4GB address boundary in some cases. */ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) tp->dev->hard_start_xmit = tg3_start_xmit; else tp->dev->hard_start_xmit = tg3_start_xmit_dma_bug; @@ -10701,27 +11079,27 @@ static int __devinit tg3_get_invariants( */ tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE; + if (tp->tg3_flags & TG3_FLAG_ASPM_WORKAROUND) + tp->pwrmgmt_thresh = tr32(PCIE_PWR_MGMT_THRESH) & + PCIE_PWR_MGMT_L1_THRESH_MSK; + return err; } -#ifdef CONFIG_SPARC64 +#ifdef CONFIG_SPARC static int __devinit tg3_get_macaddr_sparc(struct tg3 *tp) { struct net_device *dev = tp->dev; struct pci_dev *pdev = tp->pdev; - struct pcidev_cookie *pcp = pdev->sysdata; - - if (pcp != NULL) { - unsigned char *addr; - int len; - - addr = of_get_property(pcp->prom_node, "local-mac-address", - &len); - if (addr && len == 6) { - memcpy(dev->dev_addr, addr, 6); - memcpy(dev->perm_addr, dev->dev_addr, 6); - return 0; - } + struct device_node *dp = pci_device_to_OF_node(pdev); + const unsigned char *addr; + int len; + + addr = of_get_property(dp, "local-mac-address", &len); + if (addr && len == 6) { + memcpy(dev->dev_addr, addr, 6); + memcpy(dev->perm_addr, dev->dev_addr, 6); + return 0; } return -ENODEV; } @@ -10742,7 +11120,7 @@ static int __devinit tg3_get_device_addr u32 hi, lo, mac_offset; int addr_ok = 0; -#ifdef CONFIG_SPARC64 +#ifdef CONFIG_SPARC if (!tg3_get_macaddr_sparc(tp)) return 0; #endif @@ -10757,6 +11135,8 @@ static int __devinit tg3_get_device_addr else tg3_nvram_unlock(tp); } + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) + mac_offset = 0x10; /* First try to get it from MAC address mailbox. */ tg3_read_mem(tp, NIC_SRAM_MAC_ADDR_HIGH_MBOX, &hi); @@ -11062,6 +11442,7 @@ static int __devinit tg3_test_dma(struct if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { u32 ccval = (tr32(TG3PCI_CLOCK_CTRL) & 0x1f); + u32 read_water = 0x7; /* If the 5704 is behind the EPB bridge, we can * do the less restrictive ONE_DMA workaround for @@ -11073,8 +11454,13 @@ static int __devinit tg3_test_dma(struct else if (ccval == 0x6 || ccval == 0x7) tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) + read_water = 4; /* Set bit 23 to enable PCIX hw bug fix */ - tp->dma_rwctrl |= 0x009f0000; + tp->dma_rwctrl |= + (read_water << DMA_RWCTRL_READ_WATER_SHIFT) | + (0x3 << DMA_RWCTRL_WRITE_WATER_SHIFT) | + (1 << 23); } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) { /* 5780 always in PCIX mode */ tp->dma_rwctrl |= 0x00144000; @@ -11240,6 +11626,12 @@ static void __devinit tg3_init_bufmgr_co DEFAULT_MB_MACRX_LOW_WATER_5705; tp->bufmgr_config.mbuf_high_water = DEFAULT_MB_HIGH_WATER_5705; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + tp->bufmgr_config.mbuf_mac_rx_low_water = + DEFAULT_MB_MACRX_LOW_WATER_5906; + tp->bufmgr_config.mbuf_high_water = + DEFAULT_MB_HIGH_WATER_5906; + } tp->bufmgr_config.mbuf_read_dma_low_water_jumbo = DEFAULT_MB_RDMA_LOW_WATER_JUMBO_5780; @@ -11284,6 +11676,7 @@ static char * __devinit tg3_phy_string(s case PHY_ID_BCM5755: return "5755"; case PHY_ID_BCM5787: return "5787"; case PHY_ID_BCM5756: return "5722/5756"; + case PHY_ID_BCM5906: return "5906"; case PHY_ID_BCM8002: return "8002/serdes"; case 0: return "serdes"; default: return "unknown"; @@ -11567,17 +11960,17 @@ static int __devinit tg3_init_one(struct tg3_init_bufmgr_config(tp); -#if TG3_TSO_SUPPORT != 0 if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) { tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 || tp->pci_chip_rev_id == CHIPREV_ID_5705_A0 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 || (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) { tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE; } else { - tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; + tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE | TG3_FLG2_TSO_BUG; } /* TSO is on by default on chips that support hardware TSO. @@ -11586,11 +11979,11 @@ static int __devinit tg3_init_one(struct */ if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) { dev->features |= NETIF_F_TSO; - if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) + if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) && + (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)) dev->features |= NETIF_F_TSO6; } -#endif if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 && !(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) && @@ -11599,10 +11992,6 @@ static int __devinit tg3_init_one(struct tp->rx_pending = 63; } - if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) || - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)) - tp->pdev_peer = tg3_find_peer(tp); - err = tg3_get_device_address(tp); if (err) { printk(KERN_ERR PFX "Could not obtain valid ethernet address, " @@ -11653,6 +12042,8 @@ static int __devinit tg3_init_one(struct */ pci_save_state(tp->pdev); + pci_set_drvdata(pdev, dev); + err = register_netdev(dev); if (err) { printk(KERN_ERR PFX "Cannot register net device, " @@ -11660,29 +12051,27 @@ static int __devinit tg3_init_one(struct goto err_out_iounmap; } - pci_set_drvdata(pdev, dev); - - printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (%s) %sBaseT Ethernet ", + printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (%s) %s Ethernet ", dev->name, tp->board_part_number, tp->pci_chip_rev_id, tg3_phy_string(tp), tg3_bus_string(tp, str), - (tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100" : "10/100/1000"); + ((tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100Base-TX" : + ((tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) ? "1000Base-SX" : + "10/100/1000Base-T"))); for (i = 0; i < 6; i++) printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); printk(KERN_INFO "%s: RXcsums[%d] LinkChgREG[%d] " - "MIirq[%d] ASF[%d] Split[%d] WireSpeed[%d] " - "TSOcap[%d] \n", + "MIirq[%d] ASF[%d] WireSpeed[%d] TSOcap[%d]\n", dev->name, (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0, (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0, (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) != 0, (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0, - (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) != 0, (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0, (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0); printk(KERN_INFO "%s: dma_rwctrl[%08x] dma_mask[%d-bit]\n", @@ -11690,8 +12079,6 @@ static int __devinit tg3_init_one(struct (pdev->dma_mask == DMA_32BIT_MASK) ? 32 : (((u64) pdev->dma_mask == DMA_40BIT_MASK) ? 40 : 64)); - netif_carrier_off(tp->dev); - return 0; err_out_iounmap: @@ -11757,6 +12144,9 @@ static int tg3_suspend(struct pci_dev *p tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; tg3_full_unlock(tp); + /* Save MSI address and data for resume. */ + pci_save_state(pdev); + err = tg3_set_power_state(tp, pci_choose_state(pdev, state)); if (err) { tg3_full_lock(tp, 0); --- linux-2.6.18.x86_64/drivers/net/tg3.h.gospo 2007-05-24 14:50:12.641937000 -0400 +++ linux-2.6.18.x86_64/drivers/net/tg3.h 2007-05-24 14:50:41.769780000 -0400 @@ -24,6 +24,8 @@ #define RX_COPY_THRESHOLD 256 +#define TG3_RX_INTERNAL_RING_SZ_5906 32 + #define RX_STD_MAX_SIZE 1536 #define RX_STD_MAX_SIZE_5705 512 #define RX_JUMBO_MAX_SIZE 0xdeadbeef /* XXX */ @@ -129,6 +131,8 @@ #define CHIPREV_ID_5752_A0_HW 0x5000 #define CHIPREV_ID_5752_A0 0x6000 #define CHIPREV_ID_5752_A1 0x6001 +#define CHIPREV_ID_5714_A2 0x9002 +#define CHIPREV_ID_5906_A1 0xc001 #define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12) #define ASIC_REV_5700 0x07 #define ASIC_REV_5701 0x00 @@ -141,6 +145,7 @@ #define ASIC_REV_5714 0x09 #define ASIC_REV_5755 0x0a #define ASIC_REV_5787 0x0b +#define ASIC_REV_5906 0x0c #define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8) #define CHIPREV_5700_AX 0x70 #define CHIPREV_5700_BX 0x71 @@ -646,7 +651,8 @@ #define SNDDATAI_SCTRL_FORCE_ZERO 0x00000010 #define SNDDATAI_STATSENAB 0x00000c0c #define SNDDATAI_STATSINCMASK 0x00000c10 -/* 0xc14 --> 0xc80 unused */ +#define ISO_PKT_TX 0x00000c20 +/* 0xc24 --> 0xc80 unused */ #define SNDDATAI_COS_CNT_0 0x00000c80 #define SNDDATAI_COS_CNT_1 0x00000c84 #define SNDDATAI_COS_CNT_2 0x00000c88 @@ -997,11 +1003,13 @@ #define BUFMGR_MB_MACRX_LOW_WATER 0x00004414 #define DEFAULT_MB_MACRX_LOW_WATER 0x00000020 #define DEFAULT_MB_MACRX_LOW_WATER_5705 0x00000010 +#define DEFAULT_MB_MACRX_LOW_WATER_5906 0x00000004 #define DEFAULT_MB_MACRX_LOW_WATER_JUMBO 0x00000098 #define DEFAULT_MB_MACRX_LOW_WATER_JUMBO_5780 0x0000004b #define BUFMGR_MB_HIGH_WATER 0x00004418 #define DEFAULT_MB_HIGH_WATER 0x00000060 #define DEFAULT_MB_HIGH_WATER_5705 0x00000060 +#define DEFAULT_MB_HIGH_WATER_5906 0x00000010 #define DEFAULT_MB_HIGH_WATER_JUMBO 0x0000017c #define DEFAULT_MB_HIGH_WATER_JUMBO_5780 0x00000096 #define BUFMGR_RX_MB_ALLOC_REQ 0x0000441c @@ -1138,7 +1146,15 @@ #define TX_CPU_STATE 0x00005404 #define TX_CPU_PGMCTR 0x0000541c +#define VCPU_STATUS 0x00005100 +#define VCPU_STATUS_INIT_DONE 0x04000000 +#define VCPU_STATUS_DRV_RESET 0x08000000 + +#define VCPU_CFGSHDW 0x00005104 +#define VCPU_CFGSHDW_ASPM_DBNC 0x00001000 + /* Mailboxes */ +#define GRCMBOX_BASE 0x00005600 #define GRCMBOX_INTERRUPT_0 0x00005800 /* 64-bit */ #define GRCMBOX_INTERRUPT_1 0x00005808 /* 64-bit */ #define GRCMBOX_INTERRUPT_2 0x00005810 /* 64-bit */ @@ -1338,6 +1354,7 @@ #define GRC_MISC_CFG_BOARD_ID_5788 0x00010000 #define GRC_MISC_CFG_BOARD_ID_5788M 0x00018000 #define GRC_MISC_CFG_BOARD_ID_AC91002A1 0x00018000 +#define GRC_MISC_CFG_EPHY_IDDQ 0x00200000 #define GRC_MISC_CFG_KEEP_GPHY_POWER 0x04000000 #define GRC_LOCAL_CTRL 0x00006808 #define GRC_LCLCTRL_INT_ACTIVE 0x00000001 @@ -1398,7 +1415,10 @@ #define GRC_EEPROM_CTRL 0x00006840 #define GRC_MDI_CTRL 0x00006844 #define GRC_SEEPROM_DELAY 0x00006848 -/* 0x684c --> 0x6c00 unused */ +/* 0x684c --> 0x6890 unused */ +#define GRC_VCPU_EXT_CTRL 0x00006890 +#define GRC_VCPU_EXT_CTRL_HALT_CPU 0x00400000 +#define GRC_VCPU_EXT_CTRL_DISABLE_WOL 0x20000000 #define GRC_FASTBOOT_PC 0x00006894 /* 5752, 5755, 5787 */ /* 0x6c00 --> 0x7000 unused */ @@ -1485,9 +1505,19 @@ #define NVRAM_WRITE1 0x00007028 /* 0x702c --> 0x7400 unused */ -/* 0x7400 --> 0x8000 unused */ +/* 0x7400 --> 0x7c00 unused */ +#define PCIE_TRANSACTION_CFG 0x00007c04 +#define PCIE_TRANS_CFG_1SHOT_MSI 0x20000000 +#define PCIE_TRANS_CFG_LOM 0x00000020 + +#define PCIE_PWR_MGMT_THRESH 0x00007d28 +#define PCIE_PWR_MGMT_L1_THRESH_MSK 0x0000ff00 #define TG3_EEPROM_MAGIC 0x669955aa +#define TG3_EEPROM_MAGIC_FW 0xa5000000 +#define TG3_EEPROM_MAGIC_FW_MSK 0xff000000 +#define TG3_EEPROM_MAGIC_HW 0xabcd +#define TG3_EEPROM_MAGIC_HW_MSK 0xffff /* 32K Window into NIC internal memory */ #define NIC_SRAM_WIN_BASE 0x00008000 @@ -1537,6 +1567,7 @@ #define FWCMD_NICDRV_FIX_DMAR 0x00000005 #define FWCMD_NICDRV_FIX_DMAW 0x00000006 #define FWCMD_NICDRV_ALIVE2 0x0000000d +#define FWCMD_NICDRV_ALIVE3 0x0000000e #define NIC_SRAM_FW_CMD_LEN_MBOX 0x00000b7c #define NIC_SRAM_FW_CMD_DATA_MBOX 0x00000b80 #define NIC_SRAM_FW_ASF_STATUS_MBOX 0x00000c00 @@ -1567,6 +1598,9 @@ #define SHASTA_EXT_LED_MAC 0x00010000 #define SHASTA_EXT_LED_COMBO 0x00018000 +#define NIC_SRAM_DATA_CFG_3 0x00000d3c +#define NIC_SRAM_ASPM_DEBOUNCE 0x00000002 + #define NIC_SRAM_RX_MINI_BUFFER_DESC 0x00001000 #define NIC_SRAM_DMA_DESC_POOL_BASE 0x00002000 @@ -1604,6 +1638,7 @@ #define MII_TG3_DSP_RW_PORT 0x15 /* DSP coefficient read/write port */ #define MII_TG3_DSP_ADDRESS 0x17 /* DSP address register */ +#define MII_TG3_EPHY_PTEST 0x17 /* 5906 PHY register */ #define MII_TG3_AUX_CTRL 0x18 /* auxilliary control register */ @@ -1617,6 +1652,8 @@ #define MII_TG3_AUX_STAT_100FULL 0x0500 #define MII_TG3_AUX_STAT_1000HALF 0x0600 #define MII_TG3_AUX_STAT_1000FULL 0x0700 +#define MII_TG3_AUX_STAT_100 0x0008 +#define MII_TG3_AUX_STAT_FULL 0x0001 #define MII_TG3_ISTAT 0x1a /* IRQ status register */ #define MII_TG3_IMASK 0x1b /* IRQ mask register */ @@ -1627,6 +1664,13 @@ #define MII_TG3_INT_DUPLEXCHG 0x0008 #define MII_TG3_INT_ANEG_PAGE_RX 0x0400 +#define MII_TG3_EPHY_TEST 0x1f /* 5906 PHY register */ +#define MII_TG3_EPHY_SHADOW_EN 0x80 + +#define MII_TG3_TEST1 0x1e +#define MII_TG3_TEST1_TRIM_EN 0x0010 +#define MII_TG3_TEST1_CRC_EN 0x8000 + /* There are two ways to manage the TX descriptors on the tigon3. * Either the descriptors are in host DMA'able memory, or they * exist only in the cards on-chip SRAM. All 16 send bds are under @@ -2164,7 +2208,7 @@ struct tg3 { #define TG3_FLAG_USE_LINKCHG_REG 0x00000008 #define TG3_FLAG_USE_MI_INTERRUPT 0x00000010 #define TG3_FLAG_ENABLE_ASF 0x00000020 -#define TG3_FLAG_5701_REG_WRITE_BUG 0x00000040 +#define TG3_FLAG_ASPM_WORKAROUND 0x00000040 #define TG3_FLAG_POLL_SERDES 0x00000080 #define TG3_FLAG_MBOX_WRITE_REORDER 0x00000100 #define TG3_FLAG_PCIX_TARGET_HWBUG 0x00000200 @@ -2180,19 +2224,19 @@ struct tg3 { #define TG3_FLAG_PCI_32BIT 0x00080000 #define TG3_FLAG_SRAM_USE_CONFIG 0x00100000 #define TG3_FLAG_TX_RECOVERY_PENDING 0x00200000 -#define TG3_FLAG_SERDES_WOL_CAP 0x00400000 +#define TG3_FLAG_WOL_CAP 0x00400000 #define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000 #define TG3_FLAG_10_100_ONLY 0x01000000 #define TG3_FLAG_PAUSE_AUTONEG 0x02000000 #define TG3_FLAG_IN_RESET_TASK 0x04000000 #define TG3_FLAG_40BIT_DMA_BUG 0x08000000 #define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000 -#define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000 -#define TG3_FLAG_SPLIT_MODE 0x40000000 +#define TG3_FLAG_SUPPORT_MSI 0x20000000 +#define TG3_FLAG_CHIP_RESETTING 0x40000000 #define TG3_FLAG_INIT_COMPLETE 0x80000000 u32 tg3_flags2; #define TG3_FLG2_RESTART_TIMER 0x00000001 -#define TG3_FLG2_HW_TSO_1_BUG 0x00000002 +#define TG3_FLG2_TSO_BUG 0x00000002 #define TG3_FLG2_NO_ETH_WIRE_SPEED 0x00000004 #define TG3_FLG2_IS_5788 0x00000008 #define TG3_FLG2_MAX_RXPEND_64 0x00000010 @@ -2203,7 +2247,7 @@ struct tg3 { #define TG3_FLG2_PCI_EXPRESS 0x00000200 #define TG3_FLG2_ASF_NEW_HANDSHAKE 0x00000400 #define TG3_FLG2_HW_AUTONEG 0x00000800 -#define TG3_FLG2_PHY_JUST_INITTED 0x00001000 +#define TG3_FLG2_IS_NIC 0x00001000 #define TG3_FLG2_PHY_SERDES 0x00002000 #define TG3_FLG2_CAPACITIVE_COUPLING 0x00004000 #define TG3_FLG2_FLASH 0x00008000 @@ -2225,9 +2269,7 @@ struct tg3 { #define TG3_FLG2_1SHOT_MSI 0x10000000 #define TG3_FLG2_PHY_JITTER_BUG 0x20000000 #define TG3_FLG2_NO_FWARE_REPORTED 0x40000000 - - u32 split_mode_max_reqs; -#define SPLIT_MODE_5704_MAX_REQ 3 +#define TG3_FLG2_PHY_ADJUST_TRIM 0x80000000 struct timer_list timer; u16 timer_counter; @@ -2236,6 +2278,12 @@ struct tg3 { u16 asf_counter; u16 asf_multiplier; + /* 1 second counter for transient serdes link events */ + u32 serdes_counter; +#define SERDES_AN_TIMEOUT_5704S 2 +#define SERDES_PARALLEL_DET_TIMEOUT 1 +#define SERDES_AN_TIMEOUT_5714S 1 + struct tg3_link_config link_config; struct tg3_bufmgr_config bufmgr_config; @@ -2249,6 +2297,7 @@ struct tg3 { u32 grc_local_ctrl; u32 dma_rwctrl; u32 coalesce_mode; + u32 pwrmgmt_thresh; /* PCI block */ u16 pci_chip_rev_id; @@ -2277,6 +2326,7 @@ struct tg3 { #define PHY_ID_BCM5755 0xbc050cc0 #define PHY_ID_BCM5787 0xbc050ce0 #define PHY_ID_BCM5756 0xbc050ed0 +#define PHY_ID_BCM5906 0xdc00ac40 #define PHY_ID_BCM8002 0x60010140 #define PHY_ID_INVALID 0xffffffff #define PHY_ID_REV_MASK 0x0000000f @@ -2304,7 +2354,7 @@ struct tg3 { (X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5714 || \ (X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM5787 || \ (X) == PHY_ID_BCM5755 || (X) == PHY_ID_BCM5756 || \ - (X) == PHY_ID_BCM8002) + (X) == PHY_ID_BCM5906 || (X) == PHY_ID_BCM8002) struct tg3_hw_stats *hw_stats; dma_addr_t stats_mapping; --- linux-2.6.18.x86_64/include/linux/pci_ids.h.gospo 2007-05-24 14:50:12.694883000 -0400 +++ linux-2.6.18.x86_64/include/linux/pci_ids.h 2007-05-24 14:50:35.895659000 -0400 @@ -1926,6 +1926,7 @@ #define PCI_DEVICE_ID_TIGON3_5750M 0x167c #define PCI_DEVICE_ID_TIGON3_5751M 0x167d #define PCI_DEVICE_ID_TIGON3_5751F 0x167e +#define PCI_DEVICE_ID_TIGON3_5787F 0x167f #define PCI_DEVICE_ID_TIGON3_5787M 0x1693 #define PCI_DEVICE_ID_TIGON3_5782 0x1696 #define PCI_DEVICE_ID_TIGON3_5786 0x169a @@ -1946,6 +1947,8 @@ #define PCI_DEVICE_ID_TIGON3_5901 0x170d #define PCI_DEVICE_ID_BCM4401B1 0x170c #define PCI_DEVICE_ID_TIGON3_5901_2 0x170e +#define PCI_DEVICE_ID_TIGON3_5906 0x1712 +#define PCI_DEVICE_ID_TIGON3_5906M 0x1713 #define PCI_DEVICE_ID_BCM4401 0x4401 #define PCI_DEVICE_ID_BCM4401B0 0x4402 @@ -1995,6 +1998,8 @@ #define PCI_DEVICE_ID_FARSITE_TE1 0x1610 #define PCI_DEVICE_ID_FARSITE_TE1C 0x1612 +#define PCI_VENDOR_ID_ARIMA 0x161f + #define PCI_VENDOR_ID_SIBYTE 0x166d #define PCI_DEVICE_ID_BCM1250_HT 0x0002 [TG3]: Fix link problem on Dell's onboard 5906. The bug is caused by code that always set (TG3_FLAG_USE_MI_INTERRUPT | TG3_FLAG_USE_LINKCHG_REG) on all Dell's onboard devices. With these 2 flags set, the link status is polled by tg3_timer() and will only work when the PHY is set up to interrupt the MAC on link changes. This breaks 5906 because the 5906 PHY does not support TG3_FLAG_USE_MI_INTERRUPT the same as other PHYs. For correctness, only Dell's onboard 5701 needs these 2 flags to be set. This change will fix the 5906 problem and will change other Dell devices except 5700 and 5701 to use the more efficient interrupt-driven link changes. Update version to 3.77. Signed-off-by: Michael Chan <mchan@broadcom.com> --- tg3.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) --- linux-2.6.18.x86_64/drivers/net/tg3.c.gospo 2007-06-04 15:18:55.885776000 -0400 +++ linux-2.6.18.x86_64/drivers/net/tg3.c 2007-06-04 15:18:58.420238000 -0400 @@ -63,8 +63,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.76" -#define DRV_MODULE_RELDATE "May 5, 2007" +#define DRV_MODULE_VERSION "3.77" +#define DRV_MODULE_RELDATE "May 31, 2007" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -11038,6 +11038,7 @@ static int __devinit tg3_get_invariants( * upon subsystem IDs. */ if (tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL && + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 && !(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { tp->tg3_flags |= (TG3_FLAG_USE_MI_INTERRUPT | TG3_FLAG_USE_LINKCHG_REG);