diff options
author | Michael Chan <michael.chan@broadcom.com> | 2018-03-31 13:54:20 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-03-31 23:24:20 -0400 |
commit | fbcfc8e4674156cb7eb3d8054bd4332142d2cc58 (patch) | |
tree | 081395ff312f956c6d56a8472a1f3d1b249227a6 /drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c | |
parent | 4e41dc5deb6e5c36ac5f2e49575485920037b2aa (diff) |
bnxt_en: Reserve completion rings and MSIX for bnxt_re RDMA driver.
Add additional logic to reserve completion rings for the bnxt_re driver
when it requests MSIX vectors. The function bnxt_cp_rings_in_use()
will return the total number of completion rings used by both drivers
that need to be reserved. If the network interface in up, we will
close and open the NIC to reserve the new set of completion rings and
re-initialize the vectors.
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c')
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c index 62636cd44331..2583923df5a1 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c @@ -108,6 +108,7 @@ static int bnxt_req_msix_vecs(struct bnxt_en_dev *edev, int ulp_id, struct bnxt *bp = netdev_priv(dev); int max_idx, max_cp_rings; int avail_msix, i, idx; + int rc = 0; ASSERT_RTNL(); if (ulp_id != BNXT_ROCE_ULP) @@ -120,26 +121,46 @@ static int bnxt_req_msix_vecs(struct bnxt_en_dev *edev, int ulp_id, return -EAGAIN; max_cp_rings = bnxt_get_max_func_cp_rings(bp); - max_idx = min_t(int, bp->total_irqs, max_cp_rings); - avail_msix = max_idx - bp->cp_nr_rings; + avail_msix = bnxt_get_avail_msix(bp, num_msix); if (!avail_msix) return -ENOMEM; if (avail_msix > num_msix) avail_msix = num_msix; - if (bp->flags & BNXT_FLAG_NEW_RM) + if (bp->flags & BNXT_FLAG_NEW_RM) { idx = bp->cp_nr_rings; - else + } else { + max_idx = min_t(int, bp->total_irqs, max_cp_rings); idx = max_idx - avail_msix; + } edev->ulp_tbl[ulp_id].msix_base = idx; + edev->ulp_tbl[ulp_id].msix_requested = avail_msix; + if (bp->total_irqs < (idx + avail_msix)) { + if (netif_running(dev)) { + bnxt_close_nic(bp, true, false); + rc = bnxt_open_nic(bp, true, false); + } else { + rc = bnxt_reserve_rings(bp); + } + } + if (rc) { + edev->ulp_tbl[ulp_id].msix_requested = 0; + return -EAGAIN; + } + + if (bp->flags & BNXT_FLAG_NEW_RM) { + struct bnxt_hw_resc *hw_resc = &bp->hw_resc; + + avail_msix = hw_resc->resv_cp_rings - bp->cp_nr_rings; + edev->ulp_tbl[ulp_id].msix_requested = avail_msix; + } for (i = 0; i < avail_msix; i++) { ent[i].vector = bp->irq_tbl[idx + i].vector; ent[i].ring_idx = idx + i; ent[i].db_offset = (idx + i) * 0x80; } - bnxt_set_max_func_irqs(bp, max_idx - avail_msix); + bnxt_set_max_func_irqs(bp, bnxt_get_max_func_irqs(bp) - avail_msix); bnxt_set_max_func_cp_rings(bp, max_cp_rings - avail_msix); - edev->ulp_tbl[ulp_id].msix_requested = avail_msix; return avail_msix; } @@ -157,7 +178,11 @@ static int bnxt_free_msix_vecs(struct bnxt_en_dev *edev, int ulp_id) msix_requested = edev->ulp_tbl[ulp_id].msix_requested; bnxt_set_max_func_cp_rings(bp, max_cp_rings + msix_requested); edev->ulp_tbl[ulp_id].msix_requested = 0; - bnxt_set_max_func_irqs(bp, bp->total_irqs); + bnxt_set_max_func_irqs(bp, bnxt_get_max_func_irqs(bp) + msix_requested); + if (netif_running(dev)) { + bnxt_close_nic(bp, true, false); + bnxt_open_nic(bp, true, false); + } return 0; } |