Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 013290aa authored by Johannes Berg's avatar Johannes Berg Committed by Emmanuel Grumbach
Browse files

iwlwifi: mvm: clean up broadcast station handling



Unify all the functions that handle the per-interface broadcast
station and make them have mvm and vif parameters. While at it,
add a new function to allocate the broadcast station instead of
open-coding it, and make the combined alloc+send and free+send
functions use the alloc/free & send functions.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 110cf810
Loading
Loading
Loading
Loading
+7 −19
Original line number Original line Diff line number Diff line
@@ -971,19 +971,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
	 */
	 */
	if (vif->type == NL80211_IFTYPE_AP ||
	if (vif->type == NL80211_IFTYPE_AP ||
	    vif->type == NL80211_IFTYPE_ADHOC) {
	    vif->type == NL80211_IFTYPE_ADHOC) {
		u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
		ret = iwl_mvm_alloc_bcast_sta(mvm, vif);

		/*
		 * The firmware defines the TFD queue mask to only be relevant
		 * for *unicast* queues, so the multicast (CAB) queue should
		 * be excluded.
		 */
		if (vif->type == NL80211_IFTYPE_AP)
			qmask &= ~BIT(vif->cab_queue);

		ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta,
					       qmask,
					       ieee80211_vif_type_p2p(vif));
		if (ret) {
		if (ret) {
			IWL_ERR(mvm, "Failed to allocate bcast sta\n");
			IWL_ERR(mvm, "Failed to allocate bcast sta\n");
			goto out_release;
			goto out_release;
@@ -1031,7 +1019,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
		if (ret)
		if (ret)
			goto out_unref_phy;
			goto out_unref_phy;


		ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
		ret = iwl_mvm_add_bcast_sta(mvm, vif);
		if (ret)
		if (ret)
			goto out_unbind;
			goto out_unbind;


@@ -1128,13 +1116,13 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
			mvm->noa_duration = 0;
			mvm->noa_duration = 0;
		}
		}
#endif
#endif
		iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta);
		iwl_mvm_dealloc_bcast_sta(mvm, vif);
		goto out_release;
		goto out_release;
	}
	}


	if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
	if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
		mvm->p2p_device_vif = NULL;
		mvm->p2p_device_vif = NULL;
		iwl_mvm_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
		iwl_mvm_rm_bcast_sta(mvm, vif);
		iwl_mvm_binding_remove_vif(mvm, vif);
		iwl_mvm_binding_remove_vif(mvm, vif);
		iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
		iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
		mvmvif->phy_ctxt = NULL;
		mvmvif->phy_ctxt = NULL;
@@ -1633,7 +1621,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,


	/* Send the bcast station. At this stage the TBTT and DTIM time events
	/* Send the bcast station. At this stage the TBTT and DTIM time events
	 * are added and applied to the scheduler */
	 * are added and applied to the scheduler */
	ret = iwl_mvm_send_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
	ret = iwl_mvm_send_add_bcast_sta(mvm, vif);
	if (ret)
	if (ret)
		goto out_unbind;
		goto out_unbind;


@@ -1665,7 +1653,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
out_quota_failed:
out_quota_failed:
	iwl_mvm_power_update_mac(mvm);
	iwl_mvm_power_update_mac(mvm);
	mvmvif->ap_ibss_active = false;
	mvmvif->ap_ibss_active = false;
	iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
	iwl_mvm_send_rm_bcast_sta(mvm, vif);
out_unbind:
out_unbind:
	iwl_mvm_binding_remove_vif(mvm, vif);
	iwl_mvm_binding_remove_vif(mvm, vif);
out_remove:
out_remove:
@@ -1710,7 +1698,7 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
		iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL);
		iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL);


	iwl_mvm_update_quotas(mvm, NULL);
	iwl_mvm_update_quotas(mvm, NULL);
	iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
	iwl_mvm_send_rm_bcast_sta(mvm, vif);
	iwl_mvm_binding_remove_vif(mvm, vif);
	iwl_mvm_binding_remove_vif(mvm, vif);


	iwl_mvm_power_update_mac(mvm);
	iwl_mvm_power_update_mac(mvm);
+42 −19
Original line number Original line Diff line number Diff line
@@ -558,10 +558,10 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
 * @vif: the interface to which the broadcast station is added
 * @vif: the interface to which the broadcast station is added
 * @bsta: the broadcast station to add.
 * @bsta: the broadcast station to add.
 */
 */
