Commit c3812c95 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'bnxt_en-bug-fixes'

Michael Chan says:

====================
bnxt_en: Bug fixes

This bug fix series includes fixes for PCIE AER, a crash that may occur
when doing ethtool -C in the middle of error recovery, and aRFS.
====================

Link: https://lore.kernel.org/r/1667518407-15761-1-git-send-email-michael.chan@broadcom.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 1118b204 02597d39
Loading
Loading
Loading
Loading
+45 −9
Original line number Diff line number Diff line
@@ -9983,17 +9983,12 @@ static int bnxt_try_recover_fw(struct bnxt *bp)
	return -ENODEV;
}

int bnxt_cancel_reservations(struct bnxt *bp, bool fw_reset)
static void bnxt_clear_reservations(struct bnxt *bp, bool fw_reset)
{
	struct bnxt_hw_resc *hw_resc = &bp->hw_resc;
	int rc;

	if (!BNXT_NEW_RM(bp))
		return 0; /* no resource reservations required */

	rc = bnxt_hwrm_func_resc_qcaps(bp, true);
	if (rc)
		netdev_err(bp->dev, "resc_qcaps failed\n");
		return; /* no resource reservations required */

	hw_resc->resv_cp_rings = 0;
	hw_resc->resv_stat_ctxs = 0;
@@ -10006,6 +10001,20 @@ int bnxt_cancel_reservations(struct bnxt *bp, bool fw_reset)
		bp->tx_nr_rings = 0;
		bp->rx_nr_rings = 0;
	}
}

int bnxt_cancel_reservations(struct bnxt *bp, bool fw_reset)
{
	int rc;

	if (!BNXT_NEW_RM(bp))
		return 0; /* no resource reservations required */

	rc = bnxt_hwrm_func_resc_qcaps(bp, true);
	if (rc)
		netdev_err(bp->dev, "resc_qcaps failed\n");

	bnxt_clear_reservations(bp, fw_reset);

	return rc;
}
@@ -12894,8 +12903,8 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
	rcu_read_lock();
	hlist_for_each_entry_rcu(fltr, head, hash) {
		if (bnxt_fltr_match(fltr, new_fltr)) {
			rc = fltr->sw_id;
			rcu_read_unlock();
			rc = 0;
			goto err_free;
		}
	}
@@ -13913,7 +13922,9 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
	pci_ers_result_t result = PCI_ERS_RESULT_DISCONNECT;
	struct net_device *netdev = pci_get_drvdata(pdev);
	struct bnxt *bp = netdev_priv(netdev);
	int err = 0, off;
	int retry = 0;
	int err = 0;
	int off;

	netdev_info(bp->dev, "PCI Slot Reset\n");

@@ -13941,11 +13952,36 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
		pci_restore_state(pdev);
		pci_save_state(pdev);

		bnxt_inv_fw_health_reg(bp);
		bnxt_try_map_fw_health_reg(bp);

		/* In some PCIe AER scenarios, firmware may take up to
		 * 10 seconds to become ready in the worst case.
		 */
		do {
			err = bnxt_try_recover_fw(bp);
			if (!err)
				break;
			retry++;
		} while (retry < BNXT_FW_SLOT_RESET_RETRY);

		if (err) {
			dev_err(&pdev->dev, "Firmware not ready\n");
			goto reset_exit;
		}

		err = bnxt_hwrm_func_reset(bp);
		if (!err)
			result = PCI_ERS_RESULT_RECOVERED;

		bnxt_ulp_irq_stop(bp);
		bnxt_clear_int_mode(bp);
		err = bnxt_init_int_mode(bp);
		bnxt_ulp_irq_restart(bp, err);
	}

reset_exit:
	bnxt_clear_reservations(bp, true);
	rtnl_unlock();

	return result;
+1 −0
Original line number Diff line number Diff line
@@ -1621,6 +1621,7 @@ struct bnxt_fw_health {

#define BNXT_FW_RETRY			5
#define BNXT_FW_IF_RETRY		10
#define BNXT_FW_SLOT_RESET_RETRY	4

enum board_idx {
	BCM57301,
+1 −1
Original line number Diff line number Diff line
@@ -162,7 +162,7 @@ static int bnxt_set_coalesce(struct net_device *dev,
	}

reset_coalesce:
	if (netif_running(dev)) {
	if (test_bit(BNXT_STATE_OPEN, &bp->state)) {
		if (update_stats) {
			rc = bnxt_close_nic(bp, true, false);
			if (!rc)
+2 −1
Original line number Diff line number Diff line
@@ -476,7 +476,8 @@ static int __hwrm_send(struct bnxt *bp, struct bnxt_hwrm_ctx *ctx)
		memset(ctx->resp, 0, PAGE_SIZE);

	req_type = le16_to_cpu(ctx->req->req_type);
	if (BNXT_NO_FW_ACCESS(bp) && req_type != HWRM_FUNC_RESET) {
	if (BNXT_NO_FW_ACCESS(bp) &&
	    (req_type != HWRM_FUNC_RESET && req_type != HWRM_VER_GET)) {
		netdev_dbg(bp->dev, "hwrm req_type 0x%x skipped, FW channel down\n",
			   req_type);
		goto exit;