diff options
author | Eliezer Tamir <eliezert@broadcom.com> | 2008-02-28 14:54:54 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-02-28 14:54:54 -0500 |
commit | 615f8fd9c2ab475c420d5baa7def37c5cb0d50d3 (patch) | |
tree | 754b4dbb9bab483b5fdfc02621657e8dbe7c7d14 /drivers/net/bnx2x.c | |
parent | 0e39e645b3e83873d59b865df2b671c822e2182c (diff) |
[BNX2X]: fix MSI-X/INT#A errata
Errata A0.158 workaround.
Running in INT#A mode after running with MSI-X fails due to a PCI core
bug.
Signed-off-by: Eliezer Tamir <eliezert@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x.c')
-rw-r--r-- | drivers/net/bnx2x.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c index a35feee513db..6f987fa10a6d 100644 --- a/drivers/net/bnx2x.c +++ b/drivers/net/bnx2x.c | |||
@@ -443,7 +443,7 @@ static void bnx2x_panic_dump(struct bnx2x *bp) | |||
443 | DP(BNX2X_MSG_STATS, "stats_state - DISABLE\n"); | 443 | DP(BNX2X_MSG_STATS, "stats_state - DISABLE\n"); |
444 | } | 444 | } |
445 | 445 | ||
446 | static void bnx2x_enable_int(struct bnx2x *bp) | 446 | static void bnx2x_int_enable(struct bnx2x *bp) |
447 | { | 447 | { |
448 | int port = bp->port; | 448 | int port = bp->port; |
449 | u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; | 449 | u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; |
@@ -456,18 +456,26 @@ static void bnx2x_enable_int(struct bnx2x *bp) | |||
456 | HC_CONFIG_0_REG_ATTN_BIT_EN_0); | 456 | HC_CONFIG_0_REG_ATTN_BIT_EN_0); |
457 | } else { | 457 | } else { |
458 | val |= (HC_CONFIG_0_REG_SINGLE_ISR_EN_0 | | 458 | val |= (HC_CONFIG_0_REG_SINGLE_ISR_EN_0 | |
459 | HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 | | ||
459 | HC_CONFIG_0_REG_INT_LINE_EN_0 | | 460 | HC_CONFIG_0_REG_INT_LINE_EN_0 | |
460 | HC_CONFIG_0_REG_ATTN_BIT_EN_0); | 461 | HC_CONFIG_0_REG_ATTN_BIT_EN_0); |
462 | |||
463 | /* Errata A0.158 workaround */ | ||
464 | DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) MSI-X %d\n", | ||
465 | val, port, addr, msix); | ||
466 | |||
467 | REG_WR(bp, addr, val); | ||
468 | |||
461 | val &= ~HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0; | 469 | val &= ~HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0; |
462 | } | 470 | } |
463 | 471 | ||
464 | DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) msi %d\n", | 472 | DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) MSI-X %d\n", |
465 | val, port, addr, msix); | 473 | val, port, addr, msix); |
466 | 474 | ||
467 | REG_WR(bp, addr, val); | 475 | REG_WR(bp, addr, val); |
468 | } | 476 | } |
469 | 477 | ||
470 | static void bnx2x_disable_int(struct bnx2x *bp) | 478 | static void bnx2x_int_disable(struct bnx2x *bp) |
471 | { | 479 | { |
472 | int port = bp->port; | 480 | int port = bp->port; |
473 | u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; | 481 | u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; |
@@ -486,7 +494,7 @@ static void bnx2x_disable_int(struct bnx2x *bp) | |||
486 | BNX2X_ERR("BUG! proper val not read from IGU!\n"); | 494 | BNX2X_ERR("BUG! proper val not read from IGU!\n"); |
487 | } | 495 | } |
488 | 496 | ||
489 | static void bnx2x_disable_int_sync(struct bnx2x *bp) | 497 | static void bnx2x_int_disable_sync(struct bnx2x *bp) |
490 | { | 498 | { |
491 | 499 | ||
492 | int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0; | 500 | int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0; |
@@ -494,7 +502,7 @@ static void bnx2x_disable_int_sync(struct bnx2x *bp) | |||
494 | 502 | ||
495 | atomic_inc(&bp->intr_sem); | 503 | atomic_inc(&bp->intr_sem); |
496 | /* prevent the HW from sending interrupts */ | 504 | /* prevent the HW from sending interrupts */ |
497 | bnx2x_disable_int(bp); | 505 | bnx2x_int_disable(bp); |
498 | 506 | ||
499 | /* make sure all ISRs are done */ | 507 | /* make sure all ISRs are done */ |
500 | if (msix) { | 508 | if (msix) { |
@@ -5710,7 +5718,7 @@ static void bnx2x_nic_init(struct bnx2x *bp) | |||
5710 | bnx2x_init_internal(bp); | 5718 | bnx2x_init_internal(bp); |
5711 | bnx2x_init_stats(bp); | 5719 | bnx2x_init_stats(bp); |
5712 | bnx2x_init_ind_table(bp); | 5720 | bnx2x_init_ind_table(bp); |
5713 | bnx2x_enable_int(bp); | 5721 | bnx2x_int_enable(bp); |
5714 | 5722 | ||
5715 | } | 5723 | } |
5716 | 5724 | ||
@@ -7154,7 +7162,7 @@ stop_netif: | |||
7154 | napi_disable(&bnx2x_fp(bp, i, napi)); | 7162 | napi_disable(&bnx2x_fp(bp, i, napi)); |
7155 | 7163 | ||
7156 | int_disable: | 7164 | int_disable: |
7157 | bnx2x_disable_int_sync(bp); | 7165 | bnx2x_int_disable_sync(bp); |
7158 | 7166 | ||
7159 | bnx2x_free_skbs(bp); | 7167 | bnx2x_free_skbs(bp); |
7160 | bnx2x_free_irq(bp); | 7168 | bnx2x_free_irq(bp); |
@@ -7174,7 +7182,7 @@ static void bnx2x_netif_stop(struct bnx2x *bp) | |||
7174 | bp->rx_mode = BNX2X_RX_MODE_NONE; | 7182 | bp->rx_mode = BNX2X_RX_MODE_NONE; |
7175 | bnx2x_set_storm_rx_mode(bp); | 7183 | bnx2x_set_storm_rx_mode(bp); |
7176 | 7184 | ||
7177 | bnx2x_disable_int_sync(bp); | 7185 | bnx2x_int_disable_sync(bp); |
7178 | bnx2x_link_reset(bp); | 7186 | bnx2x_link_reset(bp); |
7179 | 7187 | ||
7180 | for_each_queue(bp, i) | 7188 | for_each_queue(bp, i) |