aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tg3.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2005-08-09 23:17:14 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2005-08-29 18:50:42 -0400
commit6892914fb7980d844f2bac859f4095df9ebd18da (patch)
treeddeb1904b798bb69ed248840f25477bf8891d250 /drivers/net/tg3.c
parent09ee929cccfd0b56ea3724b3c6299fbbe813df43 (diff)
[TG3]: Add indirect register method for 5703 behind ICH
This patch adds the new workaround for 5703 A1/A2 if it is behind certain ICH bridges. The workaround disables memory and uses config. cycles only to access all registers. The 5702/03 chips can mistakenly decode the special cycles from the ICH chipsets as memory write cycles, causing corruption of register and memory space. Only certain ICH bridges will drive special cycles with non-zero data during the address phase which can fall within the 5703's address range. This is not an ICH bug as the PCI spec allows non-zero address during special cycles. However, only these ICH bridges are known to drive non-zero addresses during special cycles. The indirect_lock is also changed to spin_lock_irqsave from spin_lock_bh because it is used in irq handler when using the indirect method to disable interrupts. 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.c190
1 files changed, 162 insertions, 28 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 8411e0f4cb69..3a7cfb81bf89 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -340,10 +340,12 @@ static struct {
340 340
341static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) 341static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val)
342{ 342{
343 spin_lock_bh(&tp->indirect_lock); 343 unsigned long flags;
344
345 spin_lock_irqsave(&tp->indirect_lock, flags);
344 pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off); 346 pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off);
345 pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val); 347 pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val);
346 spin_unlock_bh(&tp->indirect_lock); 348 spin_unlock_irqrestore(&tp->indirect_lock, flags);
347} 349}
348 350
349static void tg3_write_flush_reg32(struct tg3 *tp, u32 off, u32 val) 351static void tg3_write_flush_reg32(struct tg3 *tp, u32 off, u32 val)
@@ -352,24 +354,75 @@ static void tg3_write_flush_reg32(struct tg3 *tp, u32 off, u32 val)
352 readl(tp->regs + off); 354 readl(tp->regs + off);
353} 355}
354 356
355static void _tw32_flush(struct tg3 *tp, u32 off, u32 val) 357static u32 tg3_read_indirect_reg32(struct tg3 *tp, u32 off)
356{ 358{
357 if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) { 359 unsigned long flags;
358 spin_lock_bh(&tp->indirect_lock); 360 u32 val;
359 pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off); 361
360 pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val); 362 spin_lock_irqsave(&tp->indirect_lock, flags);
361 spin_unlock_bh(&tp->indirect_lock); 363 pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off);
362 } else { 364 pci_read_config_dword(tp->pdev, TG3PCI_REG_DATA, &val);
363 void __iomem *dest = tp->regs + off; 365 spin_unlock_irqrestore(&tp->indirect_lock, flags);
364 writel(val, dest); 366 return val;
365 readl(dest); /* always flush PCI write */ 367}
368
369static void tg3_write_indirect_mbox(struct tg3 *tp, u32 off, u32 val)
370{
371 unsigned long flags;
372
373 if (off == (MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW)) {
374 pci_write_config_dword(tp->pdev, TG3PCI_RCV_RET_RING_CON_IDX +
375 TG3_64BIT_REG_LOW, val);
376 return;
377 }
378 if (off == (MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW)) {
379 pci_write_config_dword(tp->pdev, TG3PCI_STD_RING_PROD_IDX +
380 TG3_64BIT_REG_LOW, val);
381 return;
366 } 382 }
383
384 spin_lock_irqsave(&tp->indirect_lock, flags);
385 pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off + 0x5600);
386 pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val);
387 spin_unlock_irqrestore(&tp->indirect_lock, flags);
388
389 /* In indirect mode when disabling interrupts, we also need
390 * to clear the interrupt bit in the GRC local ctrl register.
391 */
392 if ((off == (MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW)) &&
393 (val == 0x1)) {
394 pci_write_config_dword(tp->pdev, TG3PCI_MISC_LOCAL_CTRL,
395 tp->grc_local_ctrl|GRC_LCLCTRL_CLEARINT);
396 }
397}
398
399static u32 tg3_read_indirect_mbox(struct tg3 *tp, u32 off)
400{
401 unsigned long flags;
402 u32 val;
403
404 spin_lock_irqsave(&tp->indirect_lock, flags);
405 pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off + 0x5600);
406 pci_read_config_dword(tp->pdev, TG3PCI_REG_DATA, &val);
407 spin_unlock_irqrestore(&tp->indirect_lock, flags);
408 return val;
409}
410
411static void _tw32_flush(struct tg3 *tp, u32 off, u32 val)
412{
413 tp->write32(tp, off, val);
414 if (!(tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) &&
415 !(tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) &&
416 !(tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND))
417 tp->read32(tp, off); /* flush */
367} 418}
368 419
369static inline void tw32_mailbox_flush(struct tg3 *tp, u32 off, u32 val) 420static inline void tw32_mailbox_flush(struct tg3 *tp, u32 off, u32 val)
370{ 421{
371 tp->write32_mbox(tp, off, val); 422 tp->write32_mbox(tp, off, val);
372 tp->read32_mbox(tp, off); 423 if (!(tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) &&
424 !(tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND))
425 tp->read32_mbox(tp, off);
373} 426}
374 427
375static void tg3_write32_tx_mbox(struct tg3 *tp, u32 off, u32 val) 428static void tg3_write32_tx_mbox(struct tg3 *tp, u32 off, u32 val)
@@ -404,24 +457,28 @@ static u32 tg3_read32(struct tg3 *tp, u32 off)
404 457
405static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) 458static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
406{ 459{
407 spin_lock_bh(&tp->indirect_lock); 460 unsigned long flags;
461
462 spin_lock_irqsave(&tp->indirect_lock, flags);
408 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); 463 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
409 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); 464 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
410 465
411 /* Always leave this as zero. */ 466 /* Always leave this as zero. */
412 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); 467 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
413 spin_unlock_bh(&tp->indirect_lock); 468 spin_unlock_irqrestore(&tp->indirect_lock, flags);
414} 469}
415 470
416static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) 471static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
417{ 472{
418 spin_lock_bh(&tp->indirect_lock); 473 unsigned long flags;
474
475 spin_lock_irqsave(&tp->indirect_lock, flags);
419 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); 476 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
420 pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); 477 pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
421 478
422 /* Always leave this as zero. */ 479 /* Always leave this as zero. */
423 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); 480 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
424 spin_unlock_bh(&tp->indirect_lock); 481 spin_unlock_irqrestore(&tp->indirect_lock, flags);
425} 482}
426 483
427static void tg3_disable_ints(struct tg3 *tp) 484static void tg3_disable_ints(struct tg3 *tp)
@@ -9149,14 +9206,6 @@ static int __devinit tg3_is_sun_570X(struct tg3 *tp)
9149static int __devinit tg3_get_invariants(struct tg3 *tp) 9206static int __devinit tg3_get_invariants(struct tg3 *tp)
9150{ 9207{
9151 static struct pci_device_id write_reorder_chipsets[] = { 9208 static struct pci_device_id write_reorder_chipsets[] = {
9152 { PCI_DEVICE(PCI_VENDOR_ID_INTEL,
9153 PCI_DEVICE_ID_INTEL_82801AA_8) },
9154 { PCI_DEVICE(PCI_VENDOR_ID_INTEL,
9155 PCI_DEVICE_ID_INTEL_82801AB_8) },
9156 { PCI_DEVICE(PCI_VENDOR_ID_INTEL,
9157 PCI_DEVICE_ID_INTEL_82801BA_11) },
9158 { PCI_DEVICE(PCI_VENDOR_ID_INTEL,
9159 PCI_DEVICE_ID_INTEL_82801BA_6) },
9160 { PCI_DEVICE(PCI_VENDOR_ID_AMD, 9209 { PCI_DEVICE(PCI_VENDOR_ID_AMD,
9161 PCI_DEVICE_ID_AMD_FE_GATE_700C) }, 9210 PCI_DEVICE_ID_AMD_FE_GATE_700C) },
9162 { }, 9211 { },
@@ -9173,7 +9222,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
9173 tp->tg3_flags2 |= TG3_FLG2_SUN_570X; 9222 tp->tg3_flags2 |= TG3_FLG2_SUN_570X;
9174#endif 9223#endif
9175 9224
9176 /* If we have an AMD 762 or Intel ICH/ICH0/ICH2 chipset, write 9225 /* If we have an AMD 762 chipset, write
9177 * reordering to the mailbox registers done by the host 9226 * reordering to the mailbox registers done by the host
9178 * controller can cause major troubles. We read back from 9227 * controller can cause major troubles. We read back from
9179 * every mailbox register write to force the writes to be 9228 * every mailbox register write to force the writes to be
@@ -9211,6 +9260,69 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
9211 if (tp->pci_chip_rev_id == CHIPREV_ID_5752_A0_HW) 9260 if (tp->pci_chip_rev_id == CHIPREV_ID_5752_A0_HW)
9212 tp->pci_chip_rev_id = CHIPREV_ID_5752_A0; 9261 tp->pci_chip_rev_id = CHIPREV_ID_5752_A0;
9213 9262
9263 /* If we have 5702/03 A1 or A2 on certain ICH chipsets,
9264 * we need to disable memory and use config. cycles
9265 * only to access all registers. The 5702/03 chips
9266 * can mistakenly decode the special cycles from the
9267 * ICH chipsets as memory write cycles, causing corruption
9268 * of register and memory space. Only certain ICH bridges
9269 * will drive special cycles with non-zero data during the
9270 * address phase which can fall within the 5703's address
9271 * range. This is not an ICH bug as the PCI spec allows
9272 * non-zero address during special cycles. However, only
9273 * these ICH bridges are known to drive non-zero addresses
9274 * during special cycles.
9275 *
9276 * Since special cycles do not cross PCI bridges, we only
9277 * enable this workaround if the 5703 is on the secondary
9278 * bus of these ICH bridges.
9279 */
9280 if ((tp->pci_chip_rev_id == CHIPREV_ID_5703_A1) ||
9281 (tp->pci_chip_rev_id == CHIPREV_ID_5703_A2)) {
9282 static struct tg3_dev_id {
9283 u32 vendor;
9284 u32 device;
9285 u32 rev;
9286 } ich_chipsets[] = {
9287 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_8,
9288 PCI_ANY_ID },
9289 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_8,
9290 PCI_ANY_ID },
9291 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_11,
9292 0xa },
9293 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_6,
9294 PCI_ANY_ID },
9295 { },
9296 };
9297 struct tg3_dev_id *pci_id = &ich_chipsets[0];
9298 struct pci_dev *bridge = NULL;
9299
9300 while (pci_id->vendor != 0) {
9301 bridge = pci_get_device(pci_id->vendor, pci_id->device,
9302 bridge);
9303 if (!bridge) {
9304 pci_id++;
9305 continue;
9306 }
9307 if (pci_id->rev != PCI_ANY_ID) {
9308 u8 rev;
9309
9310 pci_read_config_byte(bridge, PCI_REVISION_ID,
9311 &rev);
9312 if (rev > pci_id->rev)
9313 continue;
9314 }
9315 if (bridge->subordinate &&
9316 (bridge->subordinate->number ==
9317 tp->pdev->bus->number)) {
9318
9319 tp->tg3_flags2 |= TG3_FLG2_ICH_WORKAROUND;
9320 pci_dev_put(bridge);
9321 break;
9322 }
9323 }
9324 }
9325
9214 /* Find msi capability. */ 9326 /* Find msi capability. */
9215 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) 9327 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
9216 tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI); 9328 tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI);
@@ -9342,6 +9454,22 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
9342 tp->write32_rx_mbox = tg3_write_flush_reg32; 9454 tp->write32_rx_mbox = tg3_write_flush_reg32;
9343 } 9455 }
9344 9456
9457 if (tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND) {
9458 tp->read32 = tg3_read_indirect_reg32;
9459 tp->write32 = tg3_write_indirect_reg32;
9460 tp->read32_mbox = tg3_read_indirect_mbox;
9461 tp->write32_mbox = tg3_write_indirect_mbox;
9462 tp->write32_tx_mbox = tg3_write_indirect_mbox;
9463 tp->write32_rx_mbox = tg3_write_indirect_mbox;
9464
9465 iounmap(tp->regs);
9466 tp->regs = 0;
9467
9468 pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd);
9469 pci_cmd &= ~PCI_COMMAND_MEMORY;
9470 pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd);
9471 }
9472
9345 /* Get eeprom hw config before calling tg3_set_power_state(). 9473 /* Get eeprom hw config before calling tg3_set_power_state().
9346 * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be 9474 * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be
9347 * determined before calling tg3_set_power_state() so that 9475 * determined before calling tg3_set_power_state() so that
@@ -10486,7 +10614,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
10486 return 0; 10614 return 0;
10487 10615
10488err_out_iounmap: 10616err_out_iounmap:
10489 iounmap(tp->regs); 10617 if (tp->regs) {
10618 iounmap(tp->regs);
10619 tp->regs = 0;
10620 }
10490 10621
10491err_out_free_dev: 10622err_out_free_dev:
10492 free_netdev(dev); 10623 free_netdev(dev);
@@ -10508,7 +10639,10 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
10508 struct tg3 *tp = netdev_priv(dev); 10639 struct tg3 *tp = netdev_priv(dev);
10509 10640
10510 unregister_netdev(dev); 10641 unregister_netdev(dev);
10511 iounmap(tp->regs); 10642 if (tp->regs) {
10643 iounmap(tp->regs);
10644 tp->regs = 0;
10645 }
10512 free_netdev(dev); 10646 free_netdev(dev);
10513 pci_release_regions(pdev); 10647 pci_release_regions(pdev);
10514 pci_disable_device(pdev); 10648 pci_disable_device(pdev);