diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-09-01 18:02:01 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-09-01 18:02:01 -0400 |
commit | e3ee3b78f83688a0ae4315e8be71b2eac559904a (patch) | |
tree | deb03bcdd020262af450ed23382d7c921263f5cf /drivers/net/tg3.c | |
parent | 91cb70c1769d9b72dd1efe40c31f01005820b09e (diff) | |
parent | 6b39374a27eb4be7e9d82145ae270ba02ea90dc8 (diff) |
/spare/repo/netdev-2.6 branch 'master'
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r-- | drivers/net/tg3.c | 331 |
1 files changed, 238 insertions, 93 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 01419aff333e..af8263a1580e 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -66,8 +66,8 @@ | |||
66 | 66 | ||
67 | #define DRV_MODULE_NAME "tg3" | 67 | #define DRV_MODULE_NAME "tg3" |
68 | #define PFX DRV_MODULE_NAME ": " | 68 | #define PFX DRV_MODULE_NAME ": " |
69 | #define DRV_MODULE_VERSION "3.36" | 69 | #define DRV_MODULE_VERSION "3.37" |
70 | #define DRV_MODULE_RELDATE "August 19, 2005" | 70 | #define DRV_MODULE_RELDATE "August 25, 2005" |
71 | 71 | ||
72 | #define TG3_DEF_MAC_MODE 0 | 72 | #define TG3_DEF_MAC_MODE 0 |
73 | #define TG3_DEF_RX_MODE 0 | 73 | #define TG3_DEF_RX_MODE 0 |
@@ -340,41 +340,92 @@ 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 | unsigned long flags; |
344 | spin_lock_bh(&tp->indirect_lock); | 344 | |
345 | pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off); | 345 | spin_lock_irqsave(&tp->indirect_lock, flags); |
346 | pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val); | 346 | pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off); |
347 | spin_unlock_bh(&tp->indirect_lock); | 347 | pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val); |
348 | } else { | 348 | spin_unlock_irqrestore(&tp->indirect_lock, flags); |
349 | writel(val, tp->regs + off); | 349 | } |
350 | if ((tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) != 0) | 350 | |
351 | readl(tp->regs + off); | 351 | static void tg3_write_flush_reg32(struct tg3 *tp, u32 off, u32 val) |
352 | { | ||
353 | writel(val, tp->regs + off); | ||
354 | readl(tp->regs + off); | ||
355 | } | ||
356 | |||
357 | static u32 tg3_read_indirect_reg32(struct tg3 *tp, u32 off) | ||
358 | { | ||
359 | unsigned long flags; | ||
360 | u32 val; | ||
361 | |||
362 | spin_lock_irqsave(&tp->indirect_lock, flags); | ||
363 | pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off); | ||
364 | pci_read_config_dword(tp->pdev, TG3PCI_REG_DATA, &val); | ||
365 | spin_unlock_irqrestore(&tp->indirect_lock, flags); | ||
366 | return val; | ||
367 | } | ||
368 | |||
369 | static 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; | ||
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); | ||
352 | } | 396 | } |
353 | } | 397 | } |
354 | 398 | ||
399 | static 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 | |||
355 | static void _tw32_flush(struct tg3 *tp, u32 off, u32 val) | 411 | static void _tw32_flush(struct tg3 *tp, u32 off, u32 val) |
356 | { | 412 | { |
357 | if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) { | 413 | tp->write32(tp, off, val); |
358 | spin_lock_bh(&tp->indirect_lock); | 414 | if (!(tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) && |
359 | pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off); | 415 | !(tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) && |
360 | pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val); | 416 | !(tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND)) |
361 | spin_unlock_bh(&tp->indirect_lock); | 417 | tp->read32(tp, off); /* flush */ |
362 | } else { | ||
363 | void __iomem *dest = tp->regs + off; | ||
364 | writel(val, dest); | ||
365 | readl(dest); /* always flush PCI write */ | ||
366 | } | ||
367 | } | 418 | } |
368 | 419 | ||
369 | static inline void _tw32_rx_mbox(struct tg3 *tp, u32 off, u32 val) | 420 | static inline void tw32_mailbox_flush(struct tg3 *tp, u32 off, u32 val) |
370 | { | 421 | { |
371 | void __iomem *mbox = tp->regs + off; | 422 | tp->write32_mbox(tp, off, val); |
372 | writel(val, mbox); | 423 | if (!(tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) && |
373 | if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) | 424 | !(tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND)) |
374 | readl(mbox); | 425 | tp->read32_mbox(tp, off); |
375 | } | 426 | } |
376 | 427 | ||
377 | static inline void _tw32_tx_mbox(struct tg3 *tp, u32 off, u32 val) | 428 | static void tg3_write32_tx_mbox(struct tg3 *tp, u32 off, u32 val) |
378 | { | 429 | { |
379 | void __iomem *mbox = tp->regs + off; | 430 | void __iomem *mbox = tp->regs + off; |
380 | writel(val, mbox); | 431 | writel(val, mbox); |
@@ -384,46 +435,57 @@ static inline void _tw32_tx_mbox(struct tg3 *tp, u32 off, u32 val) | |||
384 | readl(mbox); | 435 | readl(mbox); |
385 | } | 436 | } |
386 | 437 | ||
387 | #define tw32_mailbox(reg, val) writel(((val) & 0xffffffff), tp->regs + (reg)) | 438 | static void tg3_write32(struct tg3 *tp, u32 off, u32 val) |
388 | #define tw32_rx_mbox(reg, val) _tw32_rx_mbox(tp, reg, val) | 439 | { |
389 | #define tw32_tx_mbox(reg, val) _tw32_tx_mbox(tp, reg, val) | 440 | writel(val, tp->regs + off); |
441 | } | ||
442 | |||
443 | static u32 tg3_read32(struct tg3 *tp, u32 off) | ||
444 | { | ||
445 | return (readl(tp->regs + off)); | ||
446 | } | ||
447 | |||
448 | #define tw32_mailbox(reg, val) tp->write32_mbox(tp, reg, val) | ||
449 | #define tw32_mailbox_f(reg, val) tw32_mailbox_flush(tp, (reg), (val)) | ||
450 | #define tw32_rx_mbox(reg, val) tp->write32_rx_mbox(tp, reg, val) | ||
451 | #define tw32_tx_mbox(reg, val) tp->write32_tx_mbox(tp, reg, val) | ||
452 | #define tr32_mailbox(reg) tp->read32_mbox(tp, reg) | ||
390 | 453 | ||
391 | #define tw32(reg,val) tg3_write_indirect_reg32(tp,(reg),(val)) | 454 | #define tw32(reg,val) tp->write32(tp, reg, val) |
392 | #define tw32_f(reg,val) _tw32_flush(tp,(reg),(val)) | 455 | #define tw32_f(reg,val) _tw32_flush(tp,(reg),(val)) |
393 | #define tw16(reg,val) writew(((val) & 0xffff), tp->regs + (reg)) | 456 | #define tr32(reg) tp->read32(tp, reg) |
394 | #define tw8(reg,val) writeb(((val) & 0xff), tp->regs + (reg)) | ||
395 | #define tr32(reg) readl(tp->regs + (reg)) | ||
396 | #define tr16(reg) readw(tp->regs + (reg)) | ||
397 | #define tr8(reg) readb(tp->regs + (reg)) | ||
398 | 457 | ||
399 | static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) | 458 | static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) |
400 | { | 459 | { |
401 | spin_lock_bh(&tp->indirect_lock); | 460 | unsigned long flags; |
461 | |||
462 | spin_lock_irqsave(&tp->indirect_lock, flags); | ||
402 | 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); |
403 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | 464 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); |
404 | 465 | ||
405 | /* Always leave this as zero. */ | 466 | /* Always leave this as zero. */ |
406 | 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); |
407 | spin_unlock_bh(&tp->indirect_lock); | 468 | spin_unlock_irqrestore(&tp->indirect_lock, flags); |
408 | } | 469 | } |
409 | 470 | ||
410 | static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) | 471 | static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) |
411 | { | 472 | { |
412 | spin_lock_bh(&tp->indirect_lock); | 473 | unsigned long flags; |
474 | |||
475 | spin_lock_irqsave(&tp->indirect_lock, flags); | ||
413 | 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); |
414 | pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | 477 | pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); |
415 | 478 | ||
416 | /* Always leave this as zero. */ | 479 | /* Always leave this as zero. */ |
417 | 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); |
418 | spin_unlock_bh(&tp->indirect_lock); | 481 | spin_unlock_irqrestore(&tp->indirect_lock, flags); |
419 | } | 482 | } |
420 | 483 | ||
421 | static void tg3_disable_ints(struct tg3 *tp) | 484 | static void tg3_disable_ints(struct tg3 *tp) |
422 | { | 485 | { |
423 | tw32(TG3PCI_MISC_HOST_CTRL, | 486 | tw32(TG3PCI_MISC_HOST_CTRL, |
424 | (tp->misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT)); | 487 | (tp->misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT)); |
425 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); | 488 | tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); |
426 | tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); | ||
427 | } | 489 | } |
428 | 490 | ||
429 | static inline void tg3_cond_int(struct tg3 *tp) | 491 | static inline void tg3_cond_int(struct tg3 *tp) |
@@ -439,9 +501,8 @@ static void tg3_enable_ints(struct tg3 *tp) | |||
439 | 501 | ||
440 | tw32(TG3PCI_MISC_HOST_CTRL, | 502 | tw32(TG3PCI_MISC_HOST_CTRL, |
441 | (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); | 503 | (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); |
442 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | 504 | tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, |
443 | (tp->last_tag << 24)); | 505 | (tp->last_tag << 24)); |
444 | tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); | ||
445 | tg3_cond_int(tp); | 506 | tg3_cond_int(tp); |
446 | } | 507 | } |
447 | 508 | ||
@@ -472,8 +533,6 @@ static inline unsigned int tg3_has_work(struct tg3 *tp) | |||
472 | */ | 533 | */ |
473 | static void tg3_restart_ints(struct tg3 *tp) | 534 | static void tg3_restart_ints(struct tg3 *tp) |
474 | { | 535 | { |
475 | tw32(TG3PCI_MISC_HOST_CTRL, | ||
476 | (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); | ||
477 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | 536 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, |
478 | tp->last_tag << 24); | 537 | tp->last_tag << 24); |
479 | mmiowb(); | 538 | mmiowb(); |
@@ -3278,9 +3337,8 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
3278 | /* No work, shared interrupt perhaps? re-enable | 3337 | /* No work, shared interrupt perhaps? re-enable |
3279 | * interrupts, and flush that PCI write | 3338 | * interrupts, and flush that PCI write |
3280 | */ | 3339 | */ |
3281 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | 3340 | tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, |
3282 | 0x00000000); | 3341 | 0x00000000); |
3283 | tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); | ||
3284 | } | 3342 | } |
3285 | } else { /* shared interrupt */ | 3343 | } else { /* shared interrupt */ |
3286 | handled = 0; | 3344 | handled = 0; |
@@ -3323,9 +3381,8 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r | |||
3323 | /* no work, shared interrupt perhaps? re-enable | 3381 | /* no work, shared interrupt perhaps? re-enable |
3324 | * interrupts, and flush that PCI write | 3382 | * interrupts, and flush that PCI write |
3325 | */ | 3383 | */ |
3326 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | 3384 | tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, |
3327 | tp->last_tag << 24); | 3385 | tp->last_tag << 24); |
3328 | tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); | ||
3329 | } | 3386 | } |
3330 | } else { /* shared interrupt */ | 3387 | } else { /* shared interrupt */ |
3331 | handled = 0; | 3388 | handled = 0; |
@@ -4216,7 +4273,7 @@ static void tg3_stop_fw(struct tg3 *); | |||
4216 | static int tg3_chip_reset(struct tg3 *tp) | 4273 | static int tg3_chip_reset(struct tg3 *tp) |
4217 | { | 4274 | { |
4218 | u32 val; | 4275 | u32 val; |
4219 | u32 flags_save; | 4276 | void (*write_op)(struct tg3 *, u32, u32); |
4220 | int i; | 4277 | int i; |
4221 | 4278 | ||
4222 | if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) | 4279 | if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) |
@@ -4228,8 +4285,9 @@ static int tg3_chip_reset(struct tg3 *tp) | |||
4228 | * fun things. So, temporarily disable the 5701 | 4285 | * fun things. So, temporarily disable the 5701 |
4229 | * hardware workaround, while we do the reset. | 4286 | * hardware workaround, while we do the reset. |
4230 | */ | 4287 | */ |
4231 | flags_save = tp->tg3_flags; | 4288 | write_op = tp->write32; |
4232 | tp->tg3_flags &= ~TG3_FLAG_5701_REG_WRITE_BUG; | 4289 | if (write_op == tg3_write_flush_reg32) |
4290 | tp->write32 = tg3_write32; | ||
4233 | 4291 | ||
4234 | /* do the reset */ | 4292 | /* do the reset */ |
4235 | val = GRC_MISC_CFG_CORECLK_RESET; | 4293 | val = GRC_MISC_CFG_CORECLK_RESET; |
@@ -4248,8 +4306,8 @@ static int tg3_chip_reset(struct tg3 *tp) | |||
4248 | val |= GRC_MISC_CFG_KEEP_GPHY_POWER; | 4306 | val |= GRC_MISC_CFG_KEEP_GPHY_POWER; |
4249 | tw32(GRC_MISC_CFG, val); | 4307 | tw32(GRC_MISC_CFG, val); |
4250 | 4308 | ||
4251 | /* restore 5701 hardware bug workaround flag */ | 4309 | /* restore 5701 hardware bug workaround write method */ |
4252 | tp->tg3_flags = flags_save; | 4310 | tp->write32 = write_op; |
4253 | 4311 | ||
4254 | /* Unfortunately, we have to delay before the PCI read back. | 4312 | /* Unfortunately, we have to delay before the PCI read back. |
4255 | * Some 575X chips even will not respond to a PCI cfg access | 4313 | * Some 575X chips even will not respond to a PCI cfg access |
@@ -4635,7 +4693,6 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b | |||
4635 | int cpu_scratch_size, struct fw_info *info) | 4693 | int cpu_scratch_size, struct fw_info *info) |
4636 | { | 4694 | { |
4637 | int err, i; | 4695 | int err, i; |
4638 | u32 orig_tg3_flags = tp->tg3_flags; | ||
4639 | void (*write_op)(struct tg3 *, u32, u32); | 4696 | void (*write_op)(struct tg3 *, u32, u32); |
4640 | 4697 | ||
4641 | if (cpu_base == TX_CPU_BASE && | 4698 | if (cpu_base == TX_CPU_BASE && |
@@ -4651,11 +4708,6 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b | |||
4651 | else | 4708 | else |
4652 | write_op = tg3_write_indirect_reg32; | 4709 | write_op = tg3_write_indirect_reg32; |
4653 | 4710 | ||
4654 | /* Force use of PCI config space for indirect register | ||
4655 | * write calls. | ||
4656 | */ | ||
4657 | tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG; | ||
4658 | |||
4659 | /* It is possible that bootcode is still loading at this point. | 4711 | /* It is possible that bootcode is still loading at this point. |
4660 | * Get the nvram lock first before halting the cpu. | 4712 | * Get the nvram lock first before halting the cpu. |
4661 | */ | 4713 | */ |
@@ -4691,7 +4743,6 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b | |||
4691 | err = 0; | 4743 | err = 0; |
4692 | 4744 | ||
4693 | out: | 4745 | out: |
4694 | tp->tg3_flags = orig_tg3_flags; | ||
4695 | return err; | 4746 | return err; |
4696 | } | 4747 | } |
4697 | 4748 | ||
@@ -5808,8 +5859,7 @@ static int tg3_reset_hw(struct tg3 *tp) | |||
5808 | tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl); | 5859 | tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl); |
5809 | udelay(100); | 5860 | udelay(100); |
5810 | 5861 | ||
5811 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0); | 5862 | tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0); |
5812 | tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); | ||
5813 | tp->last_tag = 0; | 5863 | tp->last_tag = 0; |
5814 | 5864 | ||
5815 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { | 5865 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { |
@@ -6198,7 +6248,8 @@ static int tg3_test_interrupt(struct tg3 *tp) | |||
6198 | HOSTCC_MODE_NOW); | 6248 | HOSTCC_MODE_NOW); |
6199 | 6249 | ||
6200 | for (i = 0; i < 5; i++) { | 6250 | for (i = 0; i < 5; i++) { |
6201 | int_mbox = tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); | 6251 | int_mbox = tr32_mailbox(MAILBOX_INTERRUPT_0 + |
6252 | TG3_64BIT_REG_LOW); | ||
6202 | if (int_mbox != 0) | 6253 | if (int_mbox != 0) |
6203 | break; | 6254 | break; |
6204 | msleep(10); | 6255 | msleep(10); |
@@ -6598,10 +6649,10 @@ static int tg3_open(struct net_device *dev) | |||
6598 | 6649 | ||
6599 | /* Mailboxes */ | 6650 | /* Mailboxes */ |
6600 | printk("DEBUG: SNDHOST_PROD[%08x%08x] SNDNIC_PROD[%08x%08x]\n", | 6651 | printk("DEBUG: SNDHOST_PROD[%08x%08x] SNDNIC_PROD[%08x%08x]\n", |
6601 | tr32(MAILBOX_SNDHOST_PROD_IDX_0 + 0x0), | 6652 | tr32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + 0x0), |
6602 | tr32(MAILBOX_SNDHOST_PROD_IDX_0 + 0x4), | 6653 | tr32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + 0x4), |
6603 | tr32(MAILBOX_SNDNIC_PROD_IDX_0 + 0x0), | 6654 | tr32_mailbox(MAILBOX_SNDNIC_PROD_IDX_0 + 0x0), |
6604 | tr32(MAILBOX_SNDNIC_PROD_IDX_0 + 0x4)); | 6655 | tr32_mailbox(MAILBOX_SNDNIC_PROD_IDX_0 + 0x4)); |
6605 | 6656 | ||
6606 | /* NIC side send descriptors. */ | 6657 | /* NIC side send descriptors. */ |
6607 | for (i = 0; i < 6; i++) { | 6658 | for (i = 0; i < 6; i++) { |
@@ -7865,8 +7916,6 @@ static int tg3_test_loopback(struct tg3 *tp) | |||
7865 | 7916 | ||
7866 | err = -EIO; | 7917 | err = -EIO; |
7867 | 7918 | ||
7868 | tg3_abort_hw(tp, 1); | ||
7869 | |||
7870 | tg3_reset_hw(tp); | 7919 | tg3_reset_hw(tp); |
7871 | 7920 | ||
7872 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | | 7921 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | |
@@ -7903,7 +7952,7 @@ static int tg3_test_loopback(struct tg3 *tp) | |||
7903 | num_pkts++; | 7952 | num_pkts++; |
7904 | 7953 | ||
7905 | tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, send_idx); | 7954 | tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, send_idx); |
7906 | tr32(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW); | 7955 | tr32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW); |
7907 | 7956 | ||
7908 | udelay(10); | 7957 | udelay(10); |
7909 | 7958 | ||
@@ -9155,14 +9204,6 @@ static int __devinit tg3_is_sun_570X(struct tg3 *tp) | |||
9155 | static int __devinit tg3_get_invariants(struct tg3 *tp) | 9204 | static int __devinit tg3_get_invariants(struct tg3 *tp) |
9156 | { | 9205 | { |
9157 | static struct pci_device_id write_reorder_chipsets[] = { | 9206 | static struct pci_device_id write_reorder_chipsets[] = { |
9158 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, | ||
9159 | PCI_DEVICE_ID_INTEL_82801AA_8) }, | ||
9160 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, | ||
9161 | PCI_DEVICE_ID_INTEL_82801AB_8) }, | ||
9162 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, | ||
9163 | PCI_DEVICE_ID_INTEL_82801BA_11) }, | ||
9164 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, | ||
9165 | PCI_DEVICE_ID_INTEL_82801BA_6) }, | ||
9166 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, | 9207 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, |
9167 | PCI_DEVICE_ID_AMD_FE_GATE_700C) }, | 9208 | PCI_DEVICE_ID_AMD_FE_GATE_700C) }, |
9168 | { }, | 9209 | { }, |
@@ -9179,7 +9220,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
9179 | tp->tg3_flags2 |= TG3_FLG2_SUN_570X; | 9220 | tp->tg3_flags2 |= TG3_FLG2_SUN_570X; |
9180 | #endif | 9221 | #endif |
9181 | 9222 | ||
9182 | /* If we have an AMD 762 or Intel ICH/ICH0/ICH2 chipset, write | 9223 | /* If we have an AMD 762 chipset, write |
9183 | * reordering to the mailbox registers done by the host | 9224 | * reordering to the mailbox registers done by the host |
9184 | * controller can cause major troubles. We read back from | 9225 | * controller can cause major troubles. We read back from |
9185 | * every mailbox register write to force the writes to be | 9226 | * every mailbox register write to force the writes to be |
@@ -9217,6 +9258,69 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
9217 | if (tp->pci_chip_rev_id == CHIPREV_ID_5752_A0_HW) | 9258 | if (tp->pci_chip_rev_id == CHIPREV_ID_5752_A0_HW) |
9218 | tp->pci_chip_rev_id = CHIPREV_ID_5752_A0; | 9259 | tp->pci_chip_rev_id = CHIPREV_ID_5752_A0; |
9219 | 9260 | ||
9261 | /* If we have 5702/03 A1 or A2 on certain ICH chipsets, | ||
9262 | * we need to disable memory and use config. cycles | ||
9263 | * only to access all registers. The 5702/03 chips | ||
9264 | * can mistakenly decode the special cycles from the | ||
9265 | * ICH chipsets as memory write cycles, causing corruption | ||
9266 | * of register and memory space. Only certain ICH bridges | ||
9267 | * will drive special cycles with non-zero data during the | ||
9268 | * address phase which can fall within the 5703's address | ||
9269 | * range. This is not an ICH bug as the PCI spec allows | ||
9270 | * non-zero address during special cycles. However, only | ||
9271 | * these ICH bridges are known to drive non-zero addresses | ||
9272 | * during special cycles. | ||
9273 | * | ||
9274 | * Since special cycles do not cross PCI bridges, we only | ||
9275 | * enable this workaround if the 5703 is on the secondary | ||
9276 | * bus of these ICH bridges. | ||
9277 | */ | ||
9278 | if ((tp->pci_chip_rev_id == CHIPREV_ID_5703_A1) || | ||
9279 | (tp->pci_chip_rev_id == CHIPREV_ID_5703_A2)) { | ||
9280 | static struct tg3_dev_id { | ||
9281 | u32 vendor; | ||
9282 | u32 device; | ||
9283 | u32 rev; | ||
9284 | } ich_chipsets[] = { | ||
9285 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_8, | ||
9286 | PCI_ANY_ID }, | ||
9287 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_8, | ||
9288 | PCI_ANY_ID }, | ||
9289 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_11, | ||
9290 | 0xa }, | ||
9291 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_6, | ||
9292 | PCI_ANY_ID }, | ||
9293 | { }, | ||
9294 | }; | ||
9295 | struct tg3_dev_id *pci_id = &ich_chipsets[0]; | ||
9296 | struct pci_dev *bridge = NULL; | ||
9297 | |||
9298 | while (pci_id->vendor != 0) { | ||
9299 | bridge = pci_get_device(pci_id->vendor, pci_id->device, | ||
9300 | bridge); | ||
9301 | if (!bridge) { | ||
9302 | pci_id++; | ||
9303 | continue; | ||
9304 | } | ||
9305 | if (pci_id->rev != PCI_ANY_ID) { | ||
9306 | u8 rev; | ||
9307 | |||
9308 | pci_read_config_byte(bridge, PCI_REVISION_ID, | ||
9309 | &rev); | ||
9310 | if (rev > pci_id->rev) | ||
9311 | continue; | ||
9312 | } | ||
9313 | if (bridge->subordinate && | ||
9314 | (bridge->subordinate->number == | ||
9315 | tp->pdev->bus->number)) { | ||
9316 | |||
9317 | tp->tg3_flags2 |= TG3_FLG2_ICH_WORKAROUND; | ||
9318 | pci_dev_put(bridge); | ||
9319 | break; | ||
9320 | } | ||
9321 | } | ||
9322 | } | ||
9323 | |||
9220 | /* Find msi capability. */ | 9324 | /* Find msi capability. */ |
9221 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) | 9325 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) |
9222 | tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI); | 9326 | tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI); |
@@ -9304,6 +9408,12 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
9304 | } | 9408 | } |
9305 | } | 9409 | } |
9306 | 9410 | ||
9411 | /* 5700 BX chips need to have their TX producer index mailboxes | ||
9412 | * written twice to workaround a bug. | ||
9413 | */ | ||
9414 | if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5700_BX) | ||
9415 | tp->tg3_flags |= TG3_FLAG_TXD_MBOX_HWBUG; | ||
9416 | |||
9307 | /* Back to back register writes can cause problems on this chip, | 9417 | /* Back to back register writes can cause problems on this chip, |
9308 | * the workaround is to read back all reg writes except those to | 9418 | * the workaround is to read back all reg writes except those to |
9309 | * mailbox regs. See tg3_write_indirect_reg32(). | 9419 | * mailbox regs. See tg3_write_indirect_reg32(). |
@@ -9327,6 +9437,43 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
9327 | pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, pci_state_reg); | 9437 | pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, pci_state_reg); |
9328 | } | 9438 | } |
9329 | 9439 | ||
9440 | /* Default fast path register access methods */ | ||
9441 | tp->read32 = tg3_read32; | ||
9442 | tp->write32 = tg3_write32; | ||
9443 | tp->read32_mbox = tg3_read32; | ||
9444 | tp->write32_mbox = tg3_write32; | ||
9445 | tp->write32_tx_mbox = tg3_write32; | ||
9446 | tp->write32_rx_mbox = tg3_write32; | ||
9447 | |||
9448 | /* Various workaround register access methods */ | ||
9449 | if (tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) | ||
9450 | tp->write32 = tg3_write_indirect_reg32; | ||
9451 | else if (tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) | ||
9452 | tp->write32 = tg3_write_flush_reg32; | ||
9453 | |||
9454 | if ((tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG) || | ||
9455 | (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)) { | ||
9456 | tp->write32_tx_mbox = tg3_write32_tx_mbox; | ||
9457 | if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) | ||
9458 | tp->write32_rx_mbox = tg3_write_flush_reg32; | ||
9459 | } | ||
9460 | |||
9461 | if (tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND) { | ||
9462 | tp->read32 = tg3_read_indirect_reg32; | ||
9463 | tp->write32 = tg3_write_indirect_reg32; | ||
9464 | tp->read32_mbox = tg3_read_indirect_mbox; | ||
9465 | tp->write32_mbox = tg3_write_indirect_mbox; | ||
9466 | tp->write32_tx_mbox = tg3_write_indirect_mbox; | ||
9467 | tp->write32_rx_mbox = tg3_write_indirect_mbox; | ||
9468 | |||
9469 | iounmap(tp->regs); | ||
9470 | tp->regs = 0; | ||
9471 | |||
9472 | pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd); | ||
9473 | pci_cmd &= ~PCI_COMMAND_MEMORY; | ||
9474 | pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd); | ||
9475 | } | ||
9476 | |||
9330 | /* Get eeprom hw config before calling tg3_set_power_state(). | 9477 | /* Get eeprom hw config before calling tg3_set_power_state(). |
9331 | * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be | 9478 | * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be |
9332 | * determined before calling tg3_set_power_state() so that | 9479 | * determined before calling tg3_set_power_state() so that |
@@ -9541,14 +9688,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
9541 | else | 9688 | else |
9542 | tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES; | 9689 | tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES; |
9543 | 9690 | ||
9544 | /* 5700 BX chips need to have their TX producer index mailboxes | ||
9545 | * written twice to workaround a bug. | ||
9546 | */ | ||
9547 | if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5700_BX) | ||
9548 | tp->tg3_flags |= TG3_FLAG_TXD_MBOX_HWBUG; | ||
9549 | else | ||
9550 | tp->tg3_flags &= ~TG3_FLAG_TXD_MBOX_HWBUG; | ||
9551 | |||
9552 | /* It seems all chips can get confused if TX buffers | 9691 | /* It seems all chips can get confused if TX buffers |
9553 | * straddle the 4GB address boundary in some cases. | 9692 | * straddle the 4GB address boundary in some cases. |
9554 | */ | 9693 | */ |
@@ -10471,7 +10610,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
10471 | return 0; | 10610 | return 0; |
10472 | 10611 | ||
10473 | err_out_iounmap: | 10612 | err_out_iounmap: |
10474 | iounmap(tp->regs); | 10613 | if (tp->regs) { |
10614 | iounmap(tp->regs); | ||
10615 | tp->regs = 0; | ||
10616 | } | ||
10475 | 10617 | ||
10476 | err_out_free_dev: | 10618 | err_out_free_dev: |
10477 | free_netdev(dev); | 10619 | free_netdev(dev); |
@@ -10493,7 +10635,10 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev) | |||
10493 | struct tg3 *tp = netdev_priv(dev); | 10635 | struct tg3 *tp = netdev_priv(dev); |
10494 | 10636 | ||
10495 | unregister_netdev(dev); | 10637 | unregister_netdev(dev); |
10496 | iounmap(tp->regs); | 10638 | if (tp->regs) { |
10639 | iounmap(tp->regs); | ||
10640 | tp->regs = 0; | ||
10641 | } | ||
10497 | free_netdev(dev); | 10642 | free_netdev(dev); |
10498 | pci_release_regions(pdev); | 10643 | pci_release_regions(pdev); |
10499 | pci_disable_device(pdev); | 10644 | pci_disable_device(pdev); |