Commit 2603d315 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Kalle Valo says:

====================
wireless fixes for v6.11

Hopefully final fixes for v6.11 and this time only fixes to ath11k
driver. We need to revert hibernation support due to reported
regressions and we have a fix for kernel crash introduced in
v6.11-rc1.

* tag 'wireless-2024-09-04' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless:
  MAINTAINERS: wifi: cw1200: add net-cw1200.h
  Revert "wifi: ath11k: support hibernation"
  Revert "wifi: ath11k: restore country code during resume"
  wifi: ath11k: fix NULL pointer dereference in ath11k_mac_get_eirp_power()
====================

Link: https://patch.msgid.link/20240904135906.5986EC4CECA@smtp.kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 858430db 5872b47c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -5953,6 +5953,7 @@ F: Documentation/process/cve.rst
CW1200 WLAN driver
S:	Orphan
F:	drivers/net/wireless/st/cw1200/
F:	include/linux/platform_data/net-cw1200.h
CX18 VIDEO4LINUX DRIVER
M:	Andy Walls <awalls@md.metrocast.net>
+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)
Loading