From df149d70e1f34ec4995c8a703dbde38071ff4a05 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sat, 7 Jul 2007 22:51:36 -0700 Subject: [PATCH] [BNX2]: Enhance the heartbeat. In addition to the periodic heartbeat, we're adding a heartbeat request interrupt when the heartbeat is late. This is needed during netpoll where the timer is not available. -rt kernels will also benefit since the timer is not as accurate. [ We discussed this patch last time and we decided that the -rt kernel problem alone did not justify this patch. I think the netpoll problem makes this patch necessary. ] Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 26 ++++++++++++++++++++++---- drivers/net/bnx2.h | 3 +++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index a806a8edec8..e7551040b09 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -1486,6 +1486,20 @@ bnx2_set_default_link(struct bnx2 *bp) bp->advertising = ETHTOOL_ALL_COPPER_SPEED | ADVERTISED_Autoneg; } +static void +bnx2_send_heart_beat(struct bnx2 *bp) +{ + u32 msg; + u32 addr; + + spin_lock(&bp->indirect_lock); + msg = (u32) (++bp->fw_drv_pulse_wr_seq & BNX2_DRV_PULSE_SEQ_MASK); + addr = bp->shmem_base + BNX2_DRV_PULSE_MB; + REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, addr); + REG_WR(bp, BNX2_PCICFG_REG_WINDOW, msg); + spin_unlock(&bp->indirect_lock); +} + static void bnx2_remote_phy_event(struct bnx2 *bp) { @@ -1495,6 +1509,11 @@ bnx2_remote_phy_event(struct bnx2 *bp) msg = REG_RD_IND(bp, bp->shmem_base + BNX2_LINK_STATUS); + if (msg & BNX2_LINK_STATUS_HEART_BEAT_EXPIRED) + bnx2_send_heart_beat(bp); + + msg &= ~BNX2_LINK_STATUS_HEART_BEAT_EXPIRED; + if ((msg & BNX2_LINK_STATUS_LINK_UP) == BNX2_LINK_STATUS_LINK_DOWN) bp->link_up = 0; else { @@ -1572,6 +1591,7 @@ bnx2_set_remote_link(struct bnx2 *bp) break; case BNX2_FW_EVT_CODE_SW_TIMER_EXPIRATION_EVENT: default: + bnx2_send_heart_beat(bp); break; } return 0; @@ -4122,7 +4142,7 @@ bnx2_init_chip(struct bnx2 *bp) rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET, 0); - REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, 0x5ffffff); + REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, BNX2_MISC_ENABLE_DEFAULT); REG_RD(bp, BNX2_MISC_ENABLE_SET_BITS); udelay(20); @@ -4930,7 +4950,6 @@ static void bnx2_timer(unsigned long data) { struct bnx2 *bp = (struct bnx2 *) data; - u32 msg; if (!netif_running(bp->dev)) return; @@ -4938,8 +4957,7 @@ bnx2_timer(unsigned long data) if (atomic_read(&bp->intr_sem) != 0) goto bnx2_restart_timer; - msg = (u32) ++bp->fw_drv_pulse_wr_seq; - REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB, msg); + bnx2_send_heart_beat(bp); bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT); diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 14c0a1e25b1..6dca333855a 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -6338,6 +6338,8 @@ struct l2_fhdr { #define RX_COPY_THRESH 92 +#define BNX2_MISC_ENABLE_DEFAULT 0x7ffffff + #define DMA_READ_CHANS 5 #define DMA_WRITE_CHANS 3 @@ -6839,6 +6841,7 @@ struct fw_info { #define BNX2_LINK_STATUS_SERDES_LINK (1<<20) #define BNX2_LINK_STATUS_PARTNER_AD_2500FULL (1<<21) #define BNX2_LINK_STATUS_PARTNER_AD_2500HALF (1<<22) +#define BNX2_LINK_STATUS_HEART_BEAT_EXPIRED (1<<31) #define BNX2_DRV_PULSE_MB 0x00000010 #define BNX2_DRV_PULSE_SEQ_MASK 0x00007fff -- 2.41.1