Commit e88b9ed3 authored by Kalle Valo's avatar Kalle Valo
Browse files

Merge tag 'ath-current-20240903' of git://git.kernel.org/pub/scm/linux/kernel/git/ath/ath

ath.git patches for v6.11-rc7

We have three patch which address two issues in the ath11k driver
which should be addressed for 6.11-rc7:

One patch fixes a NULL pointer dereference while parsing transmit
power envelope (TPE) information, and the other two patches revert the
hibernation support since it is interfering with suspend on some
platforms. Note the cause of the suspend wakeups is still being
investigated, and it is hoped this can be addressed and hibernation
support can be restored in the near future.
parents 094513f8 2f833e89
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -413,7 +413,7 @@ static int ath11k_ahb_power_up(struct ath11k_base *ab)
	return ret;
}

static void ath11k_ahb_power_down(struct ath11k_base *ab, bool is_suspend)
static void ath11k_ahb_power_down(struct ath11k_base *ab)
{
	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);

@@ -1280,7 +1280,7 @@ static void ath11k_ahb_remove(struct platform_device *pdev)
	struct ath11k_base *ab = platform_get_drvdata(pdev);

	if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) {
		ath11k_ahb_power_down(ab, false);
		ath11k_ahb_power_down(ab);
		ath11k_debugfs_soc_destroy(ab);
		ath11k_qmi_deinit_service(ab);
		goto qmi_fail;
+31 −84
Original line number Diff line number Diff line
@@ -906,6 +906,12 @@ int ath11k_core_suspend(struct ath11k_base *ab)
		return ret;
	}

	ret = ath11k_wow_enable(ab);
	if (ret) {
		ath11k_warn(ab, "failed to enable wow during suspend: %d\n", ret);
		return ret;
	}

	ret = ath11k_dp_rx_pktlog_stop(ab, false);
	if (ret) {
		ath11k_warn(ab, "failed to stop dp rx pktlog during suspend: %d\n",
@@ -916,85 +922,29 @@ int ath11k_core_suspend(struct ath11k_base *ab)
	ath11k_ce_stop_shadow_timers(ab);
	ath11k_dp_stop_shadow_timers(ab);

	/* PM framework skips suspend_late/resume_early callbacks
	 * if other devices report errors in their suspend callbacks.
	 * However ath11k_core_resume() would still be called because
	 * here we return success thus kernel put us on dpm_suspended_list.
	 * Since we won't go through a power down/up cycle, there is
	 * no chance to call complete(&ab->restart_completed) in
	 * ath11k_core_restart(), making ath11k_core_resume() timeout.
	 * So call it here to avoid this issue. This also works in case
	 * no error happens thus suspend_late/resume_early get called,
	 * because it will be reinitialized in ath11k_core_resume_early().
	 */
	complete(&ab->restart_completed);

	return 0;
}
EXPORT_SYMBOL(ath11k_core_suspend);

int ath11k_core_suspend_late(struct ath11k_base *ab)
{
	struct ath11k_pdev *pdev;
	struct ath11k *ar;

	if (!ab->hw_params.supports_suspend)
		return -EOPNOTSUPP;

	/* so far single_pdev_only chips have supports_suspend as true
	 * and only the first pdev is valid.
	 */
	pdev = ath11k_core_get_single_pdev(ab);
	ar = pdev->ar;
	if (!ar || ar->state != ATH11K_STATE_OFF)
		return 0;

	ath11k_hif_irq_disable(ab);
	ath11k_hif_ce_irq_disable(ab);

	ath11k_hif_power_down(ab, true);

	return 0;
	ret = ath11k_hif_suspend(ab);
	if (ret) {
		ath11k_warn(ab, "failed to suspend hif: %d\n", ret);
		return ret;
	}
EXPORT_SYMBOL(ath11k_core_suspend_late);

int ath11k_core_resume_early(struct ath11k_base *ab)
{
	int ret;
	struct ath11k_pdev *pdev;
	struct ath11k *ar;

	if (!ab->hw_params.supports_suspend)
		return -EOPNOTSUPP;

	/* so far single_pdev_only chips have supports_suspend as true
	 * and only the first pdev is valid.
	 */
	pdev = ath11k_core_get_single_pdev(ab);
	ar = pdev->ar;
	if (!ar || ar->state != ATH11K_STATE_OFF)
	return 0;

	reinit_completion(&ab->restart_completed);
	ret = ath11k_hif_power_up(ab);
	if (ret)
		ath11k_warn(ab, "failed to power up hif during resume: %d\n", ret);

	return ret;
}
EXPORT_SYMBOL(ath11k_core_resume_early);
EXPORT_SYMBOL(ath11k_core_suspend);

int ath11k_core_resume(struct ath11k_base *ab)
{
	int ret;
	struct ath11k_pdev *pdev;
	struct ath11k *ar;
	long time_left;

	if (!ab->hw_params.supports_suspend)
		return -EOPNOTSUPP;

	/* so far single_pdev_only chips have supports_suspend as true
	/* so far signle_pdev_only chips have supports_suspend as true
	 * and only the first pdev is valid.
	 */
	pdev = ath11k_core_get_single_pdev(ab);
@@ -1002,30 +952,30 @@ int ath11k_core_resume(struct ath11k_base *ab)
	if (!ar || ar->state != ATH11K_STATE_OFF)
		return 0;

	time_left = wait_for_completion_timeout(&ab->restart_completed,
						ATH11K_RESET_TIMEOUT_HZ);
	if (time_left == 0) {
		ath11k_warn(ab, "timeout while waiting for restart complete");
		return -ETIMEDOUT;
	}

	if (ab->hw_params.current_cc_support &&
	    ar->alpha2[0] != 0 && ar->alpha2[1] != 0) {
		ret = ath11k_reg_set_cc(ar);
	ret = ath11k_hif_resume(ab);
	if (ret) {
			ath11k_warn(ab, "failed to set country code during resume: %d\n",
				    ret);
		ath11k_warn(ab, "failed to resume hif during resume: %d\n", ret);
		return ret;
	}
	}

	ath11k_hif_ce_irq_enable(ab);
	ath11k_hif_irq_enable(ab);

	ret = ath11k_dp_rx_pktlog_start(ab);
	if (ret)
	if (ret) {
		ath11k_warn(ab, "failed to start rx pktlog during resume: %d\n",
			    ret);
		return ret;
	}

	ret = ath11k_wow_wakeup(ab);
	if (ret) {
		ath11k_warn(ab, "failed to wakeup wow during resume: %d\n", ret);
		return ret;
	}

	return 0;
}
EXPORT_SYMBOL(ath11k_core_resume);

static void ath11k_core_check_cc_code_bdfext(const struct dmi_header *hdr, void *data)
@@ -2119,8 +2069,6 @@ static void ath11k_core_restart(struct work_struct *work)

	if (!ab->is_reset)
		ath11k_core_post_reconfigure_recovery(ab);

	complete(&ab->restart_completed);
}

static void ath11k_core_reset(struct work_struct *work)
@@ -2190,7 +2138,7 @@ static void ath11k_core_reset(struct work_struct *work)
	ath11k_hif_irq_disable(ab);
	ath11k_hif_ce_irq_disable(ab);

	ath11k_hif_power_down(ab, false);
	ath11k_hif_power_down(ab);
	ath11k_hif_power_up(ab);

	ath11k_dbg(ab, ATH11K_DBG_BOOT, "reset started\n");
@@ -2263,7 +2211,7 @@ void ath11k_core_deinit(struct ath11k_base *ab)

	mutex_unlock(&ab->core_lock);

	ath11k_hif_power_down(ab, false);
	ath11k_hif_power_down(ab);
	ath11k_mac_destroy(ab);
	ath11k_core_soc_destroy(ab);
	ath11k_fw_destroy(ab);
@@ -2316,7 +2264,6 @@ struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size,
	timer_setup(&ab->rx_replenish_retry, ath11k_ce_rx_replenish_retry, 0);
	init_completion(&ab->htc_suspend);
	init_completion(&ab->wow.wakeup_completed);
	init_completion(&ab->restart_completed);

	ab->dev = dev;
	ab->hif.bus = bus;
+0 −4
Original line number Diff line number Diff line
@@ -1036,8 +1036,6 @@ struct ath11k_base {
		DECLARE_BITMAP(fw_features, ATH11K_FW_FEATURE_COUNT);
	} fw;

	struct completion restart_completed;

#ifdef CONFIG_NL80211_TESTMODE
	struct {
		u32 data_pos;
@@ -1237,10 +1235,8 @@ void ath11k_core_free_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd);
int ath11k_core_check_dt(struct ath11k_base *ath11k);
int ath11k_core_check_smbios(struct ath11k_base *ab);
void ath11k_core_halt(struct ath11k *ar);
int ath11k_core_resume_early(struct ath11k_base *ab);
int ath11k_core_resume(struct ath11k_base *ab);
int ath11k_core_suspend(struct ath11k_base *ab);
int ath11k_core_suspend_late(struct ath11k_base *ab);
void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab);
bool ath11k_core_coldboot_cal_support(struct ath11k_base *ab);

