mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-16 18:08:20 +00:00
bnxt: fix bnxt_get_avail_msix() returning negative values
Current net-next/main does not boot for older chipsets e.g. Stratus. Sample dmesg: [ 11.368315] bnxt_en 0000:02:00.0 (unnamed net_device) (uninitialized): Able to reserve only 0 out of 9 requested RX rings [ 11.390181] bnxt_en 0000:02:00.0 (unnamed net_device) (uninitialized): Unable to reserve tx rings [ 11.438780] bnxt_en 0000:02:00.0 (unnamed net_device) (uninitialized): 2nd rings reservation failed. [ 11.487559] bnxt_en 0000:02:00.0 (unnamed net_device) (uninitialized): Not enough rings available. [ 11.506012] bnxt_en 0000:02:00.0: probe with driver bnxt_en failed with error -12 This is caused by bnxt_get_avail_msix() returning a negative value for these chipsets not using the new resource manager i.e. !BNXT_NEW_RM. This in turn causes hwr.cp in __bnxt_reserve_rings() to be set to 0. In the current call stack, __bnxt_reserve_rings() is called from bnxt_set_dflt_rings() before bnxt_init_int_mode(). Therefore, bp->total_irqs is always 0 and for !BNXT_NEW_RM bnxt_get_avail_msix() always returns a negative number. Historically, MSIX vectors were requested by the RoCE driver during run-time and bnxt_get_avail_msix() was used for this purpose. Today, RoCE MSIX vectors are statically allocated. bnxt_get_avail_msix() should only be called for the BNXT_NEW_RM() case to reserve the MSIX ahead of time for RoCE use. bnxt_get_avail_msix() is also be simplified to handle the BNXT_NEW_RM() case only. Fixes: d630624ebd70 ("bnxt_en: Utilize ulp client resources if RoCE is not registered") Signed-off-by: David Wei <dw@davidwei.uk> Reviewed-by: Michael Chan <michael.chan@broadcom.com> Link: https://lore.kernel.org/r/20240502203757.3761827-1-dw@davidwei.uk Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
c1742dcb6b
commit
5bfadc5737
@ -7469,6 +7469,8 @@ static bool bnxt_rings_ok(struct bnxt *bp, struct bnxt_hw_rings *hwr)
|
||||
hwr->stat && (hwr->cp_p5 || !(bp->flags & BNXT_FLAG_CHIP_P5_PLUS));
|
||||
}
|
||||
|
||||
static int bnxt_get_avail_msix(struct bnxt *bp, int num);
|
||||
|
||||
static int __bnxt_reserve_rings(struct bnxt *bp)
|
||||
{
|
||||
struct bnxt_hw_rings hwr = {0};
|
||||
@ -7481,7 +7483,7 @@ static int __bnxt_reserve_rings(struct bnxt *bp)
|
||||
if (!bnxt_need_reserve_rings(bp))
|
||||
return 0;
|
||||
|
||||
if (!bnxt_ulp_registered(bp->edev)) {
|
||||
if (BNXT_NEW_RM(bp) && !bnxt_ulp_registered(bp->edev)) {
|
||||
ulp_msix = bnxt_get_avail_msix(bp, bp->ulp_num_msix_want);
|
||||
if (!ulp_msix)
|
||||
bnxt_set_ulp_stat_ctxs(bp, 0);
|
||||
@ -10484,19 +10486,10 @@ unsigned int bnxt_get_avail_stat_ctxs_for_en(struct bnxt *bp)
|
||||
return bnxt_get_max_func_stat_ctxs(bp) - bnxt_get_func_stat_ctxs(bp);
|
||||
}
|
||||
|
||||
int bnxt_get_avail_msix(struct bnxt *bp, int num)
|
||||
static int bnxt_get_avail_msix(struct bnxt *bp, int num)
|
||||
{
|
||||
int max_cp = bnxt_get_max_func_cp_rings(bp);
|
||||
int max_irq = bnxt_get_max_func_irqs(bp);
|
||||
int total_req = bp->cp_nr_rings + num;
|
||||
int max_idx, avail_msix;
|
||||
|
||||
max_idx = bp->total_irqs;
|
||||
if (!(bp->flags & BNXT_FLAG_CHIP_P5_PLUS))
|
||||
max_idx = min_t(int, bp->total_irqs, max_cp);
|
||||
avail_msix = max_idx - bp->cp_nr_rings;
|
||||
if (!BNXT_NEW_RM(bp) || avail_msix >= num)
|
||||
return avail_msix;
|
||||
|
||||
if (max_irq < total_req) {
|
||||
num = max_irq - bp->cp_nr_rings;
|
||||
@ -10629,7 +10622,7 @@ int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init)
|
||||
if (!bnxt_need_reserve_rings(bp))
|
||||
return 0;
|
||||
|
||||
if (!bnxt_ulp_registered(bp->edev)) {
|
||||
if (BNXT_NEW_RM(bp) && !bnxt_ulp_registered(bp->edev)) {
|
||||
int ulp_msix = bnxt_get_avail_msix(bp, bp->ulp_num_msix_want);
|
||||
|
||||
if (ulp_msix > bp->ulp_num_msix_want)
|
||||
|
@ -2738,7 +2738,6 @@ unsigned int bnxt_get_max_func_stat_ctxs(struct bnxt *bp);
|
||||
unsigned int bnxt_get_avail_stat_ctxs_for_en(struct bnxt *bp);
|
||||
unsigned int bnxt_get_max_func_cp_rings(struct bnxt *bp);
|
||||
unsigned int bnxt_get_avail_cp_rings_for_en(struct bnxt *bp);
|
||||
int bnxt_get_avail_msix(struct bnxt *bp, int num);
|
||||
int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init);
|
||||
void bnxt_tx_disable(struct bnxt *bp);
|
||||
void bnxt_tx_enable(struct bnxt *bp);
|
||||
|
Loading…
x
Reference in New Issue
Block a user