Merge branch 'bnxt_en-fixes'

Michael Chan says:

====================
bnxt_en: Misc. bug fixes

This series fixes a bug in the driver initialization path, MSIX
setup sequencing issue in the FW error and AER paths, a missing
skb_mark_for_recycle() in the VLAN error path, some ethtool coredump
fixes, an ethtool selftest fix, and an ethtool register dump byte order
fix.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller
2025-04-30 13:03:22 +01:00
4 changed files with 69 additions and 28 deletions

View File

@@ -2015,6 +2015,7 @@ static struct sk_buff *bnxt_rx_vlan(struct sk_buff *skb, u8 cmp_type,
}
return skb;
vlan_err:
skb_mark_for_recycle(skb);
dev_kfree_skb(skb);
return NULL;
}
@@ -11602,6 +11603,9 @@ static void bnxt_init_napi(struct bnxt *bp)
poll_fn = bnxt_poll_p5;
else if (BNXT_CHIP_TYPE_NITRO_A0(bp))
cp_nr_rings--;
set_bit(BNXT_STATE_NAPI_DISABLED, &bp->state);
for (i = 0; i < cp_nr_rings; i++) {
bnapi = bp->bnapi[i];
netif_napi_add_config_locked(bp->dev, &bnapi->napi, poll_fn,
@@ -12321,12 +12325,15 @@ static int bnxt_hwrm_if_change(struct bnxt *bp, bool up)
{
struct hwrm_func_drv_if_change_output *resp;
struct hwrm_func_drv_if_change_input *req;
bool fw_reset = !bp->irq_tbl;
bool resc_reinit = false;
bool caps_change = false;
int rc, retry = 0;
bool fw_reset;
u32 flags = 0;
fw_reset = (bp->fw_reset_state == BNXT_FW_RESET_STATE_ABORT);
bp->fw_reset_state = 0;
if (!(bp->fw_cap & BNXT_FW_CAP_IF_CHANGE))
return 0;
@@ -12395,13 +12402,8 @@ static int bnxt_hwrm_if_change(struct bnxt *bp, bool up)
set_bit(BNXT_STATE_ABORT_ERR, &bp->state);
return rc;
}
/* IRQ will be initialized later in bnxt_request_irq()*/
bnxt_clear_int_mode(bp);
rc = bnxt_init_int_mode(bp);
if (rc) {
clear_bit(BNXT_STATE_FW_RESET_DET, &bp->state);
netdev_err(bp->dev, "init int mode failed\n");
return rc;
}
}
rc = bnxt_cancel_reservations(bp, fw_reset);
}
@@ -14834,7 +14836,7 @@ static void bnxt_fw_reset_abort(struct bnxt *bp, int rc)
clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
if (bp->fw_reset_state != BNXT_FW_RESET_STATE_POLL_VF)
bnxt_dl_health_fw_status_update(bp, false);
bp->fw_reset_state = 0;
bp->fw_reset_state = BNXT_FW_RESET_STATE_ABORT;
netif_close(bp->dev);
}
@@ -16932,10 +16934,9 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
if (!err)
result = PCI_ERS_RESULT_RECOVERED;
/* IRQ will be initialized later in bnxt_io_resume */
bnxt_ulp_irq_stop(bp);
bnxt_clear_int_mode(bp);
err = bnxt_init_int_mode(bp);
bnxt_ulp_irq_restart(bp, err);
}
reset_exit:
@@ -16964,10 +16965,13 @@ static void bnxt_io_resume(struct pci_dev *pdev)
err = bnxt_hwrm_func_qcaps(bp);
if (!err) {
if (netif_running(netdev))
if (netif_running(netdev)) {
err = bnxt_open(netdev);
else
} else {
err = bnxt_reserve_rings(bp, true);
if (!err)
err = bnxt_init_int_mode(bp);
}
}
if (!err)

View File

