diff options
Diffstat (limited to 'drivers/net/bnx2.c')
| -rw-r--r-- | drivers/net/bnx2.c | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index d07e3f148951..9e8222f9e90e 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
| @@ -543,9 +543,9 @@ bnx2_free_rx_mem(struct bnx2 *bp) | |||
| 543 | for (j = 0; j < bp->rx_max_pg_ring; j++) { | 543 | for (j = 0; j < bp->rx_max_pg_ring; j++) { |
| 544 | if (rxr->rx_pg_desc_ring[j]) | 544 | if (rxr->rx_pg_desc_ring[j]) |
| 545 | pci_free_consistent(bp->pdev, RXBD_RING_SIZE, | 545 | pci_free_consistent(bp->pdev, RXBD_RING_SIZE, |
| 546 | rxr->rx_pg_desc_ring[i], | 546 | rxr->rx_pg_desc_ring[j], |
| 547 | rxr->rx_pg_desc_mapping[i]); | 547 | rxr->rx_pg_desc_mapping[j]); |
| 548 | rxr->rx_pg_desc_ring[i] = NULL; | 548 | rxr->rx_pg_desc_ring[j] = NULL; |
| 549 | } | 549 | } |
| 550 | if (rxr->rx_pg_ring) | 550 | if (rxr->rx_pg_ring) |
| 551 | vfree(rxr->rx_pg_ring); | 551 | vfree(rxr->rx_pg_ring); |
| @@ -3144,6 +3144,28 @@ bnx2_has_work(struct bnx2_napi *bnapi) | |||
| 3144 | return 0; | 3144 | return 0; |
| 3145 | } | 3145 | } |
| 3146 | 3146 | ||
| 3147 | static void | ||
| 3148 | bnx2_chk_missed_msi(struct bnx2 *bp) | ||
| 3149 | { | ||
| 3150 | struct bnx2_napi *bnapi = &bp->bnx2_napi[0]; | ||
| 3151 | u32 msi_ctrl; | ||
| 3152 | |||
| 3153 | if (bnx2_has_work(bnapi)) { | ||
| 3154 | msi_ctrl = REG_RD(bp, BNX2_PCICFG_MSI_CONTROL); | ||
| 3155 | if (!(msi_ctrl & BNX2_PCICFG_MSI_CONTROL_ENABLE)) | ||
| 3156 | return; | ||
| 3157 | |||
| 3158 | if (bnapi->last_status_idx == bp->idle_chk_status_idx) { | ||
| 3159 | REG_WR(bp, BNX2_PCICFG_MSI_CONTROL, msi_ctrl & | ||
| 3160 | ~BNX2_PCICFG_MSI_CONTROL_ENABLE); | ||
| 3161 | REG_WR(bp, BNX2_PCICFG_MSI_CONTROL, msi_ctrl); | ||
| 3162 | bnx2_msi(bp->irq_tbl[0].vector, bnapi); | ||
| 3163 | } | ||
| 3164 | } | ||
| 3165 | |||
| 3166 | bp->idle_chk_status_idx = bnapi->last_status_idx; | ||
| 3167 | } | ||
| 3168 | |||
| 3147 | static void bnx2_poll_link(struct bnx2 *bp, struct bnx2_napi *bnapi) | 3169 | static void bnx2_poll_link(struct bnx2 *bp, struct bnx2_napi *bnapi) |
| 3148 | { | 3170 | { |
| 3149 | struct status_block *sblk = bnapi->status_blk.msi; | 3171 | struct status_block *sblk = bnapi->status_blk.msi; |
| @@ -3218,14 +3240,15 @@ static int bnx2_poll(struct napi_struct *napi, int budget) | |||
| 3218 | 3240 | ||
| 3219 | work_done = bnx2_poll_work(bp, bnapi, work_done, budget); | 3241 | work_done = bnx2_poll_work(bp, bnapi, work_done, budget); |
| 3220 | 3242 | ||
| 3221 | if (unlikely(work_done >= budget)) | ||
| 3222 | break; | ||
| 3223 | |||
| 3224 | /* bnapi->last_status_idx is used below to tell the hw how | 3243 | /* bnapi->last_status_idx is used below to tell the hw how |
| 3225 | * much work has been processed, so we must read it before | 3244 | * much work has been processed, so we must read it before |
| 3226 | * checking for more work. | 3245 | * checking for more work. |
| 3227 | */ | 3246 | */ |
| 3228 | bnapi->last_status_idx = sblk->status_idx; | 3247 | bnapi->last_status_idx = sblk->status_idx; |
| 3248 | |||
| 3249 | if (unlikely(work_done >= budget)) | ||
| 3250 | break; | ||
| 3251 | |||
| 3229 | rmb(); | 3252 | rmb(); |
| 3230 | if (likely(!bnx2_has_work(bnapi))) { | 3253 | if (likely(!bnx2_has_work(bnapi))) { |
| 3231 | netif_rx_complete(bp->dev, napi); | 3254 | netif_rx_complete(bp->dev, napi); |
| @@ -4570,6 +4593,8 @@ bnx2_init_chip(struct bnx2 *bp) | |||
| 4570 | for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) | 4593 | for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) |
| 4571 | bp->bnx2_napi[i].last_status_idx = 0; | 4594 | bp->bnx2_napi[i].last_status_idx = 0; |
| 4572 | 4595 | ||
| 4596 | bp->idle_chk_status_idx = 0xffff; | ||
| 4597 | |||
| 4573 | bp->rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE; | 4598 | bp->rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE; |
| 4574 | 4599 | ||
| 4575 | /* Set up how to generate a link change interrupt. */ | 4600 | /* Set up how to generate a link change interrupt. */ |
| @@ -5718,6 +5743,10 @@ bnx2_timer(unsigned long data) | |||
| 5718 | if (atomic_read(&bp->intr_sem) != 0) | 5743 | if (atomic_read(&bp->intr_sem) != 0) |
| 5719 | goto bnx2_restart_timer; | 5744 | goto bnx2_restart_timer; |
| 5720 | 5745 | ||
| 5746 | if ((bp->flags & (BNX2_FLAG_USING_MSI | BNX2_FLAG_ONE_SHOT_MSI)) == | ||
| 5747 | BNX2_FLAG_USING_MSI) | ||
| 5748 | bnx2_chk_missed_msi(bp); | ||
| 5749 | |||
| 5721 | bnx2_send_heart_beat(bp); | 5750 | bnx2_send_heart_beat(bp); |
| 5722 | 5751 | ||
| 5723 | bp->stats_blk->stat_FwRxDrop = | 5752 | bp->stats_blk->stat_FwRxDrop = |
