Commit 1d52d299 authored by Jérôme Pouiller's avatar Jérôme Pouiller Committed by Greg Kroah-Hartman
Browse files

staging: wfx: add support for 'device too hot' indication



Device is able to detect a high temperature. In this case, the traffic
is not allowed to be sent until the temperature decrease.

This patch detects the warnings raised by the device and stop the
traffic accordingly. It also add a delayed task as safeguard in case the
chip would never send the indication that the temperature decrease.

Signed-off-by: default avatarJérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200427134031.323403-7-Jerome.Pouiller@silabs.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 8e47df5f
Loading
Loading
Loading
Loading
+14 −6
Original line number Diff line number Diff line
@@ -235,12 +235,20 @@ static int hif_suspend_resume_indication(struct wfx_dev *wdev,
	struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);
	const struct hif_ind_suspend_resume_tx *body = buf;

	if (body->suspend_resume_flags.bc_mc_only) {
		WARN_ON(!wvif);
	WARN(!body->suspend_resume_flags.bc_mc_only, "unsupported suspend/resume notification");
		if (body->suspend_resume_flags.resume)
			wfx_suspend_resume_mc(wvif, STA_NOTIFY_AWAKE);
		else
			wfx_suspend_resume_mc(wvif, STA_NOTIFY_SLEEP);
	} else {
		WARN(body->peer_sta_set, "misunderstood indication");
		WARN(hif->interface != 2, "misunderstood indication");
		if (body->suspend_resume_flags.resume)
			wfx_suspend_hot_dev(wdev, STA_NOTIFY_AWAKE);
		else
			wfx_suspend_hot_dev(wdev, STA_NOTIFY_SLEEP);
	}

	return 0;
}
+2 −0
Original line number Diff line number Diff line
@@ -341,6 +341,8 @@ struct wfx_dev *wfx_init_common(struct device *dev,
	mutex_init(&wdev->conf_mutex);
	mutex_init(&wdev->rx_stats_lock);
	init_completion(&wdev->firmware_ready);
	INIT_DELAYED_WORK(&wdev->cooling_timeout_work,
			  wfx_cooling_timeout_work);
	wfx_init_hif_cmd(&wdev->hif_cmd);
	wfx_tx_queues_init(wdev);

+23 −0
Original line number Diff line number Diff line
@@ -38,6 +38,29 @@ u32 wfx_rate_mask_to_hw(struct wfx_dev *wdev, u32 rates)
	return ret;
}

void wfx_cooling_timeout_work(struct work_struct *work)
{
	struct wfx_dev *wdev = container_of(to_delayed_work(work),
					    struct wfx_dev,
					    cooling_timeout_work);

	wdev->chip_frozen = true;
	wfx_tx_unlock(wdev);
}

void wfx_suspend_hot_dev(struct wfx_dev *wdev, enum sta_notify_cmd cmd)
{
	if (cmd == STA_NOTIFY_AWAKE) {
		// Device recover normal temperature
		if (cancel_delayed_work(&wdev->cooling_timeout_work))
			wfx_tx_unlock(wdev);
	} else {
		// Device is too hot
		schedule_delayed_work(&wdev->cooling_timeout_work, 10 * HZ);
		wfx_tx_lock(wdev);
	}
}

static void wfx_filter_beacon(struct wfx_vif *wvif, bool filter_beacon)
{
	const struct hif_ie_table_entry filter_ies[] = {
+2 −0
Original line number Diff line number Diff line
@@ -67,6 +67,8 @@ void wfx_unassign_vif_chanctx(struct ieee80211_hw *hw,
			      struct ieee80211_chanctx_conf *conf);

// WSM Callbacks
void wfx_cooling_timeout_work(struct work_struct *work);
void wfx_suspend_hot_dev(struct wfx_dev *wdev, enum sta_notify_cmd cmd);
void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd cmd);
void wfx_event_report_rssi(struct wfx_vif *wvif, u8 raw_rcpi_rssi);

+1 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ struct wfx_dev {
	struct hif_ind_startup	hw_caps;
	struct wfx_hif		hif;
	struct sl_context	sl;
	struct delayed_work	cooling_timeout_work;
	bool			chip_frozen;
	struct mutex		conf_mutex;