+3 −9
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ struct ath11k_hif_ops {
	int (*start)(struct ath11k_base *ab);
	void (*stop)(struct ath11k_base *ab);
	int (*power_up)(struct ath11k_base *ab);
	void (*power_down)(struct ath11k_base *ab, bool is_suspend);
	void (*power_down)(struct ath11k_base *ab);
	int (*suspend)(struct ath11k_base *ab);
	int (*resume)(struct ath11k_base *ab);
	int (*map_service_to_pipe)(struct ath11k_base *ab, u16 service_id,
@@ -67,18 +67,12 @@ static inline void ath11k_hif_irq_disable(struct ath11k_base *ab)

static inline int ath11k_hif_power_up(struct ath11k_base *ab)
{
	if (!ab->hif.ops->power_up)
		return -EOPNOTSUPP;

	return ab->hif.ops->power_up(ab);
}

static inline void ath11k_hif_power_down(struct ath11k_base *ab, bool is_suspend)
static inline void ath11k_hif_power_down(struct ath11k_base *ab)
{
	if (!ab->hif.ops->power_down)
		return;

	ab->hif.ops->power_down(ab, is_suspend);
	ab->hif.ops->power_down(ab);
}

static inline int ath11k_hif_suspend(struct ath11k_base *ab)
+1 −0
Original line number Diff line number Diff line
@@ -7900,6 +7900,7 @@ static void ath11k_mac_parse_tx_pwr_env(struct ath11k *ar,
	}

	if (psd) {
		arvif->reg_tpc_info.is_psd_power = true;
		arvif->reg_tpc_info.num_pwr_levels = psd->count;

		for (i = 0; i < arvif->reg_tpc_info.num_pwr_levels; i++) {
Loading