diff options
| author | Michael Chan <mchan@broadcom.com> | 2006-03-23 04:11:56 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2006-03-23 04:11:56 -0500 |
| commit | bf5295bba804a6aead9bc1c0d5970173a9d4e08e (patch) | |
| tree | 561708042eb3348d0693f4d2a4035bf4b58fd8e9 /drivers | |
| parent | ca6549af77f0f28ac5d23b662fb8f72713eb16d3 (diff) | |
[BNX2]: Fix link change handling
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>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/net/bnx2.c | 29 | ||||
| -rw-r--r-- | drivers/net/bnx2.h | 1 |
2 files changed, 18 insertions, 12 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 7d213707008a..c56888e66351 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
| @@ -313,8 +313,6 @@ bnx2_disable_int(struct bnx2 *bp) | |||
| 313 | static void | 313 | static void |
| 314 | bnx2_enable_int(struct bnx2 *bp) | 314 | bnx2_enable_int(struct bnx2 *bp) |
| 315 | { | 315 | { |
| 316 | u32 val; | ||
| 317 | |||
| 318 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, | 316 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, |
| 319 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | | 317 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | |
| 320 | BNX2_PCICFG_INT_ACK_CMD_MASK_INT | bp->last_status_idx); | 318 | BNX2_PCICFG_INT_ACK_CMD_MASK_INT | bp->last_status_idx); |
| @@ -322,8 +320,7 @@ bnx2_enable_int(struct bnx2 *bp) | |||
| 322 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, | 320 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, |
| 323 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | bp->last_status_idx); | 321 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | bp->last_status_idx); |
| 324 | 322 | ||
| 325 | val = REG_RD(bp, BNX2_HC_COMMAND); | 323 | REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW); |
| 326 | REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW); | ||
| 327 | } | 324 | } |
| 328 | 325 | ||
| 329 | static void | 326 | static void |
| @@ -1926,6 +1923,13 @@ bnx2_poll(struct net_device *dev, int *budget) | |||
| 1926 | spin_lock(&bp->phy_lock); | 1923 | spin_lock(&bp->phy_lock); |
| 1927 | bnx2_phy_int(bp); | 1924 | bnx2_phy_int(bp); |
| 1928 | spin_unlock(&bp->phy_lock); | 1925 | spin_unlock(&bp->phy_lock); |
| 1926 | |||
| 1927 | /* This is needed to take care of transient status | ||
| 1928 | * during link changes. | ||
| 1929 | */ | ||
| 1930 | REG_WR(bp, BNX2_HC_COMMAND, | ||
| 1931 | bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT); | ||
| 1932 | REG_RD(bp, BNX2_HC_COMMAND); | ||
| 1929 | } | 1933 | } |
| 1930 | 1934 | ||
| 1931 | if (bp->status_blk->status_tx_quick_consumer_index0 != bp->hw_tx_cons) | 1935 | if (bp->status_blk->status_tx_quick_consumer_index0 != bp->hw_tx_cons) |
| @@ -3307,6 +3311,8 @@ bnx2_init_chip(struct bnx2 *bp) | |||
| 3307 | 3311 | ||
| 3308 | udelay(20); | 3312 | udelay(20); |
| 3309 | 3313 | ||
| 3314 | bp->hc_cmd = REG_RD(bp, BNX2_HC_COMMAND); | ||
| 3315 | |||
| 3310 | return rc; | 3316 | return rc; |
| 3311 | } | 3317 | } |
| 3312 | 3318 | ||
| @@ -3746,7 +3752,6 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) | |||
| 3746 | struct sk_buff *skb, *rx_skb; | 3752 | struct sk_buff *skb, *rx_skb; |
| 3747 | unsigned char *packet; | 3753 | unsigned char *packet; |
| 3748 | u16 rx_start_idx, rx_idx; | 3754 | u16 rx_start_idx, rx_idx; |
| 3749 | u32 val; | ||
| 3750 | dma_addr_t map; | 3755 | dma_addr_t map; |
| 3751 | struct tx_bd *txbd; | 3756 | struct tx_bd *txbd; |
| 3752 | struct sw_bd *rx_buf; | 3757 | struct sw_bd *rx_buf; |
| @@ -3777,8 +3782,9 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) | |||
| 3777 | map = pci_map_single(bp->pdev, skb->data, pkt_size, | 3782 | map = pci_map_single(bp->pdev, skb->data, pkt_size, |
| 3778 | PCI_DMA_TODEVICE); | 3783 | PCI_DMA_TODEVICE); |
| 3779 | 3784 | ||
| 3780 | val = REG_RD(bp, BNX2_HC_COMMAND); | 3785 | REG_WR(bp, BNX2_HC_COMMAND, |
| 3781 | REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW_WO_INT); | 3786 | bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT); |
| 3787 | |||
| 3782 | REG_RD(bp, BNX2_HC_COMMAND); | 3788 | REG_RD(bp, BNX2_HC_COMMAND); |
| 3783 | 3789 | ||
| 3784 | udelay(5); | 3790 | udelay(5); |
| @@ -3802,8 +3808,9 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) | |||
| 3802 | 3808 | ||
| 3803 | udelay(100); | 3809 | udelay(100); |
| 3804 | 3810 | ||
| 3805 | val = REG_RD(bp, BNX2_HC_COMMAND); | 3811 | REG_WR(bp, BNX2_HC_COMMAND, |
| 3806 | REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW_WO_INT); | 3812 | bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT); |
| 3813 | |||
| 3807 | REG_RD(bp, BNX2_HC_COMMAND); | 3814 | REG_RD(bp, BNX2_HC_COMMAND); |
| 3808 | 3815 | ||
| 3809 | udelay(5); | 3816 | udelay(5); |
| @@ -3939,7 +3946,6 @@ static int | |||
| 3939 | bnx2_test_intr(struct bnx2 *bp) | 3946 | bnx2_test_intr(struct bnx2 *bp) |
| 3940 | { | 3947 | { |
| 3941 | int i; | 3948 | int i; |
| 3942 | u32 val; | ||
| 3943 | u16 status_idx; | 3949 | u16 status_idx; |
| 3944 | 3950 | ||
| 3945 | if (!netif_running(bp->dev)) | 3951 | if (!netif_running(bp->dev)) |
| @@ -3948,8 +3954,7 @@ bnx2_test_intr(struct bnx2 *bp) | |||
| 3948 | status_idx = REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD) & 0xffff; | 3954 | status_idx = REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD) & 0xffff; |
| 3949 | 3955 | ||
| 3950 | /* This register is not touched during run-time. */ | 3956 | /* This register is not touched during run-time. */ |
| 3951 | val = REG_RD(bp, BNX2_HC_COMMAND); | 3957 | REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW); |
| 3952 | REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW); | ||
| 3953 | REG_RD(bp, BNX2_HC_COMMAND); | 3958 | REG_RD(bp, BNX2_HC_COMMAND); |
| 3954 | 3959 | ||
| 3955 | for (i = 0; i < 10; i++) { | 3960 | for (i = 0; i < 10; i++) { |
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index fd4b7f2eb477..18bc0919cc9e 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h | |||
| @@ -4038,6 +4038,7 @@ struct bnx2 { | |||
| 4038 | struct statistics_block *stats_blk; | 4038 | struct statistics_block *stats_blk; |
| 4039 | dma_addr_t stats_blk_mapping; | 4039 | dma_addr_t stats_blk_mapping; |
| 4040 | 4040 | ||
| 4041 | u32 hc_cmd; | ||
| 4041 | u32 rx_mode; | 4042 | u32 rx_mode; |
| 4042 | 4043 | ||
| 4043 | u16 req_line_speed; | 4044 | u16 req_line_speed; |
