Commit bbadf503 authored by Michael Chan's avatar Michael Chan Committed by David S. Miller

[TG3]: Speed up SRAM access (2nd version)

Speed up SRAM read and write functions if possible by using MMIO
instead of config. cycles. With this change, the post reset signature
done at the end of D3 power change must now be moved before the D3
power change.

IBM reported a problem on powerpc blades during ethtool self test that
was caused by the memory test taking excessively long. Config.  cycles
are very slow on powerpc and the memory test can take more than 10
seconds to complete using config. cycles.

David Miller informed me that an earlier version of the patch caused
problems on sparc64 systems with built-in tg3 chips. This version
fixes the problem by excluding all SUN built-in tg3 chips from doing
MMIO SRAM access.

TG3_FLAG_EEPROM_WRITE_PROT is also set unconditionally when
TG3_FLG2_SUN_570X is set. This should be sane as all SUN chips are
built-in and do not require Vaux switching.
Signed-off-by: default avatarMichael Chan <mchan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d2d746f8
...@@ -497,21 +497,20 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) ...@@ -497,21 +497,20 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&tp->indirect_lock, flags); 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); pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
/* Always leave this as zero. */ /* Always leave this as zero. */
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
spin_unlock_irqrestore(&tp->indirect_lock, flags); } else {
} tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off);
tw32_f(TG3PCI_MEM_WIN_DATA, val);
static void tg3_write_mem_fast(struct tg3 *tp, u32 off, u32 val) /* Always leave this as zero. */
{ tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0);
/* If no workaround is needed, write to mem space directly */ }
if (tp->write32 != tg3_write_indirect_reg32) spin_unlock_irqrestore(&tp->indirect_lock, flags);
tw32(NIC_SRAM_WIN_BASE + off, val);
else
tg3_write_mem(tp, off, val);
} }
static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
...@@ -519,11 +518,19 @@ static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) ...@@ -519,11 +518,19 @@ static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&tp->indirect_lock, flags); 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); pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
/* Always leave this as zero. */ /* Always leave this as zero. */
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
} else {
tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off);
*val = tr32(TG3PCI_MEM_WIN_DATA);
/* Always leave this as zero. */
tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0);
}
spin_unlock_irqrestore(&tp->indirect_lock, flags); spin_unlock_irqrestore(&tp->indirect_lock, flags);
} }
...@@ -1367,12 +1374,12 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) ...@@ -1367,12 +1374,12 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
} }
} }
tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
/* Finally, set the new power state. */ /* Finally, set the new power state. */
pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control); pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control);
udelay(100); /* Delay after power state change */ udelay(100); /* Delay after power state change */
tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
return 0; return 0;
} }
...@@ -6539,11 +6546,11 @@ static void tg3_timer(unsigned long __opaque) ...@@ -6539,11 +6546,11 @@ static void tg3_timer(unsigned long __opaque)
if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
u32 val; u32 val;
tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_MBOX, tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX,
FWCMD_NICDRV_ALIVE2); FWCMD_NICDRV_ALIVE2);
tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
/* 5 seconds timeout */ /* 5 seconds timeout */
tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
val = tr32(GRC_RX_CPU_EVENT); val = tr32(GRC_RX_CPU_EVENT);
val |= (1 << 14); val |= (1 << 14);
tw32(GRC_RX_CPU_EVENT, val); tw32(GRC_RX_CPU_EVENT, val);
...@@ -9539,8 +9546,11 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) ...@@ -9539,8 +9546,11 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
tp->led_ctrl = LED_CTRL_MODE_PHY_1; tp->led_ctrl = LED_CTRL_MODE_PHY_1;
/* Do not even try poking around in here on Sun parts. */ /* Do not even try poking around in here on Sun parts. */
if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) {
/* All SUN chips are built-in LOMs. */
tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
return; return;
}
tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val); tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val);
if (val == NIC_SRAM_DATA_SIG_MAGIC) { if (val == NIC_SRAM_DATA_SIG_MAGIC) {
...@@ -9638,9 +9648,7 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) ...@@ -9638,9 +9648,7 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL) tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL)
tp->led_ctrl = LED_CTRL_MODE_PHY_2; tp->led_ctrl = LED_CTRL_MODE_PHY_2;
if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) && if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP)
(GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) &&
(nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP))
tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) { if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) {
...@@ -10265,6 +10273,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) ...@@ -10265,6 +10273,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd); pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd);
} }
if (tp->write32 == tg3_write_indirect_reg32 ||
((tp->tg3_flags & TG3_FLAG_PCIX_MODE) &&
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) ||
(tp->tg3_flags2 & TG3_FLG2_SUN_570X))
tp->tg3_flags |= TG3_FLAG_SRAM_USE_CONFIG;
/* Get eeprom hw config before calling tg3_set_power_state(). /* 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_FLAG_EEPROM_WRITE_PROT flag must be
* determined before calling tg3_set_power_state() so that * determined before calling tg3_set_power_state() so that
......
...@@ -2171,6 +2171,7 @@ struct tg3 { ...@@ -2171,6 +2171,7 @@ struct tg3 {
#define TG3_FLAG_PCIX_MODE 0x00020000 #define TG3_FLAG_PCIX_MODE 0x00020000
#define TG3_FLAG_PCI_HIGH_SPEED 0x00040000 #define TG3_FLAG_PCI_HIGH_SPEED 0x00040000
#define TG3_FLAG_PCI_32BIT 0x00080000 #define TG3_FLAG_PCI_32BIT 0x00080000
#define TG3_FLAG_SRAM_USE_CONFIG 0x00100000
#define TG3_FLAG_SERDES_WOL_CAP 0x00400000 #define TG3_FLAG_SERDES_WOL_CAP 0x00400000
#define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000 #define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000
#define TG3_FLAG_10_100_ONLY 0x01000000 #define TG3_FLAG_10_100_ONLY 0x01000000
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment