Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 804d4c5a authored by Eliad Peller's avatar Eliad Peller Committed by Emmanuel Grumbach
Browse files

iwlwifi: pcie: refactor cmd_in_flight set/clear code



A following patche will use trans_pcie->cmd_in_flight
for reference accounting as well. get ready for it.

Signed-off-by: default avatarEliad Peller <eliadx.peller@intel.com>
Reviewed-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 160acc0e
Loading
Loading
Loading
Loading
+66 −36
Original line number Diff line number Diff line
@@ -989,6 +989,65 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
	spin_unlock_bh(&txq->lock);
}

static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans)
{
	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
	int ret;

	lockdep_assert_held(&trans_pcie->reg_lock);

	if (trans_pcie->cmd_in_flight)
		return 0;

	trans_pcie->cmd_in_flight = true;

	/*
	 * wake up the NIC to make sure that the firmware will see the host
	 * command - we will let the NIC sleep once all the host commands
	 * returned. This needs to be done only on NICs that have
	 * apmg_wake_up_wa set.
	 */
	if (trans->cfg->base_params->apmg_wake_up_wa) {
		__iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
					 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
		if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
			udelay(2);

		ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
				   CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
				   (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
				    CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP),
				   15000);
		if (ret < 0) {
			__iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
					CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
			trans_pcie->cmd_in_flight = false;
			IWL_ERR(trans, "Failed to wake NIC for hcmd\n");
			return -EIO;
		}
	}

	return 0;
}

static int iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans)
{
	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);

	lockdep_assert_held(&trans_pcie->reg_lock);

	if (WARN_ON(!trans_pcie->cmd_in_flight))
		return 0;

	trans_pcie->cmd_in_flight = false;

	if (trans->cfg->base_params->apmg_wake_up_wa)
		__iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
					CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);

	return 0;
}

/*
 * iwl_pcie_cmdq_reclaim - Reclaim TX command queue entries already Tx'd
 *
@@ -1024,14 +1083,9 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
		}
	}

	if (trans->cfg->base_params->apmg_wake_up_wa &&
	    q->read_ptr == q->write_ptr) {
	if (q->read_ptr == q->write_ptr) {
		spin_lock_irqsave(&trans_pcie->reg_lock, flags);
		WARN_ON(!trans_pcie->cmd_in_flight);
		trans_pcie->cmd_in_flight = false;
		__iwl_trans_pcie_clear_bit(trans,
					   CSR_GP_CNTRL,
					   CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
		iwl_pcie_clear_cmd_in_flight(trans);
		spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
	}

@@ -1419,36 +1473,12 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
		mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout);

	spin_lock_irqsave(&trans_pcie->reg_lock, flags);

	/*
	 * wake up the NIC to make sure that the firmware will see the host
	 * command - we will let the NIC sleep once all the host commands
	 * returned. This needs to be done only on NICs that have
	 * apmg_wake_up_wa set.
	 */
	if (trans->cfg->base_params->apmg_wake_up_wa &&
	    !trans_pcie->cmd_in_flight) {
		trans_pcie->cmd_in_flight = true;
		__iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
					 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
		if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
			udelay(2);

		ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
				   CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
				   (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
				    CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP),
				   15000);
	ret = iwl_pcie_set_cmd_in_flight(trans);
	if (ret < 0) {
			__iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
				   CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
		idx = ret;
		spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
			trans_pcie->cmd_in_flight = false;
			IWL_ERR(trans, "Failed to wake NIC for hcmd\n");
			idx = -EIO;
		goto out;
	}
	}

	/* Increment and update queue's write index */
	q->write_ptr = iwl_queue_inc_wrap(q->write_ptr);