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

Commit 271733cf authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville
Browse files

cfg80211: notify drivers about frame registrations



Drivers may need to adjust their filters according
to frame registrations, so notify them about them.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 7a826652
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -1147,6 +1147,9 @@ struct cfg80211_pmksa {
 *	allows the driver to adjust the dynamic ps timeout value.
 * @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold.
 *
 * @mgmt_frame_register: Notify driver that a management frame type was
 *	registered. Note that this callback may not sleep, and cannot run
 *	concurrently with itself.
 */
struct cfg80211_ops {
	int	(*suspend)(struct wiphy *wiphy);
@@ -1297,6 +1300,10 @@ struct cfg80211_ops {
	int	(*set_cqm_rssi_config)(struct wiphy *wiphy,
				       struct net_device *dev,
				       s32 rssi_thold, u32 rssi_hyst);

	void	(*mgmt_frame_register)(struct wiphy *wiphy,
				       struct net_device *dev,
				       u16 frame_type, bool reg);
};

/*
+20 −3
Original line number Diff line number Diff line
@@ -764,6 +764,8 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
				u16 frame_type, const u8 *match_data,
				int match_len)
{
	struct wiphy *wiphy = wdev->wiphy;
	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
	struct cfg80211_mgmt_registration *reg, *nreg;
	int err = 0;
	u16 mgmt_type;
@@ -810,23 +812,38 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
	nreg->frame_type = cpu_to_le16(frame_type);
	list_add(&nreg->list, &wdev->mgmt_registrations);

	if (rdev->ops->mgmt_frame_register)
		rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
					       frame_type, true);

 out:
	spin_unlock_bh(&wdev->mgmt_registrations_lock);

	return err;
}

void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid)
{
	struct wiphy *wiphy = wdev->wiphy;
	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
	struct cfg80211_mgmt_registration *reg, *tmp;

	spin_lock_bh(&wdev->mgmt_registrations_lock);

	list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
		if (reg->nlpid == nlpid) {
		if (reg->nlpid != nlpid)
			continue;

		if (rdev->ops->mgmt_frame_register) {
			u16 frame_type = le16_to_cpu(reg->frame_type);

			rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
						       frame_type, false);
		}

		list_del(&reg->list);
		kfree(reg);
	}
	}

	spin_unlock_bh(&wdev->mgmt_registrations_lock);
}