diff options
author | Michael Chan <mchan@broadcom.com> | 2006-03-28 02:19:00 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-03-28 20:02:38 -0500 |
commit | 100c4673307f5806788791b9b886877c806afd96 (patch) | |
tree | 0269abfbf85bfa2e149d027393c8c27d1e00bec6 /drivers/net/tg3.c | |
parent | ff18ff023495a4f1ce7c65e7c376c4720eccf4da (diff) |
[TG3]: Speed up SRAM access
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. As a result, NETDEV
WATCHDOG can be triggered during self test and the chip can end up in
a funny state.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r-- | drivers/net/tg3.c | 53 |
1 files changed, 30 insertions, 23 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 3c5c9fafe9c8..c504ff29d44c 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -497,21 +497,20 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) | |||
497 | unsigned long flags; | 497 | unsigned long flags; |
498 | 498 | ||
499 | spin_lock_irqsave(&tp->indirect_lock, flags); | 499 | spin_lock_irqsave(&tp->indirect_lock, flags); |
500 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); | 500 | if (tp->write32 != tg3_write_indirect_reg32) { |
501 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | 501 | tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off); |
502 | tw32_f(TG3PCI_MEM_WIN_DATA, val); | ||
502 | 503 | ||
503 | /* Always leave this as zero. */ | 504 | /* Always leave this as zero. */ |
504 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); | 505 | tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0); |
505 | spin_unlock_irqrestore(&tp->indirect_lock, flags); | 506 | } else { |
506 | } | 507 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); |
508 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | ||
507 | 509 | ||
508 | static void tg3_write_mem_fast(struct tg3 *tp, u32 off, u32 val) | 510 | /* Always leave this as zero. */ |
509 | { | 511 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); |
510 | /* If no workaround is needed, write to mem space directly */ | 512 | } |
511 | if (tp->write32 != tg3_write_indirect_reg32) | 513 | spin_unlock_irqrestore(&tp->indirect_lock, flags); |
512 | tw32(NIC_SRAM_WIN_BASE + off, val); | ||
513 | else | ||
514 | tg3_write_mem(tp, off, val); | ||
515 | } | 514 | } |
516 | 515 | ||
517 | static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) | 516 | 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 | unsigned long flags; | 518 | unsigned long flags; |
520 | 519 | ||
521 | spin_lock_irqsave(&tp->indirect_lock, flags); | 520 | spin_lock_irqsave(&tp->indirect_lock, flags); |
522 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); | 521 | if (tp->write32 != tg3_write_indirect_reg32) { |
523 | pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | 522 | tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off); |
523 | *val = tr32(TG3PCI_MEM_WIN_DATA); | ||
524 | 524 | ||
525 | /* Always leave this as zero. */ | 525 | /* Always leave this as zero. */ |
526 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); | 526 | tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0); |
527 | } else { | ||
528 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); | ||
529 | pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | ||
530 | |||
531 | /* Always leave this as zero. */ | ||
532 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); | ||
533 | } | ||
527 | spin_unlock_irqrestore(&tp->indirect_lock, flags); | 534 | spin_unlock_irqrestore(&tp->indirect_lock, flags); |
528 | } | 535 | } |
529 | 536 | ||
@@ -1367,12 +1374,12 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) | |||
1367 | } | 1374 | } |
1368 | } | 1375 | } |
1369 | 1376 | ||
1377 | tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); | ||
1378 | |||
1370 | /* Finally, set the new power state. */ | 1379 | /* Finally, set the new power state. */ |
1371 | pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control); | 1380 | pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control); |
1372 | udelay(100); /* Delay after power state change */ | 1381 | udelay(100); /* Delay after power state change */ |
1373 | 1382 | ||
1374 | tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); | ||
1375 | |||
1376 | return 0; | 1383 | return 0; |
1377 | } | 1384 | } |
1378 | 1385 | ||
@@ -6537,11 +6544,11 @@ static void tg3_timer(unsigned long __opaque) | |||
6537 | if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { | 6544 | if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { |
6538 | u32 val; | 6545 | u32 val; |
6539 | 6546 | ||
6540 | tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_MBOX, | 6547 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, |
6541 | FWCMD_NICDRV_ALIVE2); | 6548 | FWCMD_NICDRV_ALIVE2); |
6542 | tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); | 6549 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); |
6543 | /* 5 seconds timeout */ | 6550 | /* 5 seconds timeout */ |
6544 | tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); | 6551 | tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); |
6545 | val = tr32(GRC_RX_CPU_EVENT); | 6552 | val = tr32(GRC_RX_CPU_EVENT); |
6546 | val |= (1 << 14); | 6553 | val |= (1 << 14); |
6547 | tw32(GRC_RX_CPU_EVENT, val); | 6554 | tw32(GRC_RX_CPU_EVENT, val); |