Skip to content

Commit

Permalink
[BNX2]: Fix link change handling
Browse files Browse the repository at this point in the history
Fix some link-related problems by doing a coalesce_now after link
change interrupt to flush out the transient link status.

To facilitate this, the host coalesce cmd register value is cached in
the device structure.

Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Michael Chan authored and David S. Miller committed Mar 23, 2006
1 parent ca6549a commit bf5295b
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 12 deletions.
29 changes: 17 additions & 12 deletions drivers/net/bnx2.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,17 +313,14 @@ bnx2_disable_int(struct bnx2 *bp)
static void
bnx2_enable_int(struct bnx2 *bp)
{
u32 val;

REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
BNX2_PCICFG_INT_ACK_CMD_MASK_INT | bp->last_status_idx);

REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | bp->last_status_idx);

val = REG_RD(bp, BNX2_HC_COMMAND);
REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW);
REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW);
}

static void
Expand Down Expand Up @@ -1926,6 +1923,13 @@ bnx2_poll(struct net_device *dev, int *budget)
spin_lock(&bp->phy_lock);
bnx2_phy_int(bp);
spin_unlock(&bp->phy_lock);

/* This is needed to take care of transient status
* during link changes.
*/
REG_WR(bp, BNX2_HC_COMMAND,
bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
REG_RD(bp, BNX2_HC_COMMAND);
}

if (bp->status_blk->status_tx_quick_consumer_index0 != bp->hw_tx_cons)
Expand Down Expand Up @@ -3307,6 +3311,8 @@ bnx2_init_chip(struct bnx2 *bp)

udelay(20);

bp->hc_cmd = REG_RD(bp, BNX2_HC_COMMAND);

return rc;
}

Expand Down Expand Up @@ -3746,7 +3752,6 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
struct sk_buff *skb, *rx_skb;
unsigned char *packet;
u16 rx_start_idx, rx_idx;
u32 val;
dma_addr_t map;
struct tx_bd *txbd;
struct sw_bd *rx_buf;
Expand Down Expand Up @@ -3777,8 +3782,9 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
map = pci_map_single(bp->pdev, skb->data, pkt_size,
PCI_DMA_TODEVICE);

val = REG_RD(bp, BNX2_HC_COMMAND);
REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
REG_WR(bp, BNX2_HC_COMMAND,
bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);

REG_RD(bp, BNX2_HC_COMMAND);

udelay(5);
Expand All @@ -3802,8 +3808,9 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)

udelay(100);

val = REG_RD(bp, BNX2_HC_COMMAND);
REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
REG_WR(bp, BNX2_HC_COMMAND,
bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);

REG_RD(bp, BNX2_HC_COMMAND);

udelay(5);
Expand Down Expand Up @@ -3939,7 +3946,6 @@ static int
bnx2_test_intr(struct bnx2 *bp)
{
int i;
u32 val;
u16 status_idx;

if (!netif_running(bp->dev))
Expand All @@ -3948,8 +3954,7 @@ bnx2_test_intr(struct bnx2 *bp)
status_idx = REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD) & 0xffff;

/* This register is not touched during run-time. */
val = REG_RD(bp, BNX2_HC_COMMAND);
REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW);
REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW);
REG_RD(bp, BNX2_HC_COMMAND);

for (i = 0; i < 10; i++) {
Expand Down
1 change: 1 addition & 0 deletions drivers/net/bnx2.h
Original file line number Diff line number Diff line change
Expand Up @@ -4038,6 +4038,7 @@ struct bnx2 {
struct statistics_block *stats_blk;
dma_addr_t stats_blk_mapping;

u32 hc_cmd;
u32 rx_mode;

u16 req_line_speed;
Expand Down

0 comments on commit bf5295b

Please sign in to comment.