drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
Extension
.c
Size
42913 bytes
Lines
1629
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

struct iwl_resume_data {
	struct iwl_priv *priv;
	struct iwlagn_wowlan_status *cmd;
	bool valid;
};

static bool iwl_resume_status_fn(struct iwl_notif_wait_data *notif_wait,
				 struct iwl_rx_packet *pkt, void *data)
{
	struct iwl_resume_data *resume_data = data;
	struct iwl_priv *priv = resume_data->priv;

	if (iwl_rx_packet_payload_len(pkt) != sizeof(*resume_data->cmd)) {
		IWL_ERR(priv, "rx wrong size data\n");
		return true;
	}
	memcpy(resume_data->cmd, pkt->data, sizeof(*resume_data->cmd));
	resume_data->valid = true;

	return true;
}

static int iwlagn_mac_resume(struct ieee80211_hw *hw)
{
	struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
	struct ieee80211_vif *vif;
	u32 base;
	int ret;
	struct error_table_start {
		/* cf. struct iwl_error_event_table */
		u32 valid;
		u32 error_id;
	} err_info;
	struct iwl_notification_wait status_wait;
	static const u16 status_cmd[] = {
		REPLY_WOWLAN_GET_STATUS,
	};
	struct iwlagn_wowlan_status status_data = {};
	struct iwl_resume_data resume_data = {
		.priv = priv,
		.cmd = &status_data,
		.valid = false,
	};
	struct cfg80211_wowlan_wakeup wakeup = {
		.pattern_idx = -1,
	};
#ifdef CONFIG_IWLWIFI_DEBUGFS
	const struct fw_img *img;
#endif

	IWL_DEBUG_MAC80211(priv, "enter\n");
	mutex_lock(&priv->mutex);

	/* we'll clear ctx->vif during iwlagn_prepare_restart() */
	vif = ctx->vif;

	ret = iwl_trans_d3_resume(priv->trans, true);
	if (ret)
		goto out_unlock;

	/* uCode is no longer operating by itself */
	iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_CLR,
		    CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);

	base = priv->device_pointers.error_event_table;
	if (!iwlagn_hw_valid_rtc_data_addr(base)) {
		IWL_WARN(priv, "Invalid error table during resume!\n");
		goto out_unlock;
	}

	iwl_trans_read_mem_bytes(priv->trans, base,
				 &err_info, sizeof(err_info));

	if (err_info.valid) {
		IWL_INFO(priv, "error table is valid (%d, 0x%x)\n",
			 err_info.valid, err_info.error_id);
		if (err_info.error_id == RF_KILL_INDICATOR_FOR_WOWLAN) {
			wakeup.rfkill_release = true;
			ieee80211_report_wowlan_wakeup(vif, &wakeup,
						       GFP_KERNEL);
		}
		goto out_unlock;
	}

#ifdef CONFIG_IWLWIFI_DEBUGFS
	img = &priv->fw->img[IWL_UCODE_WOWLAN];
	if (!priv->wowlan_sram)
		priv->wowlan_sram =
			kzalloc(img->sec[IWL_UCODE_SECTION_DATA].len,

Annotation

Implementation Notes