int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
			   struct iwl_mvm_int_sta *bsta)
{
{
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
	struct iwl_mvm_int_sta *bsta = &mvmvif->bcast_sta;
	static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
	static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
	const u8 *baddr = _baddr;
	const u8 *baddr = _baddr;


@@ -579,19 +579,40 @@ int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,


/* Send the FW a request to remove the station from it's internal data
/* Send the FW a request to remove the station from it's internal data
 * structures, but DO NOT remove the entry from the local data structures. */
 * structures, but DO NOT remove the entry from the local data structures. */
int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm,
int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
			      struct iwl_mvm_int_sta *bsta)
{
{
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
	int ret;
	int ret;


	lockdep_assert_held(&mvm->mutex);
	lockdep_assert_held(&mvm->mutex);


	ret = iwl_mvm_rm_sta_common(mvm, bsta->sta_id);
	ret = iwl_mvm_rm_sta_common(mvm, mvmvif->bcast_sta.sta_id);
	if (ret)
	if (ret)
		IWL_WARN(mvm, "Failed sending remove station\n");
		IWL_WARN(mvm, "Failed sending remove station\n");
	return ret;
	return ret;
}
}


int iwl_mvm_alloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
{
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
	u32 qmask;

	lockdep_assert_held(&mvm->mutex);

	qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);

	/*
	 * The firmware defines the TFD queue mask to only be relevant
	 * for *unicast* queues, so the multicast (CAB) queue shouldn't
	 * be included.
	 */
	if (vif->type == NL80211_IFTYPE_AP)
		qmask &= ~BIT(vif->cab_queue);

	return iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta, qmask,
					ieee80211_vif_type_p2p(vif));
}

/* Allocate a new station entry for the broadcast station to the given vif,
/* Allocate a new station entry for the broadcast station to the given vif,
 * and send it to the FW.
 * and send it to the FW.
 * Note that each P2P mac should have its own broadcast station.
 * Note that each P2P mac should have its own broadcast station.
@@ -599,45 +620,47 @@ int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm,
 * @mvm: the mvm component
 * @mvm: the mvm component
 * @vif: the interface to which the broadcast station is added
 * @vif: the interface to which the broadcast station is added
 * @bsta: the broadcast station to add. */
 * @bsta: the broadcast station to add. */
int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
			  struct iwl_mvm_int_sta *bsta)
{
{
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
	static const u8 baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
	struct iwl_mvm_int_sta *bsta = &mvmvif->bcast_sta;
	u32 qmask;
	int ret;
	int ret;


	lockdep_assert_held(&mvm->mutex);
	lockdep_assert_held(&mvm->mutex);


	qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
	ret = iwl_mvm_alloc_bcast_sta(mvm, vif);
	ret = iwl_mvm_allocate_int_sta(mvm, bsta, qmask,
				       ieee80211_vif_type_p2p(vif));
	if (ret)
	if (ret)
		return ret;
		return ret;


	ret = iwl_mvm_add_int_sta_common(mvm, bsta, baddr,
	ret = iwl_mvm_send_add_bcast_sta(mvm, vif);
					 mvmvif->id, mvmvif->color);


	if (ret)
	if (ret)
		iwl_mvm_dealloc_int_sta(mvm, bsta);
		iwl_mvm_dealloc_int_sta(mvm, bsta);

	return ret;
	return ret;
}
}


void iwl_mvm_dealloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
{
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);

	iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta);
}

/*
/*
 * Send the FW a request to remove the station from it's internal data
 * Send the FW a request to remove the station from it's internal data
 * structures, and in addition remove it from the local data structure.
 * structures, and in addition remove it from the local data structure.
 */
 */
int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta)
int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
{
{
	int ret;
	int ret;


	lockdep_assert_held(&mvm->mutex);
	lockdep_assert_held(&mvm->mutex);


	ret = iwl_mvm_rm_sta_common(mvm, bsta->sta_id);
	ret = iwl_mvm_send_rm_bcast_sta(mvm, vif);
	if (ret)

		return ret;
	iwl_mvm_dealloc_bcast_sta(mvm, vif);


	iwl_mvm_dealloc_int_sta(mvm, bsta);
	return ret;
	return ret;
}
}


+8 −7
Original line number Original line Diff line number Diff line
@@ -393,13 +393,14 @@ int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta,
			     u32 qmask, enum nl80211_iftype iftype);
			     u32 qmask, enum nl80211_iftype iftype);
void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm,
void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm,
			     struct iwl_mvm_int_sta *sta);
			     struct iwl_mvm_int_sta *sta);
int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,

			   struct iwl_mvm_int_sta *bsta);
int iwl_mvm_alloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm,
int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
			      struct iwl_mvm_int_sta *bsta);
int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
			  struct iwl_mvm_int_sta *bsta);
int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta);
void iwl_mvm_dealloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);

void iwl_mvm_sta_drained_wk(struct work_struct *wk);
void iwl_mvm_sta_drained_wk(struct work_struct *wk);
void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm,
void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm,
				struct ieee80211_sta *sta);
				struct ieee80211_sta *sta);