drivers/net/wireless/intel/iwlwifi/mld/roc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/intel/iwlwifi/mld/roc.c
Extension
.c
Size
6945 bytes
Lines
262
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_roc_iter_data {
	enum iwl_roc_activity activity;
	struct ieee80211_vif *vif;
	bool found;
};

static void iwl_mld_find_roc_vif_iter(void *data, u8 *mac,
				      struct ieee80211_vif *vif)
{
	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
	struct iwl_mld_roc_iter_data *roc_data = data;

	if (mld_vif->roc_activity != roc_data->activity)
		return;

	/* The FW supports one ROC of each type simultaneously */
	if (WARN_ON(roc_data->found)) {
		roc_data->vif = NULL;
		return;
	}

	roc_data->found = true;
	roc_data->vif = vif;
}

static struct ieee80211_vif *
iwl_mld_find_roc_vif(struct iwl_mld *mld, enum iwl_roc_activity activity)
{
	struct iwl_mld_roc_iter_data roc_data = {
		.activity = activity,
		.found = false,
	};

	ieee80211_iterate_active_interfaces_mtx(mld->hw,
						IEEE80211_IFACE_ITER_NORMAL,
						iwl_mld_find_roc_vif_iter,
						&roc_data);

	return roc_data.vif;
}

int iwl_mld_start_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
		      struct ieee80211_channel *channel, int duration,
		      enum ieee80211_roc_type type)
{
	struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw);
	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
	struct iwl_mld_int_sta *aux_sta = &mld_vif->aux_sta;
	struct iwl_roc_req cmd = {
		.action = cpu_to_le32(FW_CTXT_ACTION_ADD),
	};
	enum iwl_roc_activity activity;
	int ret = 0;

	lockdep_assert_wiphy(mld->wiphy);

	if (vif->type != NL80211_IFTYPE_P2P_DEVICE &&
	    vif->type != NL80211_IFTYPE_STATION) {
		IWL_ERR(mld, "NOT SUPPORTED: ROC on vif->type %d\n",
			vif->type);

		return -EOPNOTSUPP;
	}

	if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
		switch (type) {
		case IEEE80211_ROC_TYPE_NORMAL:
			activity = ROC_ACTIVITY_P2P_DISC;
			break;
		case IEEE80211_ROC_TYPE_MGMT_TX:
			activity = ROC_ACTIVITY_P2P_NEG;
			break;
		default:
			WARN_ONCE(1, "Got an invalid P2P ROC type\n");
			return -EINVAL;
		}
	} else {
		activity = ROC_ACTIVITY_HOTSPOT;
	}

	/* The FW supports one ROC of each type simultaneously */
	if (WARN_ON(iwl_mld_find_roc_vif(mld, activity)))
		return -EBUSY;

	ieee80211_iterate_active_interfaces_mtx(mld->hw,
						IEEE80211_IFACE_ITER_NORMAL,
						iwl_mld_vif_iter_emlsr_block_roc,
						&ret);
	if (ret)
		return ret;

Annotation

Implementation Notes