drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c
Extension
.c
Size
24766 bytes
Lines
916
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 (WARN_ON(!link_conf || !mvm_link_sta)) {
			ret = -EINVAL;
			goto err;
		}

		ret = iwl_mvm_mld_cfg_sta(mvm, sta, vif, link_sta, link_conf,
					  mvm_link_sta);
		if (ret)
			goto err;

		link_sta_added_to_fw |= BIT(link_id);

		if (vif->type == NL80211_IFTYPE_STATION)
			iwl_mvm_mld_set_ap_sta_id(sta, mvm_vif->link[link_id],
						  mvm_link_sta);
	}
	return 0;

err:
	/* remove all already allocated stations in FW */
	for_each_set_bit(link_id, &link_sta_added_to_fw,
			 IEEE80211_MLD_MAX_NUM_LINKS) {
		struct iwl_mvm_link_sta *mvm_link_sta =
			rcu_dereference_protected(mvm_sta->link[link_id],
						  lockdep_is_held(&mvm->mutex));

		iwl_mvm_mld_rm_sta_from_fw(mvm, mvm_link_sta->sta_id);
	}

	/* free all sta resources in the driver */
	iwl_mvm_mld_sta_rm_all_sta_links(mvm, mvm_sta);
	return ret;
}

int iwl_mvm_mld_update_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
			   struct ieee80211_sta *sta)
{
	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
	struct ieee80211_link_sta *link_sta;
	unsigned int link_id;
	int ret = -EINVAL;

	lockdep_assert_held(&mvm->mutex);

	for_each_sta_active_link(vif, sta, link_sta, link_id) {
		struct ieee80211_bss_conf *link_conf =
			link_conf_dereference_protected(vif, link_id);
		struct iwl_mvm_link_sta *mvm_link_sta =
			rcu_dereference_protected(mvm_sta->link[link_id],
						  lockdep_is_held(&mvm->mutex));

		if (WARN_ON(!link_conf || !mvm_link_sta))
			return -EINVAL;

		ret = iwl_mvm_mld_cfg_sta(mvm, sta, vif, link_sta, link_conf,
					  mvm_link_sta);

		if (ret) {
			IWL_ERR(mvm, "Failed to update sta link %d\n", link_id);
			break;
		}
	}

	return ret;
}

static void iwl_mvm_mld_disable_sta_queues(struct iwl_mvm *mvm,
					   struct ieee80211_vif *vif,
					   struct ieee80211_sta *sta)
{
	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
	u32 sta_mask = iwl_mvm_sta_fw_id_mask(mvm, sta, -1);
	int i;

	lockdep_assert_held(&mvm->mutex);

	for (i = 0; i < ARRAY_SIZE(mvm_sta->tid_data); i++) {
		if (mvm_sta->tid_data[i].txq_id == IWL_MVM_INVALID_QUEUE)
			continue;

		iwl_mvm_mld_disable_txq(mvm, sta_mask,
					&mvm_sta->tid_data[i].txq_id, i);
		mvm_sta->tid_data[i].txq_id = IWL_MVM_INVALID_QUEUE;
	}

	for (i = 0; i < ARRAY_SIZE(sta->txq); i++) {
		struct iwl_mvm_txq *mvmtxq =
			iwl_mvm_txq_from_mac80211(sta->txq[i]);

		mvmtxq->txq_id = IWL_MVM_INVALID_QUEUE;

Annotation

Implementation Notes