diff options
-rw-r--r-- | include/net/cfg80211.h | 4 | ||||
-rw-r--r-- | include/net/mac80211.h | 1 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 10 | ||||
-rw-r--r-- | net/mac80211/driver-ops.h | 13 | ||||
-rw-r--r-- | net/mac80211/driver-trace.h | 14 | ||||
-rw-r--r-- | net/wireless/core.c | 5 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 4 |
7 files changed, 50 insertions, 1 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index ae3a3bb37bf2..1fd1c4acfc8e 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -1344,6 +1344,9 @@ struct cfg80211_gtk_rekey_data { | |||
1344 | * be %NULL or contain the enabled Wake-on-Wireless triggers that are | 1344 | * be %NULL or contain the enabled Wake-on-Wireless triggers that are |
1345 | * configured for the device. | 1345 | * configured for the device. |
1346 | * @resume: wiphy device needs to be resumed | 1346 | * @resume: wiphy device needs to be resumed |
1347 | * @set_wakeup: Called when WoWLAN is enabled/disabled, use this callback | ||
1348 | * to call device_set_wakeup_enable() to enable/disable wakeup from | ||
1349 | * the device. | ||
1347 | * | 1350 | * |
1348 | * @add_virtual_intf: create a new virtual interface with the given name, | 1351 | * @add_virtual_intf: create a new virtual interface with the given name, |
1349 | * must set the struct wireless_dev's iftype. Beware: You must create | 1352 | * must set the struct wireless_dev's iftype. Beware: You must create |
@@ -1515,6 +1518,7 @@ struct cfg80211_gtk_rekey_data { | |||
1515 | struct cfg80211_ops { | 1518 | struct cfg80211_ops { |
1516 | int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); | 1519 | int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); |
1517 | int (*resume)(struct wiphy *wiphy); | 1520 | int (*resume)(struct wiphy *wiphy); |
1521 | void (*set_wakeup)(struct wiphy *wiphy, bool enabled); | ||
1518 | 1522 | ||
1519 | struct net_device * (*add_virtual_intf)(struct wiphy *wiphy, | 1523 | struct net_device * (*add_virtual_intf)(struct wiphy *wiphy, |
1520 | char *name, | 1524 | char *name, |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index ec4995d0c14d..838a4db1c848 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -2233,6 +2233,7 @@ struct ieee80211_ops { | |||
2233 | #ifdef CONFIG_PM | 2233 | #ifdef CONFIG_PM |
2234 | int (*suspend)(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan); | 2234 | int (*suspend)(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan); |
2235 | int (*resume)(struct ieee80211_hw *hw); | 2235 | int (*resume)(struct ieee80211_hw *hw); |
2236 | void (*set_wakeup)(struct ieee80211_hw *hw, bool enabled); | ||
2236 | #endif | 2237 | #endif |
2237 | int (*add_interface)(struct ieee80211_hw *hw, | 2238 | int (*add_interface)(struct ieee80211_hw *hw, |
2238 | struct ieee80211_vif *vif); | 2239 | struct ieee80211_vif *vif); |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index d6163b98f7b7..355735491252 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -2695,6 +2695,13 @@ ieee80211_wiphy_get_channel(struct wiphy *wiphy) | |||
2695 | return local->oper_channel; | 2695 | return local->oper_channel; |
2696 | } | 2696 | } |
2697 | 2697 | ||
2698 | #ifdef CONFIG_PM | ||
2699 | static void ieee80211_set_wakeup(struct wiphy *wiphy, bool enabled) | ||
2700 | { | ||
2701 | drv_set_wakeup(wiphy_priv(wiphy), enabled); | ||
2702 | } | ||
2703 | #endif | ||
2704 | |||
2698 | struct cfg80211_ops mac80211_config_ops = { | 2705 | struct cfg80211_ops mac80211_config_ops = { |
2699 | .add_virtual_intf = ieee80211_add_iface, | 2706 | .add_virtual_intf = ieee80211_add_iface, |
2700 | .del_virtual_intf = ieee80211_del_iface, | 2707 | .del_virtual_intf = ieee80211_del_iface, |
@@ -2763,4 +2770,7 @@ struct cfg80211_ops mac80211_config_ops = { | |||
2763 | .probe_client = ieee80211_probe_client, | 2770 | .probe_client = ieee80211_probe_client, |
2764 | .get_channel = ieee80211_wiphy_get_channel, | 2771 | .get_channel = ieee80211_wiphy_get_channel, |
2765 | .set_noack_map = ieee80211_set_noack_map, | 2772 | .set_noack_map = ieee80211_set_noack_map, |
2773 | #ifdef CONFIG_PM | ||
2774 | .set_wakeup = ieee80211_set_wakeup, | ||
2775 | #endif | ||
2766 | }; | 2776 | }; |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 492c08c27c5f..4a0e559cb26b 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -91,6 +91,19 @@ static inline int drv_resume(struct ieee80211_local *local) | |||
91 | trace_drv_return_int(local, ret); | 91 | trace_drv_return_int(local, ret); |
92 | return ret; | 92 | return ret; |
93 | } | 93 | } |
94 | |||
95 | static inline void drv_set_wakeup(struct ieee80211_local *local, | ||
96 | bool enabled) | ||
97 | { | ||
98 | might_sleep(); | ||
99 | |||
100 | if (!local->ops->set_wakeup) | ||
101 | return; | ||
102 | |||
103 | trace_drv_set_wakeup(local, enabled); | ||
104 | local->ops->set_wakeup(&local->hw, enabled); | ||
105 | trace_drv_return_void(local); | ||
106 | } | ||
94 | #endif | 107 | #endif |
95 | 108 | ||
96 | static inline int drv_add_interface(struct ieee80211_local *local, | 109 | static inline int drv_add_interface(struct ieee80211_local *local, |
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index d1f017a11988..7c0754bed61b 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h | |||
@@ -171,6 +171,20 @@ DEFINE_EVENT(local_only_evt, drv_resume, | |||
171 | TP_ARGS(local) | 171 | TP_ARGS(local) |
172 | ); | 172 | ); |
173 | 173 | ||
174 | TRACE_EVENT(drv_set_wakeup, | ||
175 | TP_PROTO(struct ieee80211_local *local, bool enabled), | ||
176 | TP_ARGS(local, enabled), | ||
177 | TP_STRUCT__entry( | ||
178 | LOCAL_ENTRY | ||
179 | __field(bool, enabled) | ||
180 | ), | ||
181 | TP_fast_assign( | ||
182 | LOCAL_ASSIGN; | ||
183 | __entry->enabled = enabled; | ||
184 | ), | ||
185 | TP_printk(LOCAL_PR_FMT " enabled:%d", LOCAL_PR_ARG, __entry->enabled) | ||
186 | ); | ||
187 | |||
174 | DEFINE_EVENT(local_only_evt, drv_stop, | 188 | DEFINE_EVENT(local_only_evt, drv_stop, |
175 | TP_PROTO(struct ieee80211_local *local), | 189 | TP_PROTO(struct ieee80211_local *local), |
176 | TP_ARGS(local) | 190 | TP_ARGS(local) |
diff --git a/net/wireless/core.c b/net/wireless/core.c index ccdfed897651..59f4a7e7c092 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -708,6 +708,10 @@ void wiphy_unregister(struct wiphy *wiphy) | |||
708 | flush_work(&rdev->scan_done_wk); | 708 | flush_work(&rdev->scan_done_wk); |
709 | cancel_work_sync(&rdev->conn_work); | 709 | cancel_work_sync(&rdev->conn_work); |
710 | flush_work(&rdev->event_work); | 710 | flush_work(&rdev->event_work); |
711 | |||
712 | if (rdev->wowlan && rdev->ops->set_wakeup) | ||
713 | rdev->ops->set_wakeup(&rdev->wiphy, false); | ||
714 | cfg80211_rdev_free_wowlan(rdev); | ||
711 | } | 715 | } |
712 | EXPORT_SYMBOL(wiphy_unregister); | 716 | EXPORT_SYMBOL(wiphy_unregister); |
713 | 717 | ||
@@ -720,7 +724,6 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev) | |||
720 | mutex_destroy(&rdev->sched_scan_mtx); | 724 | mutex_destroy(&rdev->sched_scan_mtx); |
721 | list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list) | 725 | list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list) |
722 | cfg80211_put_bss(&scan->pub); | 726 | cfg80211_put_bss(&scan->pub); |
723 | cfg80211_rdev_free_wowlan(rdev); | ||
724 | kfree(rdev); | 727 | kfree(rdev); |
725 | } | 728 | } |
726 | 729 | ||
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index b12a05243d71..40e5620e5fde 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -6014,6 +6014,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
6014 | struct cfg80211_wowlan new_triggers = {}; | 6014 | struct cfg80211_wowlan new_triggers = {}; |
6015 | struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan; | 6015 | struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan; |
6016 | int err, i; | 6016 | int err, i; |
6017 | bool prev_enabled = rdev->wowlan; | ||
6017 | 6018 | ||
6018 | if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns) | 6019 | if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns) |
6019 | return -EOPNOTSUPP; | 6020 | return -EOPNOTSUPP; |
@@ -6146,6 +6147,9 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
6146 | rdev->wowlan = NULL; | 6147 | rdev->wowlan = NULL; |
6147 | } | 6148 | } |
6148 | 6149 | ||
6150 | if (rdev->ops->set_wakeup && prev_enabled != !!rdev->wowlan) | ||
6151 | rdev->ops->set_wakeup(&rdev->wiphy, rdev->wowlan); | ||
6152 | |||
6149 | return 0; | 6153 | return 0; |
6150 | error: | 6154 | error: |
6151 | for (i = 0; i < new_triggers.n_patterns; i++) | 6155 | for (i = 0; i < new_triggers.n_patterns; i++) |