drivers/net/wireless/ath/wil6210/pm.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/ath/wil6210/pm.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/ath/wil6210/pm.c
Extension
.c
Size
10997 bytes
Lines
463
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (test_bit(wil_vif_fwconnecting, vif->status)) {
			wil_dbg_pm(wil, "Delay suspend when connecting\n");
			return false;
		}
		if (is_runtime) {
			wil_dbg_pm(wil, "STA-like interface\n");
			return false;
		}
		break;
	/* AP-like interface - can't suspend */
	default:
		wil_dbg_pm(wil, "AP-like interface\n");
		return false;
	}

	return true;
}

int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime)
{
	int rc = 0, i;
	bool wmi_only = test_bit(WMI_FW_CAPABILITY_WMI_ONLY,
				 wil->fw_capabilities);
	bool active_ifaces;

	wil_dbg_pm(wil, "can_suspend: %s\n", is_runtime ? "runtime" : "system");

	if (wmi_only || debug_fw) {
		wil_dbg_pm(wil, "Deny any suspend - %s mode\n",
			   wmi_only ? "wmi_only" : "debug_fw");
		rc = -EBUSY;
		goto out;
	}
	if (is_runtime && !wil->platform_ops.suspend) {
		rc = -EBUSY;
		goto out;
	}

	mutex_lock(&wil->vif_mutex);
	active_ifaces = wil_has_active_ifaces(wil, true, false);
	mutex_unlock(&wil->vif_mutex);

	if (!active_ifaces) {
		/* can always sleep when down */
		wil_dbg_pm(wil, "Interface is down\n");
		goto out;
	}
	if (test_bit(wil_status_resetting, wil->status)) {
		wil_dbg_pm(wil, "Delay suspend when resetting\n");
		rc = -EBUSY;
		goto out;
	}
	if (wil->recovery_state != fw_recovery_idle) {
		wil_dbg_pm(wil, "Delay suspend during recovery\n");
		rc = -EBUSY;
		goto out;
	}

	/* interface is running */
	mutex_lock(&wil->vif_mutex);
	for (i = 0; i < GET_MAX_VIFS(wil); i++) {
		struct wil6210_vif *vif = wil->vifs[i];

		if (!vif)
			continue;
		if (!wil_can_suspend_vif(wil, vif, is_runtime)) {
			rc = -EBUSY;
			mutex_unlock(&wil->vif_mutex);
			goto out;
		}
	}
	mutex_unlock(&wil->vif_mutex);

out:
	wil_dbg_pm(wil, "can_suspend: %s => %s (%d)\n",
		   is_runtime ? "runtime" : "system", rc ? "No" : "Yes", rc);

	if (rc)
		wil->suspend_stats.rejected_by_host++;

	return rc;
}

static int wil_resume_keep_radio_on(struct wil6210_priv *wil)
{
	int rc = 0;

	/* wil_status_resuming will be cleared when getting
	 * WMI_TRAFFIC_RESUME_EVENTID
	 */

Annotation

Implementation Notes