diff options
author | Michael Chan <mchan@broadcom.com> | 2005-08-09 23:16:46 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2005-08-29 18:50:15 -0400 |
commit | 1ee582d8e49a1c9dd43b2599f1cd26507182a8d4 (patch) | |
tree | 335928fc4470391ff894616e53a186200682c072 /drivers/net/tg3.c | |
parent | 2009493065e01b1fe27c1b98ffbcfab98e185f72 (diff) |
[TG3]: Add various register methods
This patch adds various dedicated register read/write methods for the
existing workarounds, including PCIX target workaround, write with read
flush, etc. The chips that require these workarounds will use these
dedicated access functions.
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 | 66 |
1 files changed, 33 insertions, 33 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 13283c29f802..80fbb183f755 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -340,16 +340,16 @@ static struct { | |||
340 | 340 | ||
341 | static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) | 341 | static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) |
342 | { | 342 | { |
343 | if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) { | 343 | spin_lock_bh(&tp->indirect_lock); |
344 | spin_lock_bh(&tp->indirect_lock); | 344 | pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off); |
345 | pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off); | 345 | pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val); |
346 | pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val); | 346 | spin_unlock_bh(&tp->indirect_lock); |
347 | spin_unlock_bh(&tp->indirect_lock); | 347 | } |
348 | } else { | 348 | |
349 | writel(val, tp->regs + off); | 349 | static void tg3_write_flush_reg32(struct tg3 *tp, u32 off, u32 val) |
350 | if ((tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) != 0) | 350 | { |
351 | readl(tp->regs + off); | 351 | writel(val, tp->regs + off); |
352 | } | 352 | readl(tp->regs + off); |
353 | } | 353 | } |
354 | 354 | ||
355 | static void _tw32_flush(struct tg3 *tp, u32 off, u32 val) | 355 | static void _tw32_flush(struct tg3 *tp, u32 off, u32 val) |
@@ -366,14 +366,6 @@ static void _tw32_flush(struct tg3 *tp, u32 off, u32 val) | |||
366 | } | 366 | } |
367 | } | 367 | } |
368 | 368 | ||
369 | static void tg3_write32_rx_mbox(struct tg3 *tp, u32 off, u32 val) | ||
370 | { | ||
371 | void __iomem *mbox = tp->regs + off; | ||
372 | writel(val, mbox); | ||
373 | if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) | ||
374 | readl(mbox); | ||
375 | } | ||
376 | |||
377 | static void tg3_write32_tx_mbox(struct tg3 *tp, u32 off, u32 val) | 369 | static void tg3_write32_tx_mbox(struct tg3 *tp, u32 off, u32 val) |
378 | { | 370 | { |
379 | void __iomem *mbox = tp->regs + off; | 371 | void __iomem *mbox = tp->regs + off; |
@@ -4222,7 +4214,7 @@ static void tg3_stop_fw(struct tg3 *); | |||
4222 | static int tg3_chip_reset(struct tg3 *tp) | 4214 | static int tg3_chip_reset(struct tg3 *tp) |
4223 | { | 4215 | { |
4224 | u32 val; | 4216 | u32 val; |
4225 | u32 flags_save; | 4217 | void (*write_op)(struct tg3 *, u32, u32); |
4226 | int i; | 4218 | int i; |
4227 | 4219 | ||
4228 | if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) | 4220 | if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) |
@@ -4234,8 +4226,9 @@ static int tg3_chip_reset(struct tg3 *tp) | |||
4234 | * fun things. So, temporarily disable the 5701 | 4226 | * fun things. So, temporarily disable the 5701 |
4235 | * hardware workaround, while we do the reset. | 4227 | * hardware workaround, while we do the reset. |
4236 | */ | 4228 | */ |
4237 | flags_save = tp->tg3_flags; | 4229 | write_op = tp->write32; |
4238 | tp->tg3_flags &= ~TG3_FLAG_5701_REG_WRITE_BUG; | 4230 | if (write_op == tg3_write_flush_reg32) |
4231 | tp->write32 = tg3_write32; | ||
4239 | 4232 | ||
4240 | /* do the reset */ | 4233 | /* do the reset */ |
4241 | val = GRC_MISC_CFG_CORECLK_RESET; | 4234 | val = GRC_MISC_CFG_CORECLK_RESET; |
@@ -4254,8 +4247,8 @@ static int tg3_chip_reset(struct tg3 *tp) | |||
4254 | val |= GRC_MISC_CFG_KEEP_GPHY_POWER; | 4247 | val |= GRC_MISC_CFG_KEEP_GPHY_POWER; |
4255 | tw32(GRC_MISC_CFG, val); | 4248 | tw32(GRC_MISC_CFG, val); |
4256 | 4249 | ||
4257 | /* restore 5701 hardware bug workaround flag */ | 4250 | /* restore 5701 hardware bug workaround write method */ |
4258 | tp->tg3_flags = flags_save; | 4251 | tp->write32 = write_op; |
4259 | 4252 | ||
4260 | /* Unfortunately, we have to delay before the PCI read back. | 4253 | /* Unfortunately, we have to delay before the PCI read back. |
4261 | * Some 575X chips even will not respond to a PCI cfg access | 4254 | * Some 575X chips even will not respond to a PCI cfg access |
@@ -4641,7 +4634,6 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b | |||
4641 | int cpu_scratch_size, struct fw_info *info) | 4634 | int cpu_scratch_size, struct fw_info *info) |
4642 | { | 4635 | { |
4643 | int err, i; | 4636 | int err, i; |
4644 | u32 orig_tg3_flags = tp->tg3_flags; | ||
4645 | void (*write_op)(struct tg3 *, u32, u32); | 4637 | void (*write_op)(struct tg3 *, u32, u32); |
4646 | 4638 | ||
4647 | if (cpu_base == TX_CPU_BASE && | 4639 | if (cpu_base == TX_CPU_BASE && |
@@ -4657,11 +4649,6 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b | |||
4657 | else | 4649 | else |
4658 | write_op = tg3_write_indirect_reg32; | 4650 | write_op = tg3_write_indirect_reg32; |
4659 | 4651 | ||
4660 | /* Force use of PCI config space for indirect register | ||
4661 | * write calls. | ||
4662 | */ | ||
4663 | tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG; | ||
4664 | |||
4665 | /* It is possible that bootcode is still loading at this point. | 4652 | /* It is possible that bootcode is still loading at this point. |
4666 | * Get the nvram lock first before halting the cpu. | 4653 | * Get the nvram lock first before halting the cpu. |
4667 | */ | 4654 | */ |
@@ -4697,7 +4684,6 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b | |||
4697 | err = 0; | 4684 | err = 0; |
4698 | 4685 | ||
4699 | out: | 4686 | out: |
4700 | tp->tg3_flags = orig_tg3_flags; | ||
4701 | return err; | 4687 | return err; |
4702 | } | 4688 | } |
4703 | 4689 | ||
@@ -9331,11 +9317,25 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
9331 | pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, pci_state_reg); | 9317 | pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, pci_state_reg); |
9332 | } | 9318 | } |
9333 | 9319 | ||
9320 | /* Default fast path register access methods */ | ||
9334 | tp->read32 = tg3_read32; | 9321 | tp->read32 = tg3_read32; |
9335 | tp->write32 = tg3_write_indirect_reg32; | 9322 | tp->write32 = tg3_write32; |
9336 | tp->write32_mbox = tg3_write32; | 9323 | tp->write32_mbox = tg3_write32; |
9337 | tp->write32_tx_mbox = tg3_write32_tx_mbox; | 9324 | tp->write32_tx_mbox = tg3_write32; |
9338 | tp->write32_rx_mbox = tg3_write32_rx_mbox; | 9325 | tp->write32_rx_mbox = tg3_write32; |
9326 | |||
9327 | /* Various workaround register access methods */ | ||
9328 | if (tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) | ||
9329 | tp->write32 = tg3_write_indirect_reg32; | ||
9330 | else if (tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) | ||
9331 | tp->write32 = tg3_write_flush_reg32; | ||
9332 | |||
9333 | if ((tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG) || | ||
9334 | (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)) { | ||
9335 | tp->write32_tx_mbox = tg3_write32_tx_mbox; | ||
9336 | if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) | ||
9337 | tp->write32_rx_mbox = tg3_write_flush_reg32; | ||
9338 | } | ||
9339 | 9339 | ||
9340 | /* Get eeprom hw config before calling tg3_set_power_state(). | 9340 | /* Get eeprom hw config before calling tg3_set_power_state(). |
9341 | * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be | 9341 | * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be |