diff options
author | Johannes Berg <johannes.berg@intel.com> | 2011-07-13 04:48:55 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-07-15 13:38:28 -0400 |
commit | 77dbbb138986b26cb99f868d4b6410577ef4c040 (patch) | |
tree | e3f4f9a2bb6b36938e3b221f4f0ee2e74d1ab238 | |
parent | 95acac61ba66c4abd40e038dae8c1ed2e176c7b1 (diff) |
nl80211: advertise GTK rekey support, new triggers
Since we now have the necessary API in place to support
GTK rekeying, applications will need to know whether it
is supported by a device. Add a pseudo-trigger that is
used only to advertise that capability. Also, add some
new triggers that match what iwlagn devices can do.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | include/linux/nl80211.h | 19 | ||||
-rw-r--r-- | include/net/cfg80211.h | 24 | ||||
-rw-r--r-- | net/wireless/core.c | 4 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 49 |
4 files changed, 90 insertions, 6 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 8cb025a00094..c5f577e9ee27 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h | |||
@@ -989,8 +989,8 @@ enum nl80211_commands { | |||
989 | * driving the peer link management state machine. | 989 | * driving the peer link management state machine. |
990 | * @NL80211_MESH_SETUP_USERSPACE_AMPE must be enabled. | 990 | * @NL80211_MESH_SETUP_USERSPACE_AMPE must be enabled. |
991 | * | 991 | * |
992 | * @NL80211_ATTR_WOWLAN_SUPPORTED: indicates, as part of the wiphy capabilities, | 992 | * @NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED: indicates, as part of the wiphy |
993 | * the supported WoWLAN triggers | 993 | * capabilities, the supported WoWLAN triggers |
994 | * @NL80211_ATTR_WOWLAN_TRIGGERS: used by %NL80211_CMD_SET_WOWLAN to | 994 | * @NL80211_ATTR_WOWLAN_TRIGGERS: used by %NL80211_CMD_SET_WOWLAN to |
995 | * indicate which WoW triggers should be enabled. This is also | 995 | * indicate which WoW triggers should be enabled. This is also |
996 | * used by %NL80211_CMD_GET_WOWLAN to get the currently enabled WoWLAN | 996 | * used by %NL80211_CMD_GET_WOWLAN to get the currently enabled WoWLAN |
@@ -2255,6 +2255,16 @@ struct nl80211_wowlan_pattern_support { | |||
2255 | * | 2255 | * |
2256 | * In %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, it is a binary attribute | 2256 | * In %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, it is a binary attribute |
2257 | * carrying a &struct nl80211_wowlan_pattern_support. | 2257 | * carrying a &struct nl80211_wowlan_pattern_support. |
2258 | * @NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED: Not a real trigger, and cannot be | ||
2259 | * used when setting, used only to indicate that GTK rekeying is supported | ||
2260 | * by the device (flag) | ||
2261 | * @NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE: wake up on GTK rekey failure (if | ||
2262 | * done by the device) (flag) | ||
2263 | * @NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST: wake up on EAP Identity Request | ||
2264 | * packet (flag) | ||
2265 | * @NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE: wake up on 4-way handshake (flag) | ||
2266 | * @NL80211_WOWLAN_TRIG_RFKILL_RELEASE: wake up when rfkill is released | ||
2267 | * (on devices that have rfkill in the device) (flag) | ||
2258 | * @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers | 2268 | * @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers |
2259 | * @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number | 2269 | * @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number |
2260 | */ | 2270 | */ |
@@ -2264,6 +2274,11 @@ enum nl80211_wowlan_triggers { | |||
2264 | NL80211_WOWLAN_TRIG_DISCONNECT, | 2274 | NL80211_WOWLAN_TRIG_DISCONNECT, |
2265 | NL80211_WOWLAN_TRIG_MAGIC_PKT, | 2275 | NL80211_WOWLAN_TRIG_MAGIC_PKT, |
2266 | NL80211_WOWLAN_TRIG_PKT_PATTERN, | 2276 | NL80211_WOWLAN_TRIG_PKT_PATTERN, |
2277 | NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED, | ||
2278 | NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE, | ||
2279 | NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST, | ||
2280 | NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE, | ||
2281 | NL80211_WOWLAN_TRIG_RFKILL_RELEASE, | ||
2267 | 2282 | ||
2268 | /* keep last */ | 2283 | /* keep last */ |
2269 | NUM_NL80211_WOWLAN_TRIG, | 2284 | NUM_NL80211_WOWLAN_TRIG, |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 5390e3245a1a..83d5c387755d 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -1146,9 +1146,15 @@ struct cfg80211_wowlan_trig_pkt_pattern { | |||
1146 | * @magic_pkt: wake up on receiving magic packet | 1146 | * @magic_pkt: wake up on receiving magic packet |
1147 | * @patterns: wake up on receiving packet matching a pattern | 1147 | * @patterns: wake up on receiving packet matching a pattern |
1148 | * @n_patterns: number of patterns | 1148 | * @n_patterns: number of patterns |
1149 | * @gtk_rekey_failure: wake up on GTK rekey failure | ||
1150 | * @eap_identity_req: wake up on EAP identity request packet | ||
1151 | * @four_way_handshake: wake up on 4-way handshake | ||
1152 | * @rfkill_release: wake up when rfkill is released | ||
1149 | */ | 1153 | */ |
1150 | struct cfg80211_wowlan { | 1154 | struct cfg80211_wowlan { |
1151 | bool any, disconnect, magic_pkt; | 1155 | bool any, disconnect, magic_pkt, gtk_rekey_failure, |
1156 | eap_identity_req, four_way_handshake, | ||
1157 | rfkill_release; | ||
1152 | struct cfg80211_wowlan_trig_pkt_pattern *patterns; | 1158 | struct cfg80211_wowlan_trig_pkt_pattern *patterns; |
1153 | int n_patterns; | 1159 | int n_patterns; |
1154 | }; | 1160 | }; |
@@ -1673,11 +1679,21 @@ struct ieee80211_txrx_stypes { | |||
1673 | * @WIPHY_WOWLAN_MAGIC_PKT: supports wakeup on magic packet | 1679 | * @WIPHY_WOWLAN_MAGIC_PKT: supports wakeup on magic packet |
1674 | * (see nl80211.h) | 1680 | * (see nl80211.h) |
1675 | * @WIPHY_WOWLAN_DISCONNECT: supports wakeup on disconnect | 1681 | * @WIPHY_WOWLAN_DISCONNECT: supports wakeup on disconnect |
1682 | * @WIPHY_WOWLAN_SUPPORTS_GTK_REKEY: supports GTK rekeying while asleep | ||
1683 | * @WIPHY_WOWLAN_GTK_REKEY_FAILURE: supports wakeup on GTK rekey failure | ||
1684 | * @WIPHY_WOWLAN_EAP_IDENTITY_REQ: supports wakeup on EAP identity request | ||
1685 | * @WIPHY_WOWLAN_4WAY_HANDSHAKE: supports wakeup on 4-way handshake failure | ||
1686 | * @WIPHY_WOWLAN_RFKILL_RELEASE: supports wakeup on RF-kill release | ||
1676 | */ | 1687 | */ |
1677 | enum wiphy_wowlan_support_flags { | 1688 | enum wiphy_wowlan_support_flags { |
1678 | WIPHY_WOWLAN_ANY = BIT(0), | 1689 | WIPHY_WOWLAN_ANY = BIT(0), |
1679 | WIPHY_WOWLAN_MAGIC_PKT = BIT(1), | 1690 | WIPHY_WOWLAN_MAGIC_PKT = BIT(1), |
1680 | WIPHY_WOWLAN_DISCONNECT = BIT(2), | 1691 | WIPHY_WOWLAN_DISCONNECT = BIT(2), |
1692 | WIPHY_WOWLAN_SUPPORTS_GTK_REKEY = BIT(3), | ||
1693 | WIPHY_WOWLAN_GTK_REKEY_FAILURE = BIT(4), | ||
1694 | WIPHY_WOWLAN_EAP_IDENTITY_REQ = BIT(5), | ||
1695 | WIPHY_WOWLAN_4WAY_HANDSHAKE = BIT(6), | ||
1696 | WIPHY_WOWLAN_RFKILL_RELEASE = BIT(7), | ||
1681 | }; | 1697 | }; |
1682 | 1698 | ||
1683 | /** | 1699 | /** |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 880dbe2e6f94..112959d5256a 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -488,6 +488,10 @@ int wiphy_register(struct wiphy *wiphy) | |||
488 | int i; | 488 | int i; |
489 | u16 ifmodes = wiphy->interface_modes; | 489 | u16 ifmodes = wiphy->interface_modes; |
490 | 490 | ||
491 | if (WARN_ON((wiphy->wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && | ||
492 | !(wiphy->wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY))) | ||
493 | return -EINVAL; | ||
494 | |||
491 | if (WARN_ON(wiphy->addresses && !wiphy->n_addresses)) | 495 | if (WARN_ON(wiphy->addresses && !wiphy->n_addresses)) |
492 | return -EINVAL; | 496 | return -EINVAL; |
493 | 497 | ||
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 6a82c898f831..a2e1e49c9196 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -205,6 +205,10 @@ nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = { | |||
205 | [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG }, | 205 | [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG }, |
206 | [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG }, | 206 | [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG }, |
207 | [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED }, | 207 | [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED }, |
208 | [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG }, | ||
209 | [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG }, | ||
210 | [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG }, | ||
211 | [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG }, | ||
208 | }; | 212 | }; |
209 | 213 | ||
210 | /* policy for GTK rekey offload attributes */ | 214 | /* policy for GTK rekey offload attributes */ |
@@ -929,6 +933,16 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
929 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT); | 933 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT); |
930 | if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT) | 934 | if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT) |
931 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT); | 935 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT); |
936 | if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) | ||
937 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED); | ||
938 | if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) | ||
939 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE); | ||
940 | if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) | ||
941 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST); | ||
942 | if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) | ||
943 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE); | ||
944 | if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_RFKILL_RELEASE) | ||
945 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE); | ||
932 | if (dev->wiphy.wowlan.n_patterns) { | 946 | if (dev->wiphy.wowlan.n_patterns) { |
933 | struct nl80211_wowlan_pattern_support pat = { | 947 | struct nl80211_wowlan_pattern_support pat = { |
934 | .max_patterns = dev->wiphy.wowlan.n_patterns, | 948 | .max_patterns = dev->wiphy.wowlan.n_patterns, |
@@ -5272,6 +5286,14 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
5272 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT); | 5286 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT); |
5273 | if (rdev->wowlan->magic_pkt) | 5287 | if (rdev->wowlan->magic_pkt) |
5274 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT); | 5288 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT); |
5289 | if (rdev->wowlan->gtk_rekey_failure) | ||
5290 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE); | ||
5291 | if (rdev->wowlan->eap_identity_req) | ||
5292 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST); | ||
5293 | if (rdev->wowlan->four_way_handshake) | ||
5294 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE); | ||
5295 | if (rdev->wowlan->rfkill_release) | ||
5296 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE); | ||
5275 | if (rdev->wowlan->n_patterns) { | 5297 | if (rdev->wowlan->n_patterns) { |
5276 | struct nlattr *nl_pats, *nl_pat; | 5298 | struct nlattr *nl_pats, *nl_pat; |
5277 | int i, pat_len; | 5299 | int i, pat_len; |
@@ -5348,6 +5370,33 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
5348 | new_triggers.magic_pkt = true; | 5370 | new_triggers.magic_pkt = true; |
5349 | } | 5371 | } |
5350 | 5372 | ||
5373 | if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED]) | ||
5374 | return -EINVAL; | ||
5375 | |||
5376 | if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) { | ||
5377 | if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE)) | ||
5378 | return -EINVAL; | ||
5379 | new_triggers.gtk_rekey_failure = true; | ||
5380 | } | ||
5381 | |||
5382 | if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) { | ||
5383 | if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ)) | ||
5384 | return -EINVAL; | ||
5385 | new_triggers.eap_identity_req = true; | ||
5386 | } | ||
5387 | |||
5388 | if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) { | ||
5389 | if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE)) | ||
5390 | return -EINVAL; | ||
5391 | new_triggers.four_way_handshake = true; | ||
5392 | } | ||
5393 | |||
5394 | if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) { | ||
5395 | if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE)) | ||
5396 | return -EINVAL; | ||
5397 | new_triggers.rfkill_release = true; | ||
5398 | } | ||
5399 | |||
5351 | if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) { | 5400 | if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) { |
5352 | struct nlattr *pat; | 5401 | struct nlattr *pat; |
5353 | int n_patterns = 0; | 5402 | int n_patterns = 0; |