Commit 10067b50 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'bnxt_en-bug-fixes'

Michael Chan says:

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

These 5 bug fixes are all related to the firmware reset or AER recovery.
2 patches fix the cleanup logic for the workqueue used to handle firmware
reset and recovery. 1 patch ensures that the chip will have the proper
BAR addresses latched after fatal AER recovery.  1 patch fixes the
open path to check for firmware reset abort error.  The last one
sends the fw reset command unconditionally to fix the AER reset logic.
====================

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


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 19c176eb 825741b0
Loading
Loading
Loading
Loading
+31 −18
Original line number Diff line number Diff line
@@ -1160,16 +1160,6 @@ static void bnxt_queue_sp_work(struct bnxt *bp)
		schedule_work(&bp->sp_task);
}

static void bnxt_cancel_sp_work(struct bnxt *bp)
{
	if (BNXT_PF(bp)) {
		flush_workqueue(bnxt_pf_wq);
	} else {
		cancel_work_sync(&bp->sp_task);
		cancel_delayed_work_sync(&bp->fw_reset_task);
	}
}

static void bnxt_sched_reset(struct bnxt *bp, struct bnxt_rx_ring_info *rxr)
{
	if (!rxr->bnapi->in_reset) {
@@ -4362,7 +4352,8 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
	u32 bar_offset = BNXT_GRCPF_REG_CHIMP_COMM;
	u16 dst = BNXT_HWRM_CHNL_CHIMP;

	if (BNXT_NO_FW_ACCESS(bp))
	if (BNXT_NO_FW_ACCESS(bp) &&
	    le16_to_cpu(req->req_type) != HWRM_FUNC_RESET)
		return -EBUSY;

	if (msg_len > BNXT_HWRM_MAX_REQ_LEN) {
@@ -9789,6 +9780,9 @@ int bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
{
	int rc = 0;

	if (test_bit(BNXT_STATE_ABORT_ERR, &bp->state))
		rc = -EIO;
	if (!rc)
		rc = __bnxt_open_nic(bp, irq_re_init, link_re_init);
	if (rc) {
		netdev_err(bp->dev, "nic open fail (rc: %x)\n", rc);
@@ -12108,15 +12102,17 @@ static void bnxt_remove_one(struct pci_dev *pdev)
	if (BNXT_PF(bp))
		bnxt_sriov_disable(bp);

	clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
	bnxt_cancel_sp_work(bp);
	bp->sp_event = 0;

	bnxt_dl_fw_reporters_destroy(bp, true);
	if (BNXT_PF(bp))
		devlink_port_type_clear(&bp->dl_port);
	pci_disable_pcie_error_reporting(pdev);
	unregister_netdev(dev);
	clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
	/* Flush any pending tasks */
	cancel_work_sync(&bp->sp_task);
	cancel_delayed_work_sync(&bp->fw_reset_task);
	bp->sp_event = 0;

	bnxt_dl_fw_reporters_destroy(bp, true);
	bnxt_dl_unregister(bp);
	bnxt_shutdown_tc(bp);

@@ -12860,6 +12856,9 @@ static pci_ers_result_t bnxt_io_error_detected(struct pci_dev *pdev,
		return PCI_ERS_RESULT_DISCONNECT;
	}

	if (state == pci_channel_io_frozen)
		set_bit(BNXT_STATE_PCI_CHANNEL_IO_FROZEN, &bp->state);

	if (netif_running(netdev))
		bnxt_close(netdev);

@@ -12886,7 +12885,7 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
{
	struct net_device *netdev = pci_get_drvdata(pdev);
	struct bnxt *bp = netdev_priv(netdev);
	int err = 0;
	int err = 0, off;
	pci_ers_result_t result = PCI_ERS_RESULT_DISCONNECT;

	netdev_info(bp->dev, "PCI Slot Reset\n");
@@ -12898,6 +12897,20 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
			"Cannot re-enable PCI device after reset.\n");
	} else {
		pci_set_master(pdev);
		/* Upon fatal error, our device internal logic that latches to
		 * BAR value is getting reset and will restore only upon
		 * rewritting the BARs.
		 *
		 * As pci_restore_state() does not re-write the BARs if the
		 * value is same as saved value earlier, driver needs to
		 * write the BARs to 0 to force restore, in case of fatal error.
		 */
		if (test_and_clear_bit(BNXT_STATE_PCI_CHANNEL_IO_FROZEN,
				       &bp->state)) {
			for (off = PCI_BASE_ADDRESS_0;
			     off <= PCI_BASE_ADDRESS_5; off += 4)
				pci_write_config_dword(bp->pdev, off, 0);
		}
		pci_restore_state(pdev);
		pci_save_state(pdev);

+1 −0
Original line number Diff line number Diff line
@@ -1781,6 +1781,7 @@ struct bnxt {
#define BNXT_STATE_ABORT_ERR	5
#define BNXT_STATE_FW_FATAL_COND	6
#define BNXT_STATE_DRV_REGISTERED	7
#define BNXT_STATE_PCI_CHANNEL_IO_FROZEN	8

#define BNXT_NO_FW_ACCESS(bp)					\
	(test_bit(BNXT_STATE_FW_FATAL_COND, &(bp)->state) ||	\