Skip to content

Commit

Permalink
cfg80211: notify drivers about frame registrations
Browse files Browse the repository at this point in the history
Drivers may need to adjust their filters according
to frame registrations, so notify them about them.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Johannes Berg authored and John W. Linville committed Oct 13, 2010
1 parent 7a82665 commit 271733c
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
7 changes: 7 additions & 0 deletions include/net/cfg80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
};

/*
Expand Down
23 changes: 20 additions & 3 deletions net/wireless/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -810,22 +812,37 @@ 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) {
list_del(&reg->list);
kfree(reg);
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);
Expand Down

0 comments on commit 271733c

Please sign in to comment.