aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom
diff options
context:
space:
mode:
authorYaniv Rosner <yaniv.rosner@broadcom.com>2012-12-01 23:05:54 -0500
committerDavid S. Miller <davem@davemloft.net>2012-12-02 20:23:00 -0500
commit27c1151c324b5a7dacd2d03e54b7c99aa5b67f27 (patch)
tree7e9eec0fdf1dd33e9c245b7525d305e5a0ef7042 /drivers/net/ethernet/broadcom
parentb343d0025b08a1ef543e3cabf8b753d84b938d48 (diff)
bnx2x: Handle a rarely missed interrupt
A rare case of no link due to a missed interrupt may occur due to a race condition between acknowledging the IGU via the BAR and restoring the NIG interrupt mask via the GRC. To solve it, we wait for the IGU ack command to finish prior to restoring the NIG interrupt mask. Signed-off-by: Yaniv Rosner <yaniv.rosner@broadcom.com> Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x.h1
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c15
2 files changed, 16 insertions, 0 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 03647bf3ddb9..02ea644573ca 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -915,6 +915,7 @@ struct bnx2x_common {
915#define BNX2X_IGU_STAS_MSG_VF_CNT 64 915#define BNX2X_IGU_STAS_MSG_VF_CNT 64
916#define BNX2X_IGU_STAS_MSG_PF_CNT 4 916#define BNX2X_IGU_STAS_MSG_PF_CNT 4
917 917
918#define MAX_IGU_ATTN_ACK_TO 100
918/* end of common */ 919/* end of common */
919 920
920/* port */ 921/* port */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 983a0c86ee33..d76ca90eea94 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -3588,6 +3588,21 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
3588 3588
3589 /* now set back the mask */ 3589 /* now set back the mask */
3590 if (asserted & ATTN_NIG_FOR_FUNC) { 3590 if (asserted & ATTN_NIG_FOR_FUNC) {
3591 /* Verify that IGU ack through BAR was written before restoring
3592 * NIG mask. This loop should exit after 2-3 iterations max.
3593 */
3594 if (bp->common.int_block != INT_BLOCK_HC) {
3595 u32 cnt = 0, igu_acked;
3596 do {
3597 igu_acked = REG_RD(bp,
3598 IGU_REG_ATTENTION_ACK_BITS);
3599 } while (((igu_acked & ATTN_NIG_FOR_FUNC) == 0) &&
3600 (++cnt < MAX_IGU_ATTN_ACK_TO));
3601 if (!igu_acked)
3602 DP(NETIF_MSG_HW,
3603 "Failed to verify IGU ack on time\n");
3604 barrier();
3605 }
3591 REG_WR(bp, nig_int_mask_addr, nig_mask); 3606 REG_WR(bp, nig_int_mask_addr, nig_mask);
3592 bnx2x_release_phy_lock(bp); 3607 bnx2x_release_phy_lock(bp);
3593 } 3608 }