drivers/net/wireless/intel/iwlwifi/mld/session-protect.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/intel/iwlwifi/mld/session-protect.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/intel/iwlwifi/mld/session-protect.c
Extension
.c
Size
6142 bytes
Lines
223
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_mld_session_start_data {
	struct iwl_mld *mld;
	struct ieee80211_bss_conf *link_conf;
	bool success;
};

static bool iwl_mld_session_start_fn(struct iwl_notif_wait_data *notif_wait,
				     struct iwl_rx_packet *pkt, void *_data)
{
	struct iwl_session_prot_notif *notif = (void *)pkt->data;
	unsigned int pkt_len = iwl_rx_packet_payload_len(pkt);
	struct iwl_mld_session_start_data *data = _data;
	struct ieee80211_bss_conf *link_conf;
	struct iwl_mld *mld = data->mld;
	int fw_link_id;

	if (IWL_FW_CHECK(mld, pkt_len < sizeof(*notif),
			 "short session prot notif (%d)\n",
			 pkt_len))
		return false;

	fw_link_id = le32_to_cpu(notif->mac_link_id);
	link_conf = iwl_mld_fw_id_to_link_conf(mld, fw_link_id);

	if (link_conf != data->link_conf)
		return false;

	if (!le32_to_cpu(notif->status))
		return true;

	if (notif->start) {
		data->success = true;
		return true;
	}

	return false;
}

int iwl_mld_start_session_protection(struct iwl_mld *mld,
				     struct ieee80211_vif *vif,
				     u32 duration, u32 min_duration,
				     int link_id, unsigned long timeout)
{
	static const u16 start_notif[] = { SESSION_PROTECTION_NOTIF };
	struct iwl_notification_wait start_wait;
	struct iwl_mld_session_start_data data = {
		.mld = mld,
		.link_conf = wiphy_dereference(mld->wiphy,
					       vif->link_conf[link_id]),
	};
	int ret;

	if (WARN_ON(!data.link_conf))
		return -EINVAL;

	iwl_init_notification_wait(&mld->notif_wait, &start_wait,
				   start_notif, ARRAY_SIZE(start_notif),
				   iwl_mld_session_start_fn, &data);

	ret = _iwl_mld_schedule_session_protection(mld, vif, duration,
						   min_duration, link_id);

	if (ret) {
		iwl_remove_notification(&mld->notif_wait, &start_wait);
		return ret == -EALREADY ? 0 : ret;
	}

	ret = iwl_wait_notification(&mld->notif_wait, &start_wait, timeout);
	if (ret)
		return ret;
	return data.success ? 0 : -EIO;
}

int iwl_mld_cancel_session_protection(struct iwl_mld *mld,
				      struct ieee80211_vif *vif,
				      int link_id)
{
	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
	struct iwl_mld_link *link =
		iwl_mld_link_dereference_check(mld_vif, link_id);
	struct iwl_mld_session_protect *session_protect =
		&mld_vif->session_protect;
	struct iwl_session_prot_cmd cmd = {
		.action = cpu_to_le32(FW_CTXT_ACTION_REMOVE),
		.conf_id = cpu_to_le32(SESSION_PROTECT_CONF_ASSOC),
	};
	int ret;

	lockdep_assert_wiphy(mld->wiphy);

Annotation

Implementation Notes