@@ -2614,6 +2614,7 @@ struct bnxt {
#define BNXT_FW_RESET_STATE_POLL_FW 4
#define BNXT_FW_RESET_STATE_OPENING 5
#define BNXT_FW_RESET_STATE_POLL_FW_DOWN 6
#define BNXT_FW_RESET_STATE_ABORT 7
u16 fw_reset_min_dsecs;
#define BNXT_DFLT_FW_RST_MIN_DSECS 20

View File

@@ -110,20 +110,30 @@ static int bnxt_hwrm_dbg_dma_data(struct bnxt *bp, void *msg,
}
}
if (info->dest_buf) {
if ((info->seg_start + off + len) <=
BNXT_COREDUMP_BUF_LEN(info->buf_len)) {
memcpy(info->dest_buf + off, dma_buf, len);
} else {
rc = -ENOBUFS;
break;
}
}
if (cmn_req->req_type ==
cpu_to_le16(HWRM_DBG_COREDUMP_RETRIEVE))
info->dest_buf_size += len;
if (info->dest_buf) {
if ((info->seg_start + off + len) <=
BNXT_COREDUMP_BUF_LEN(info->buf_len)) {
u16 copylen = min_t(u16, len,
info->dest_buf_size - off);
memcpy(info->dest_buf + off, dma_buf, copylen);
if (copylen < len)
break;
} else {
rc = -ENOBUFS;
if (cmn_req->req_type ==
cpu_to_le16(HWRM_DBG_COREDUMP_LIST)) {
kfree(info->dest_buf);
info->dest_buf = NULL;
}
break;
}
}
if (!(cmn_resp->flags & HWRM_DBG_CMN_FLAGS_MORE))
break;

View File

@@ -2062,6 +2062,17 @@ static int bnxt_get_regs_len(struct net_device *dev)
return reg_len;
}
#define BNXT_PCIE_32B_ENTRY(start, end) \
{ offsetof(struct pcie_ctx_hw_stats, start), \
offsetof(struct pcie_ctx_hw_stats, end) }
static const struct {
u16 start;
u16 end;
} bnxt_pcie_32b_entries[] = {
BNXT_PCIE_32B_ENTRY(pcie_ltssm_histogram[0], pcie_ltssm_histogram[3]),
};
static void bnxt_get_regs(struct net_device *dev, struct ethtool_regs *regs,
void *_p)
{
@@ -2094,12 +2105,27 @@ static void bnxt_get_regs(struct net_device *dev, struct ethtool_regs *regs,
req->pcie_stat_host_addr = cpu_to_le64(hw_pcie_stats_addr);
rc = hwrm_req_send(bp, req);
if (!rc) {
__le64 *src = (__le64 *)hw_pcie_stats;
u64 *dst = (u64 *)(_p + BNXT_PXP_REG_LEN);
int i;
u8 *dst = (u8 *)(_p + BNXT_PXP_REG_LEN);
u8 *src = (u8 *)hw_pcie_stats;
int i, j;
for (i = 0; i < sizeof(*hw_pcie_stats) / sizeof(__le64); i++)
dst[i] = le64_to_cpu(src[i]);
for (i = 0, j = 0; i < sizeof(*hw_pcie_stats); ) {
if (i >= bnxt_pcie_32b_entries[j].start &&
i <= bnxt_pcie_32b_entries[j].end) {
u32 *dst32 = (u32 *)(dst + i);
*dst32 = le32_to_cpu(*(__le32 *)(src + i));
i += 4;
if (i > bnxt_pcie_32b_entries[j].end &&
j < ARRAY_SIZE(bnxt_pcie_32b_entries) - 1)
j++;
} else {
u64 *dst64 = (u64 *)(dst + i);
*dst64 = le64_to_cpu(*(__le64 *)(src + i));
i += 8;
}
}
}
hwrm_req_drop(bp, req);
}
@@ -4991,6 +5017,7 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
if (!bp->num_tests || !BNXT_PF(bp))
return;
memset(buf, 0, sizeof(u64) * bp->num_tests);
if (etest->flags & ETH_TEST_FL_OFFLINE &&
bnxt_ulp_registered(bp->edev)) {
etest->flags |= ETH_TEST_FL_FAILED;
@@ -4998,7 +5025,6 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
return;
}
memset(buf, 0, sizeof(u64) * bp->num_tests);
if (!netif_running(dev)) {
etest->flags |= ETH_TEST_FL_FAILED;
return;