aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-24 23:55:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-24 23:55:48 -0400
commitee05eff6f79c25617e5b7d7677b8f79d26abbe37 (patch)
tree1efa14a8b5c79c3c986aca34dce13745760ea66c /net
parent933b44732caad0c3b65224453c54846c75d97936 (diff)
parentb6c2f86e6305be612f1196459f22343523f7049f (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (145 commits) bnx2x: use pci_pcie_cap() bnx2x: fix bnx2x_stop_on_error flow in bnx2x_sp_rtnl_task bnx2x: enable internal target-read for 57712 and up only bnx2x: count statistic ramrods on EQ to prevent MC assert bnx2x: fix loopback for non 10G link bnx2x: dcb - send all unmapped priorities to same COS as L2 iwlwifi: Fix build with CONFIG_PM disabled. gre: fix improper error handling ipv4: use RT_TOS after some rt_tos conversions via-velocity: remove duplicated #include qlge: remove duplicated #include igb: remove duplicated #include can: c_can: remove duplicated #include bnad: remove duplicated #include net: allow netif_carrier to be called safely from IRQ bna: Header File Consolidation bna: HW Error Counter Fix bna: Add HW Semaphore Unlock Logic bna: IOC Event Name Change bna: Mboxq Flush When IOC Disabled ...
Diffstat (limited to 'net')
-rw-r--r--net/bridge/br_if.c2
-rw-r--r--net/bridge/br_netlink.c2
-rw-r--r--net/bridge/br_private.h1
-rw-r--r--net/bridge/br_private_stp.h3
-rw-r--r--net/bridge/br_stp.c31
-rw-r--r--net/bridge/br_stp_bpdu.c15
-rw-r--r--net/bridge/br_stp_if.c3
-rw-r--r--net/bridge/br_stp_timer.c1
-rw-r--r--net/core/link_watch.c2
-rw-r--r--net/ipv4/gre.c21
-rw-r--r--net/ipv4/ipmr.c2
-rw-r--r--net/ipv4/route.c2
-rw-r--r--net/mac80211/agg-rx.c10
-rw-r--r--net/mac80211/cfg.c4
-rw-r--r--net/mac80211/driver-ops.h31
-rw-r--r--net/mac80211/driver-trace.h43
-rw-r--r--net/mac80211/ieee80211_i.h7
-rw-r--r--net/mac80211/key.c2
-rw-r--r--net/mac80211/mlme.c30
-rw-r--r--net/mac80211/pm.c3
-rw-r--r--net/mac80211/scan.c6
-rw-r--r--net/mac80211/tkip.c11
-rw-r--r--net/mac80211/util.c71
-rw-r--r--net/mac80211/work.c28
-rw-r--r--net/wireless/core.c7
-rw-r--r--net/wireless/core.h4
-rw-r--r--net/wireless/nl80211.c109
-rw-r--r--net/wireless/scan.c4
-rw-r--r--net/wireless/util.c38
29 files changed, 387 insertions, 106 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 1bacca4cb676..3176e2e13d9b 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -388,7 +388,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
388 br_ifinfo_notify(RTM_NEWLINK, p); 388 br_ifinfo_notify(RTM_NEWLINK, p);
389 389
390 if (changed_addr) 390 if (changed_addr)
391 call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); 391 call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev);
392 392
393 dev_set_mtu(br->dev, br_min_mtu(br)); 393 dev_set_mtu(br->dev, br_min_mtu(br));
394 394
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 6814083a92f4..5b1ed1ba9aa7 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -188,6 +188,8 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
188 188
189 p->state = new_state; 189 p->state = new_state;
190 br_log_state(p); 190 br_log_state(p);
191 br_ifinfo_notify(RTM_NEWLINK, p);
192
191 return 0; 193 return 0;
192} 194}
193 195
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 54578f274d85..78cc364997d9 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -124,6 +124,7 @@ struct net_bridge_port
124 bridge_id designated_bridge; 124 bridge_id designated_bridge;
125 u32 path_cost; 125 u32 path_cost;
126 u32 designated_cost; 126 u32 designated_cost;
127 unsigned long designated_age;
127 128
128 struct timer_list forward_delay_timer; 129 struct timer_list forward_delay_timer;
129 struct timer_list hold_timer; 130 struct timer_list hold_timer;
diff --git a/net/bridge/br_private_stp.h b/net/bridge/br_private_stp.h
index 642ef47a867e..05ed9bc7e426 100644
--- a/net/bridge/br_private_stp.h
+++ b/net/bridge/br_private_stp.h
@@ -56,7 +56,8 @@ extern void br_become_root_bridge(struct net_bridge *br);
56extern void br_config_bpdu_generation(struct net_bridge *); 56extern void br_config_bpdu_generation(struct net_bridge *);
57extern void br_configuration_update(struct net_bridge *); 57extern void br_configuration_update(struct net_bridge *);
58extern void br_port_state_selection(struct net_bridge *); 58extern void br_port_state_selection(struct net_bridge *);
59extern void br_received_config_bpdu(struct net_bridge_port *p, struct br_config_bpdu *bpdu); 59extern void br_received_config_bpdu(struct net_bridge_port *p,
60 const struct br_config_bpdu *bpdu);
60extern void br_received_tcn_bpdu(struct net_bridge_port *p); 61extern void br_received_tcn_bpdu(struct net_bridge_port *p);
61extern void br_transmit_config(struct net_bridge_port *p); 62extern void br_transmit_config(struct net_bridge_port *p);
62extern void br_transmit_tcn(struct net_bridge *br); 63extern void br_transmit_tcn(struct net_bridge *br);
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
index bb4383e84de9..ad0a3f7cf6cc 100644
--- a/net/bridge/br_stp.c
+++ b/net/bridge/br_stp.c
@@ -109,7 +109,6 @@ static void br_root_selection(struct net_bridge *br)
109 list_for_each_entry(p, &br->port_list, list) { 109 list_for_each_entry(p, &br->port_list, list) {
110 if (br_should_become_root_port(p, root_port)) 110 if (br_should_become_root_port(p, root_port))
111 root_port = p->port_no; 111 root_port = p->port_no;
112
113 } 112 }
114 113
115 br->root_port = root_port; 114 br->root_port = root_port;
@@ -145,7 +144,6 @@ void br_transmit_config(struct net_bridge_port *p)
145 struct br_config_bpdu bpdu; 144 struct br_config_bpdu bpdu;
146 struct net_bridge *br; 145 struct net_bridge *br;
147 146
148
149 if (timer_pending(&p->hold_timer)) { 147 if (timer_pending(&p->hold_timer)) {
150 p->config_pending = 1; 148 p->config_pending = 1;
151 return; 149 return;
@@ -164,8 +162,7 @@ void br_transmit_config(struct net_bridge_port *p)
164 else { 162 else {
165 struct net_bridge_port *root 163 struct net_bridge_port *root
166 = br_get_port(br, br->root_port); 164 = br_get_port(br, br->root_port);
167 bpdu.message_age = br->max_age 165 bpdu.message_age = (jiffies - root->designated_age)
168 - (root->message_age_timer.expires - jiffies)
169 + MESSAGE_AGE_INCR; 166 + MESSAGE_AGE_INCR;
170 } 167 }
171 bpdu.max_age = br->max_age; 168 bpdu.max_age = br->max_age;
@@ -182,20 +179,21 @@ void br_transmit_config(struct net_bridge_port *p)
182} 179}
183 180
184/* called under bridge lock */ 181/* called under bridge lock */
185static inline void br_record_config_information(struct net_bridge_port *p, 182static void br_record_config_information(struct net_bridge_port *p,
186 const struct br_config_bpdu *bpdu) 183 const struct br_config_bpdu *bpdu)
187{ 184{
188 p->designated_root = bpdu->root; 185 p->designated_root = bpdu->root;
189 p->designated_cost = bpdu->root_path_cost; 186 p->designated_cost = bpdu->root_path_cost;
190 p->designated_bridge = bpdu->bridge_id; 187 p->designated_bridge = bpdu->bridge_id;
191 p->designated_port = bpdu->port_id; 188 p->designated_port = bpdu->port_id;
189 p->designated_age = jiffies + bpdu->message_age;
192 190
193 mod_timer(&p->message_age_timer, jiffies 191 mod_timer(&p->message_age_timer, jiffies
194 + (p->br->max_age - bpdu->message_age)); 192 + (p->br->max_age - bpdu->message_age));
195} 193}
196 194
197/* called under bridge lock */ 195/* called under bridge lock */
198static inline void br_record_config_timeout_values(struct net_bridge *br, 196static void br_record_config_timeout_values(struct net_bridge *br,
199 const struct br_config_bpdu *bpdu) 197 const struct br_config_bpdu *bpdu)
200{ 198{
201 br->max_age = bpdu->max_age; 199 br->max_age = bpdu->max_age;
@@ -254,7 +252,8 @@ static void br_designated_port_selection(struct net_bridge *br)
254} 252}
255 253
256/* called under bridge lock */ 254/* called under bridge lock */
257static int br_supersedes_port_info(struct net_bridge_port *p, struct br_config_bpdu *bpdu) 255static int br_supersedes_port_info(const struct net_bridge_port *p,
256 const struct br_config_bpdu *bpdu)
258{ 257{
259 int t; 258 int t;
260 259
@@ -285,7 +284,7 @@ static int br_supersedes_port_info(struct net_bridge_port *p, struct br_config_b
285} 284}
286 285
287/* called under bridge lock */ 286/* called under bridge lock */
288static inline void br_topology_change_acknowledged(struct net_bridge *br) 287static void br_topology_change_acknowledged(struct net_bridge *br)
289{ 288{
290 br->topology_change_detected = 0; 289 br->topology_change_detected = 0;
291 del_timer(&br->tcn_timer); 290 del_timer(&br->tcn_timer);
@@ -327,7 +326,7 @@ void br_config_bpdu_generation(struct net_bridge *br)
327} 326}
328 327
329/* called under bridge lock */ 328/* called under bridge lock */
330static inline void br_reply(struct net_bridge_port *p) 329static void br_reply(struct net_bridge_port *p)
331{ 330{
332 br_transmit_config(p); 331 br_transmit_config(p);
333} 332}
@@ -363,6 +362,8 @@ static void br_make_blocking(struct net_bridge_port *p)
363 362
364 p->state = BR_STATE_BLOCKING; 363 p->state = BR_STATE_BLOCKING;
365 br_log_state(p); 364 br_log_state(p);
365 br_ifinfo_notify(RTM_NEWLINK, p);
366
366 del_timer(&p->forward_delay_timer); 367 del_timer(&p->forward_delay_timer);
367 } 368 }
368} 369}
@@ -379,15 +380,14 @@ static void br_make_forwarding(struct net_bridge_port *p)
379 p->state = BR_STATE_FORWARDING; 380 p->state = BR_STATE_FORWARDING;
380 br_topology_change_detection(br); 381 br_topology_change_detection(br);
381 del_timer(&p->forward_delay_timer); 382 del_timer(&p->forward_delay_timer);
382 } 383 } else if (br->stp_enabled == BR_KERNEL_STP)
383 else if (br->stp_enabled == BR_KERNEL_STP)
384 p->state = BR_STATE_LISTENING; 384 p->state = BR_STATE_LISTENING;
385 else 385 else
386 p->state = BR_STATE_LEARNING; 386 p->state = BR_STATE_LEARNING;
387 387
388 br_multicast_enable_port(p); 388 br_multicast_enable_port(p);
389
390 br_log_state(p); 389 br_log_state(p);
390 br_ifinfo_notify(RTM_NEWLINK, p);
391 391
392 if (br->forward_delay != 0) 392 if (br->forward_delay != 0)
393 mod_timer(&p->forward_delay_timer, jiffies + br->forward_delay); 393 mod_timer(&p->forward_delay_timer, jiffies + br->forward_delay);
@@ -431,14 +431,15 @@ void br_port_state_selection(struct net_bridge *br)
431} 431}
432 432
433/* called under bridge lock */ 433/* called under bridge lock */
434static inline void br_topology_change_acknowledge(struct net_bridge_port *p) 434static void br_topology_change_acknowledge(struct net_bridge_port *p)
435{ 435{
436 p->topology_change_ack = 1; 436 p->topology_change_ack = 1;
437 br_transmit_config(p); 437 br_transmit_config(p);
438} 438}
439 439
440/* called under bridge lock */ 440/* called under bridge lock */
441void br_received_config_bpdu(struct net_bridge_port *p, struct br_config_bpdu *bpdu) 441void br_received_config_bpdu(struct net_bridge_port *p,
442 const struct br_config_bpdu *bpdu)
442{ 443{
443 struct net_bridge *br; 444 struct net_bridge *br;
444 int was_root; 445 int was_root;
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c
index 289646ec9b7b..e16aade51ae0 100644
--- a/net/bridge/br_stp_bpdu.c
+++ b/net/bridge/br_stp_bpdu.c
@@ -210,10 +210,19 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb,
210 bpdu.hello_time = br_get_ticks(buf+28); 210 bpdu.hello_time = br_get_ticks(buf+28);
211 bpdu.forward_delay = br_get_ticks(buf+30); 211 bpdu.forward_delay = br_get_ticks(buf+30);
212 212
213 br_received_config_bpdu(p, &bpdu); 213 if (bpdu.message_age > bpdu.max_age) {
214 } 214 if (net_ratelimit())
215 br_notice(p->br,
216 "port %u config from %pM"
217 " (message_age %ul > max_age %ul)\n",
218 p->port_no,
219 eth_hdr(skb)->h_source,
220 bpdu.message_age, bpdu.max_age);
221 goto out;
222 }
215 223
216 else if (buf[0] == BPDU_TYPE_TCN) { 224 br_received_config_bpdu(p, &bpdu);
225 } else if (buf[0] == BPDU_TYPE_TCN) {
217 br_received_tcn_bpdu(p); 226 br_received_tcn_bpdu(p);
218 } 227 }
219 out: 228 out:
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index 6f615b8192f4..10eda3cd1d71 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -88,6 +88,7 @@ void br_stp_enable_port(struct net_bridge_port *p)
88 br_init_port(p); 88 br_init_port(p);
89 br_port_state_selection(p->br); 89 br_port_state_selection(p->br);
90 br_log_state(p); 90 br_log_state(p);
91 br_ifinfo_notify(RTM_NEWLINK, p);
91} 92}
92 93
93/* called under bridge lock */ 94/* called under bridge lock */
@@ -104,6 +105,8 @@ void br_stp_disable_port(struct net_bridge_port *p)
104 p->topology_change_ack = 0; 105 p->topology_change_ack = 0;
105 p->config_pending = 0; 106 p->config_pending = 0;
106 107
108 br_ifinfo_notify(RTM_NEWLINK, p);
109
107 del_timer(&p->message_age_timer); 110 del_timer(&p->message_age_timer);
108 del_timer(&p->forward_delay_timer); 111 del_timer(&p->forward_delay_timer);
109 del_timer(&p->hold_timer); 112 del_timer(&p->hold_timer);
diff --git a/net/bridge/br_stp_timer.c b/net/bridge/br_stp_timer.c
index 3e965140051e..58de2a0f9975 100644
--- a/net/bridge/br_stp_timer.c
+++ b/net/bridge/br_stp_timer.c
@@ -97,6 +97,7 @@ static void br_forward_delay_timer_expired(unsigned long arg)
97 netif_carrier_on(br->dev); 97 netif_carrier_on(br->dev);
98 } 98 }
99 br_log_state(p); 99 br_log_state(p);
100 br_ifinfo_notify(RTM_NEWLINK, p);
100 spin_unlock(&br->lock); 101 spin_unlock(&br->lock);
101} 102}
102 103
diff --git a/net/core/link_watch.c b/net/core/link_watch.c
index a7b342131869..357bd4ee4baa 100644
--- a/net/core/link_watch.c
+++ b/net/core/link_watch.c
@@ -126,7 +126,7 @@ static void linkwatch_schedule_work(int urgent)
126 return; 126 return;
127 127
128 /* It's already running which is good enough. */ 128 /* It's already running which is good enough. */
129 if (!cancel_delayed_work(&linkwatch_work)) 129 if (!__cancel_delayed_work(&linkwatch_work))
130 return; 130 return;
131 131
132 /* Otherwise we reschedule it again for immediate execution. */ 132 /* Otherwise we reschedule it again for immediate execution. */
diff --git a/net/ipv4/gre.c b/net/ipv4/gre.c
index 9dbe10875fbd..dbfc21de3479 100644
--- a/net/ipv4/gre.c
+++ b/net/ipv4/gre.c
@@ -15,6 +15,7 @@
15#include <linux/kmod.h> 15#include <linux/kmod.h>
16#include <linux/skbuff.h> 16#include <linux/skbuff.h>
17#include <linux/in.h> 17#include <linux/in.h>
18#include <linux/ip.h>
18#include <linux/netdevice.h> 19#include <linux/netdevice.h>
19#include <linux/spinlock.h> 20#include <linux/spinlock.h>
20#include <net/protocol.h> 21#include <net/protocol.h>
@@ -96,27 +97,17 @@ drop:
96static void gre_err(struct sk_buff *skb, u32 info) 97static void gre_err(struct sk_buff *skb, u32 info)
97{ 98{
98 const struct gre_protocol *proto; 99 const struct gre_protocol *proto;
99 u8 ver; 100 const struct iphdr *iph = (const struct iphdr *)skb->data;
100 101 u8 ver = skb->data[(iph->ihl<<2) + 1]&0x7f;
101 if (!pskb_may_pull(skb, 12))
102 goto drop;
103 102
104 ver = skb->data[1]&0x7f;
105 if (ver >= GREPROTO_MAX) 103 if (ver >= GREPROTO_MAX)
106 goto drop; 104 return;
107 105
108 rcu_read_lock(); 106 rcu_read_lock();
109 proto = rcu_dereference(gre_proto[ver]); 107 proto = rcu_dereference(gre_proto[ver]);
110 if (!proto || !proto->err_handler) 108 if (proto && proto->err_handler)
111 goto drop_unlock; 109 proto->err_handler(skb, info);
112 proto->err_handler(skb, info);
113 rcu_read_unlock();
114 return;
115
116drop_unlock:
117 rcu_read_unlock(); 110 rcu_read_unlock();
118drop:
119 kfree_skb(skb);
120} 111}
121 112
122static const struct net_protocol net_gre_protocol = { 113static const struct net_protocol net_gre_protocol = {
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index aae2bd8cd924..58e879157976 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1796,7 +1796,7 @@ static struct mr_table *ipmr_rt_fib_lookup(struct net *net, struct sk_buff *skb)
1796 struct flowi4 fl4 = { 1796 struct flowi4 fl4 = {
1797 .daddr = iph->daddr, 1797 .daddr = iph->daddr,
1798 .saddr = iph->saddr, 1798 .saddr = iph->saddr,
1799 .flowi4_tos = iph->tos, 1799 .flowi4_tos = RT_TOS(iph->tos),
1800 .flowi4_oif = rt->rt_oif, 1800 .flowi4_oif = rt->rt_oif,
1801 .flowi4_iif = rt->rt_iif, 1801 .flowi4_iif = rt->rt_iif,
1802 .flowi4_mark = rt->rt_mark, 1802 .flowi4_mark = rt->rt_mark,
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 33137307d52a..1730689f560e 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1740,7 +1740,7 @@ void ip_rt_get_source(u8 *addr, struct sk_buff *skb, struct rtable *rt)
1740 memset(&fl4, 0, sizeof(fl4)); 1740 memset(&fl4, 0, sizeof(fl4));
1741 fl4.daddr = iph->daddr; 1741 fl4.daddr = iph->daddr;
1742 fl4.saddr = iph->saddr; 1742 fl4.saddr = iph->saddr;
1743 fl4.flowi4_tos = iph->tos; 1743 fl4.flowi4_tos = RT_TOS(iph->tos);
1744 fl4.flowi4_oif = rt->dst.dev->ifindex; 1744 fl4.flowi4_oif = rt->dst.dev->ifindex;
1745 fl4.flowi4_iif = skb->dev->ifindex; 1745 fl4.flowi4_iif = skb->dev->ifindex;
1746 fl4.flowi4_mark = skb->mark; 1746 fl4.flowi4_mark = skb->mark;
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index ebadb9ac9a7e..fd1aaf2a4a6c 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -104,14 +104,22 @@ void ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, u16 ba_rx_bitmap,
104 const u8 *addr) 104 const u8 *addr)
105{ 105{
106 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 106 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
107 struct sta_info *sta = sta_info_get(sdata, addr); 107 struct sta_info *sta;
108 int i; 108 int i;
109 109
110 rcu_read_lock();
111 sta = sta_info_get(sdata, addr);
112 if (!sta) {
113 rcu_read_unlock();
114 return;
115 }
116
110 for (i = 0; i < STA_TID_NUM; i++) 117 for (i = 0; i < STA_TID_NUM; i++)
111 if (ba_rx_bitmap & BIT(i)) 118 if (ba_rx_bitmap & BIT(i))
112 set_bit(i, sta->ampdu_mlme.tid_rx_stop_requested); 119 set_bit(i, sta->ampdu_mlme.tid_rx_stop_requested);
113 120
114 ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work); 121 ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work);
122 rcu_read_unlock();
115} 123}
116EXPORT_SYMBOL(ieee80211_stop_rx_ba_session); 124EXPORT_SYMBOL(ieee80211_stop_rx_ba_session);
117 125
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index bfc36e904764..3d1b091d9b2e 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1255,6 +1255,10 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
1255 */ 1255 */
1256 p.uapsd = false; 1256 p.uapsd = false;
1257 1257
1258 if (params->queue >= local->hw.queues)
1259 return -EINVAL;
1260
1261 local->tx_conf[params->queue] = p;
1258 if (drv_conf_tx(local, params->queue, &p)) { 1262 if (drv_conf_tx(local, params->queue, &p)) {
1259 wiphy_debug(local->hw.wiphy, 1263 wiphy_debug(local->hw.wiphy,
1260 "failed to set TX queue parameters for queue %d\n", 1264 "failed to set TX queue parameters for queue %d\n",
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index b2d6bba44054..1425380983f7 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -130,6 +130,37 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local,
130 trace_drv_return_void(local); 130 trace_drv_return_void(local);
131} 131}
132 132
133static inline int drv_tx_sync(struct ieee80211_local *local,
134 struct ieee80211_sub_if_data *sdata,
135 const u8 *bssid,
136 enum ieee80211_tx_sync_type type)
137{
138 int ret = 0;
139
140 might_sleep();
141
142 trace_drv_tx_sync(local, sdata, bssid, type);
143 if (local->ops->tx_sync)
144 ret = local->ops->tx_sync(&local->hw, &sdata->vif,
145 bssid, type);
146 trace_drv_return_int(local, ret);
147 return ret;
148}
149
150static inline void drv_finish_tx_sync(struct ieee80211_local *local,
151 struct ieee80211_sub_if_data *sdata,
152 const u8 *bssid,
153 enum ieee80211_tx_sync_type type)
154{
155 might_sleep();
156
157 trace_drv_finish_tx_sync(local, sdata, bssid, type);
158 if (local->ops->finish_tx_sync)
159 local->ops->finish_tx_sync(&local->hw, &sdata->vif,
160 bssid, type);
161 trace_drv_return_void(local);
162}
163
133static inline u64 drv_prepare_multicast(struct ieee80211_local *local, 164static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
134 struct netdev_hw_addr_list *mc_list) 165 struct netdev_hw_addr_list *mc_list)
135{ 166{
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 4470f6e8b845..f47b00dc7afd 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -319,6 +319,49 @@ TRACE_EVENT(drv_bss_info_changed,
319 ) 319 )
320); 320);
321 321
322DECLARE_EVENT_CLASS(tx_sync_evt,
323 TP_PROTO(struct ieee80211_local *local,
324 struct ieee80211_sub_if_data *sdata,
325 const u8 *bssid,
326 enum ieee80211_tx_sync_type type),
327 TP_ARGS(local, sdata, bssid, type),
328
329 TP_STRUCT__entry(
330 LOCAL_ENTRY
331 VIF_ENTRY
332 __array(char, bssid, ETH_ALEN)
333 __field(u32, sync_type)
334 ),
335
336 TP_fast_assign(
337 LOCAL_ASSIGN;
338 VIF_ASSIGN;
339 memcpy(__entry->bssid, bssid, ETH_ALEN);
340 __entry->sync_type = type;
341 ),
342
343 TP_printk(
344 LOCAL_PR_FMT VIF_PR_FMT " bssid:%pM type:%d",
345 LOCAL_PR_ARG, VIF_PR_ARG, __entry->bssid, __entry->sync_type
346 )
347);
348
349DEFINE_EVENT(tx_sync_evt, drv_tx_sync,
350 TP_PROTO(struct ieee80211_local *local,
351 struct ieee80211_sub_if_data *sdata,
352 const u8 *bssid,
353 enum ieee80211_tx_sync_type type),
354 TP_ARGS(local, sdata, bssid, type)
355);
356
357DEFINE_EVENT(tx_sync_evt, drv_finish_tx_sync,
358 TP_PROTO(struct ieee80211_local *local,
359 struct ieee80211_sub_if_data *sdata,
360 const u8 *bssid,
361 enum ieee80211_tx_sync_type type),
362 TP_ARGS(local, sdata, bssid, type)
363);
364
322TRACE_EVENT(drv_prepare_multicast, 365TRACE_EVENT(drv_prepare_multicast,
323 TP_PROTO(struct ieee80211_local *local, int mc_count), 366 TP_PROTO(struct ieee80211_local *local, int mc_count),
324 367
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index dda0d1ab34f3..400c09bea639 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -323,6 +323,7 @@ struct ieee80211_work {
323 u8 key[WLAN_KEY_LEN_WEP104]; 323 u8 key[WLAN_KEY_LEN_WEP104];
324 u8 key_len, key_idx; 324 u8 key_len, key_idx;
325 bool privacy; 325 bool privacy;
326 bool synced;
326 } probe_auth; 327 } probe_auth;
327 struct { 328 struct {
328 struct cfg80211_bss *bss; 329 struct cfg80211_bss *bss;
@@ -336,6 +337,7 @@ struct ieee80211_work {
336 u8 ssid_len; 337 u8 ssid_len;
337 u8 supp_rates_len; 338 u8 supp_rates_len;
338 bool wmm_used, use_11n, uapsd_used; 339 bool wmm_used, use_11n, uapsd_used;
340 bool synced;
339 } assoc; 341 } assoc;
340 struct { 342 struct {
341 u32 duration; 343 u32 duration;
@@ -746,6 +748,7 @@ struct ieee80211_local {
746 struct workqueue_struct *workqueue; 748 struct workqueue_struct *workqueue;
747 749
748 unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES]; 750 unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES];
751 struct ieee80211_tx_queue_params tx_conf[IEEE80211_MAX_QUEUES];
749 /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */ 752 /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */
750 spinlock_t queue_stop_reason_lock; 753 spinlock_t queue_stop_reason_lock;
751 754
@@ -1376,14 +1379,14 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1376 enum ieee80211_band band, u32 rate_mask, 1379 enum ieee80211_band band, u32 rate_mask,
1377 u8 channel); 1380 u8 channel);
1378struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, 1381struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1379 u8 *dst, 1382 u8 *dst, u32 ratemask,
1380 const u8 *ssid, size_t ssid_len, 1383 const u8 *ssid, size_t ssid_len,
1381 const u8 *ie, size_t ie_len, 1384 const u8 *ie, size_t ie_len,
1382 bool directed); 1385 bool directed);
1383void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, 1386void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
1384 const u8 *ssid, size_t ssid_len, 1387 const u8 *ssid, size_t ssid_len,
1385 const u8 *ie, size_t ie_len, 1388 const u8 *ie, size_t ie_len,
1386 bool directed); 1389 u32 ratemask, bool directed);
1387 1390
1388void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, 1391void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
1389 const size_t supp_rates_len, 1392 const size_t supp_rates_len,
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 739bee13e813..5150c6d11b57 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -278,7 +278,7 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
278 bool defunikey, defmultikey, defmgmtkey; 278 bool defunikey, defmultikey, defmgmtkey;
279 279
280 if (new) 280 if (new)
281 list_add(&new->list, &sdata->key_list); 281 list_add_tail(&new->list, &sdata->key_list);
282 282
283 if (sta && pairwise) { 283 if (sta && pairwise) {
284 rcu_assign_pointer(sta->ptk, new); 284 rcu_assign_pointer(sta->ptk, new);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index c99237cd4b98..d6470c7fd6ce 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -917,6 +917,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
917 params.aifs, params.cw_min, params.cw_max, 917 params.aifs, params.cw_min, params.cw_max,
918 params.txop, params.uapsd); 918 params.txop, params.uapsd);
919#endif 919#endif
920 local->tx_conf[queue] = params;
920 if (drv_conf_tx(local, queue, &params)) 921 if (drv_conf_tx(local, queue, &params))
921 wiphy_debug(local->hw.wiphy, 922 wiphy_debug(local->hw.wiphy,
922 "failed to set TX queue parameters for queue %d\n", 923 "failed to set TX queue parameters for queue %d\n",
@@ -1219,7 +1220,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
1219 } else { 1220 } else {
1220 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); 1221 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
1221 ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0, 1222 ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0,
1222 true); 1223 (u32) -1, true);
1223 } 1224 }
1224 1225
1225 ifmgd->probe_send_count++; 1226 ifmgd->probe_send_count++;
@@ -1304,7 +1305,8 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
1304 1305
1305 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); 1306 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
1306 skb = ieee80211_build_probe_req(sdata, ifmgd->associated->bssid, 1307 skb = ieee80211_build_probe_req(sdata, ifmgd->associated->bssid,
1307 ssid + 2, ssid[1], NULL, 0, true); 1308 (u32) -1, ssid + 2, ssid[1],
1309 NULL, 0, true);
1308 1310
1309 return skb; 1311 return skb;
1310} 1312}
@@ -2333,14 +2335,16 @@ static enum work_done_result
2333ieee80211_probe_auth_done(struct ieee80211_work *wk, 2335ieee80211_probe_auth_done(struct ieee80211_work *wk,
2334 struct sk_buff *skb) 2336 struct sk_buff *skb)
2335{ 2337{
2338 struct ieee80211_local *local = wk->sdata->local;
2339
2336 if (!skb) { 2340 if (!skb) {
2337 cfg80211_send_auth_timeout(wk->sdata->dev, wk->filter_ta); 2341 cfg80211_send_auth_timeout(wk->sdata->dev, wk->filter_ta);
2338 return WORK_DONE_DESTROY; 2342 goto destroy;
2339 } 2343 }
2340 2344
2341 if (wk->type == IEEE80211_WORK_AUTH) { 2345 if (wk->type == IEEE80211_WORK_AUTH) {
2342 cfg80211_send_rx_auth(wk->sdata->dev, skb->data, skb->len); 2346 cfg80211_send_rx_auth(wk->sdata->dev, skb->data, skb->len);
2343 return WORK_DONE_DESTROY; 2347 goto destroy;
2344 } 2348 }
2345 2349
2346 mutex_lock(&wk->sdata->u.mgd.mtx); 2350 mutex_lock(&wk->sdata->u.mgd.mtx);
@@ -2350,6 +2354,12 @@ ieee80211_probe_auth_done(struct ieee80211_work *wk,
2350 wk->type = IEEE80211_WORK_AUTH; 2354 wk->type = IEEE80211_WORK_AUTH;
2351 wk->probe_auth.tries = 0; 2355 wk->probe_auth.tries = 0;
2352 return WORK_DONE_REQUEUE; 2356 return WORK_DONE_REQUEUE;
2357 destroy:
2358 if (wk->probe_auth.synced)
2359 drv_finish_tx_sync(local, wk->sdata, wk->filter_ta,
2360 IEEE80211_TX_SYNC_AUTH);
2361
2362 return WORK_DONE_DESTROY;
2353} 2363}
2354 2364
2355int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, 2365int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
@@ -2422,6 +2432,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
2422static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk, 2432static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
2423 struct sk_buff *skb) 2433 struct sk_buff *skb)
2424{ 2434{
2435 struct ieee80211_local *local = wk->sdata->local;
2425 struct ieee80211_mgmt *mgmt; 2436 struct ieee80211_mgmt *mgmt;
2426 struct ieee80211_rx_status *rx_status; 2437 struct ieee80211_rx_status *rx_status;
2427 struct ieee802_11_elems elems; 2438 struct ieee802_11_elems elems;
@@ -2429,7 +2440,7 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
2429 2440
2430 if (!skb) { 2441 if (!skb) {
2431 cfg80211_send_assoc_timeout(wk->sdata->dev, wk->filter_ta); 2442 cfg80211_send_assoc_timeout(wk->sdata->dev, wk->filter_ta);
2432 return WORK_DONE_DESTROY; 2443 goto destroy;
2433 } 2444 }
2434 2445
2435 if (wk->type == IEEE80211_WORK_ASSOC_BEACON_WAIT) { 2446 if (wk->type == IEEE80211_WORK_ASSOC_BEACON_WAIT) {
@@ -2449,6 +2460,10 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
2449 status = le16_to_cpu(mgmt->u.assoc_resp.status_code); 2460 status = le16_to_cpu(mgmt->u.assoc_resp.status_code);
2450 2461
2451 if (status == WLAN_STATUS_SUCCESS) { 2462 if (status == WLAN_STATUS_SUCCESS) {
2463 if (wk->assoc.synced)
2464 drv_finish_tx_sync(local, wk->sdata, wk->filter_ta,
2465 IEEE80211_TX_SYNC_ASSOC);
2466
2452 mutex_lock(&wk->sdata->u.mgd.mtx); 2467 mutex_lock(&wk->sdata->u.mgd.mtx);
2453 if (!ieee80211_assoc_success(wk, mgmt, skb->len)) { 2468 if (!ieee80211_assoc_success(wk, mgmt, skb->len)) {
2454 mutex_unlock(&wk->sdata->u.mgd.mtx); 2469 mutex_unlock(&wk->sdata->u.mgd.mtx);
@@ -2462,6 +2477,11 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
2462 } 2477 }
2463 2478
2464 cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len); 2479 cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len);
2480 destroy:
2481 if (wk->assoc.synced)
2482 drv_finish_tx_sync(local, wk->sdata, wk->filter_ta,
2483 IEEE80211_TX_SYNC_ASSOC);
2484
2465 return WORK_DONE_DESTROY; 2485 return WORK_DONE_DESTROY;
2466} 2486}
2467 2487
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index f87e993e713b..6326d3439861 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -34,6 +34,9 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
34 struct ieee80211_sub_if_data *sdata; 34 struct ieee80211_sub_if_data *sdata;
35 struct sta_info *sta; 35 struct sta_info *sta;
36 36
37 if (!local->open_count)
38 goto suspend;
39
37 ieee80211_scan_cancel(local); 40 ieee80211_scan_cancel(local);
38 41
39 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { 42 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 08a45ac3d6f8..6f09eca01112 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -228,7 +228,6 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
228static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) 228static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
229{ 229{
230 struct cfg80211_scan_request *req = local->scan_req; 230 struct cfg80211_scan_request *req = local->scan_req;
231 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
232 enum ieee80211_band band; 231 enum ieee80211_band band;
233 int i, ielen, n_chans; 232 int i, ielen, n_chans;
234 233
@@ -253,7 +252,7 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
253 252
254 ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, 253 ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie,
255 req->ie, req->ie_len, band, 254 req->ie, req->ie_len, band,
256 sdata->rc_rateidx_mask[band], 0); 255 req->rates[band], 0);
257 local->hw_scan_req->ie_len = ielen; 256 local->hw_scan_req->ie_len = ielen;
258 257
259 return true; 258 return true;
@@ -653,6 +652,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
653{ 652{
654 int i; 653 int i;
655 struct ieee80211_sub_if_data *sdata = local->scan_sdata; 654 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
655 enum ieee80211_band band = local->hw.conf.channel->band;
656 656
657 for (i = 0; i < local->scan_req->n_ssids; i++) 657 for (i = 0; i < local->scan_req->n_ssids; i++)
658 ieee80211_send_probe_req( 658 ieee80211_send_probe_req(
@@ -660,7 +660,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
660 local->scan_req->ssids[i].ssid, 660 local->scan_req->ssids[i].ssid,
661 local->scan_req->ssids[i].ssid_len, 661 local->scan_req->ssids[i].ssid_len,
662 local->scan_req->ie, local->scan_req->ie_len, 662 local->scan_req->ie, local->scan_req->ie_len,
663 false); 663 local->scan_req->rates[band], false);
664 664
665 /* 665 /*
666 * After sending probe requests, wait for probe responses 666 * After sending probe requests, wait for probe responses
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c
index cc79e697cdb2..f49d00a4c7fd 100644
--- a/net/mac80211/tkip.c
+++ b/net/mac80211/tkip.c
@@ -185,6 +185,17 @@ void ieee80211_get_tkip_p1k_iv(struct ieee80211_key_conf *keyconf,
185} 185}
186EXPORT_SYMBOL(ieee80211_get_tkip_p1k_iv); 186EXPORT_SYMBOL(ieee80211_get_tkip_p1k_iv);
187 187
188void ieee80211_get_tkip_rx_p1k(struct ieee80211_key_conf *keyconf,
189 const u8 *ta, u32 iv32, u16 *p1k)
190{
191 const u8 *tk = &keyconf->key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
192 struct tkip_ctx ctx;
193
194 tkip_mixing_phase1(tk, &ctx, ta, iv32);
195 memcpy(p1k, ctx.p1k, sizeof(ctx.p1k));
196}
197EXPORT_SYMBOL(ieee80211_get_tkip_rx_p1k);
198
188void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf, 199void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf,
189 struct sk_buff *skb, u8 *p2k) 200 struct sk_buff *skb, u8 *p2k)
190{ 201{
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 5bfb80cba634..ddeb1b998383 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -799,6 +799,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
799 799
800 qparam.uapsd = false; 800 qparam.uapsd = false;
801 801
802 local->tx_conf[queue] = qparam;
802 drv_conf_tx(local, queue, &qparam); 803 drv_conf_tx(local, queue, &qparam);
803 } 804 }
804 805
@@ -1016,7 +1017,7 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1016} 1017}
1017 1018
1018struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, 1019struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1019 u8 *dst, 1020 u8 *dst, u32 ratemask,
1020 const u8 *ssid, size_t ssid_len, 1021 const u8 *ssid, size_t ssid_len,
1021 const u8 *ie, size_t ie_len, 1022 const u8 *ie, size_t ie_len,
1022 bool directed) 1023 bool directed)
@@ -1049,9 +1050,7 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1049 1050
1050 buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, 1051 buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len,
1051 local->hw.conf.channel->band, 1052 local->hw.conf.channel->band,
1052 sdata->rc_rateidx_mask 1053 ratemask, chan);
1053 [local->hw.conf.channel->band],
1054 chan);
1055 1054
1056 skb = ieee80211_probereq_get(&local->hw, &sdata->vif, 1055 skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
1057 ssid, ssid_len, 1056 ssid, ssid_len,
@@ -1072,12 +1071,12 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1072void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, 1071void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
1073 const u8 *ssid, size_t ssid_len, 1072 const u8 *ssid, size_t ssid_len,
1074 const u8 *ie, size_t ie_len, 1073 const u8 *ie, size_t ie_len,
1075 bool directed) 1074 u32 ratemask, bool directed)
1076{ 1075{
1077 struct sk_buff *skb; 1076 struct sk_buff *skb;
1078 1077
1079 skb = ieee80211_build_probe_req(sdata, dst, ssid, ssid_len, ie, ie_len, 1078 skb = ieee80211_build_probe_req(sdata, dst, ratemask, ssid, ssid_len,
1080 directed); 1079 ie, ie_len, directed);
1081 if (skb) 1080 if (skb)
1082 ieee80211_tx_skb(sdata, skb); 1081 ieee80211_tx_skb(sdata, skb);
1083} 1082}
@@ -1134,7 +1133,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1134 struct ieee80211_hw *hw = &local->hw; 1133 struct ieee80211_hw *hw = &local->hw;
1135 struct ieee80211_sub_if_data *sdata; 1134 struct ieee80211_sub_if_data *sdata;
1136 struct sta_info *sta; 1135 struct sta_info *sta;
1137 int res; 1136 int res, i;
1138 1137
1139#ifdef CONFIG_PM 1138#ifdef CONFIG_PM
1140 if (local->suspended) 1139 if (local->suspended)
@@ -1157,27 +1156,37 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1157 } 1156 }
1158#endif 1157#endif
1159 1158
1160 /* restart hardware */ 1159 /* setup fragmentation threshold */
1161 if (local->open_count) { 1160 drv_set_frag_threshold(local, hw->wiphy->frag_threshold);
1162 /* 1161
1163 * Upon resume hardware can sometimes be goofy due to 1162 /* setup RTS threshold */
1164 * various platform / driver / bus issues, so restarting 1163 drv_set_rts_threshold(local, hw->wiphy->rts_threshold);
1165 * the device may at times not work immediately. Propagate 1164
1166 * the error. 1165 /* reset coverage class */
1167 */ 1166 drv_set_coverage_class(local, hw->wiphy->coverage_class);
1168 res = drv_start(local); 1167
1169 if (res) { 1168 /* everything else happens only if HW was up & running */
1170 WARN(local->suspended, "Hardware became unavailable " 1169 if (!local->open_count)
1171 "upon resume. This could be a software issue " 1170 goto wake_up;
1172 "prior to suspend or a hardware issue.\n");
1173 return res;
1174 }
1175 1171
1176 ieee80211_led_radio(local, true); 1172 /*
1177 ieee80211_mod_tpt_led_trig(local, 1173 * Upon resume hardware can sometimes be goofy due to
1178 IEEE80211_TPT_LEDTRIG_FL_RADIO, 0); 1174 * various platform / driver / bus issues, so restarting
1175 * the device may at times not work immediately. Propagate
1176 * the error.
1177 */
1178 res = drv_start(local);
1179 if (res) {
1180 WARN(local->suspended, "Hardware became unavailable "
1181 "upon resume. This could be a software issue "
1182 "prior to suspend or a hardware issue.\n");
1183 return res;
1179 } 1184 }
1180 1185
1186 ieee80211_led_radio(local, true);
1187 ieee80211_mod_tpt_led_trig(local,
1188 IEEE80211_TPT_LEDTRIG_FL_RADIO, 0);
1189
1181 /* add interfaces */ 1190 /* add interfaces */
1182 list_for_each_entry(sdata, &local->interfaces, list) { 1191 list_for_each_entry(sdata, &local->interfaces, list) {
1183 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && 1192 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
@@ -1201,11 +1210,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1201 } 1210 }
1202 mutex_unlock(&local->sta_mtx); 1211 mutex_unlock(&local->sta_mtx);
1203 1212
1204 /* setup fragmentation threshold */ 1213 /* reconfigure tx conf */
1205 drv_set_frag_threshold(local, hw->wiphy->frag_threshold); 1214 for (i = 0; i < hw->queues; i++)
1206 1215 drv_conf_tx(local, i, &local->tx_conf[i]);
1207 /* setup RTS threshold */
1208 drv_set_rts_threshold(local, hw->wiphy->rts_threshold);
1209 1216
1210 /* reconfigure hardware */ 1217 /* reconfigure hardware */
1211 ieee80211_hw_config(local, ~0); 1218 ieee80211_hw_config(local, ~0);
@@ -1287,9 +1294,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1287 if (ieee80211_sdata_running(sdata)) 1294 if (ieee80211_sdata_running(sdata))
1288 ieee80211_enable_keys(sdata); 1295 ieee80211_enable_keys(sdata);
1289 1296
1290#ifdef CONFIG_PM
1291 wake_up: 1297 wake_up:
1292#endif
1293 ieee80211_wake_queues_by_reason(hw, 1298 ieee80211_wake_queues_by_reason(hw,
1294 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 1299 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
1295 1300
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index edf8583280c9..380b9a7462b6 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -25,6 +25,7 @@
25 25
26#include "ieee80211_i.h" 26#include "ieee80211_i.h"
27#include "rate.h" 27#include "rate.h"
28#include "driver-ops.h"
28 29
29#define IEEE80211_AUTH_TIMEOUT (HZ / 5) 30#define IEEE80211_AUTH_TIMEOUT (HZ / 5)
30#define IEEE80211_AUTH_MAX_TRIES 3 31#define IEEE80211_AUTH_MAX_TRIES 3
@@ -427,6 +428,14 @@ ieee80211_direct_probe(struct ieee80211_work *wk)
427 struct ieee80211_sub_if_data *sdata = wk->sdata; 428 struct ieee80211_sub_if_data *sdata = wk->sdata;
428 struct ieee80211_local *local = sdata->local; 429 struct ieee80211_local *local = sdata->local;
429 430
431 if (!wk->probe_auth.synced) {
432 int ret = drv_tx_sync(local, sdata, wk->filter_ta,
433 IEEE80211_TX_SYNC_AUTH);
434 if (ret)
435 return WORK_ACT_TIMEOUT;
436 }
437 wk->probe_auth.synced = true;
438
430 wk->probe_auth.tries++; 439 wk->probe_auth.tries++;
431 if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) { 440 if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) {
432 printk(KERN_DEBUG "%s: direct probe to %pM timed out\n", 441 printk(KERN_DEBUG "%s: direct probe to %pM timed out\n",
@@ -450,7 +459,8 @@ ieee80211_direct_probe(struct ieee80211_work *wk)
450 * will not answer to direct packet in unassociated state. 459 * will not answer to direct packet in unassociated state.
451 */ 460 */
452 ieee80211_send_probe_req(sdata, NULL, wk->probe_auth.ssid, 461 ieee80211_send_probe_req(sdata, NULL, wk->probe_auth.ssid,
453 wk->probe_auth.ssid_len, NULL, 0, true); 462 wk->probe_auth.ssid_len, NULL, 0,
463 (u32) -1, true);
454 464
455 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; 465 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
456 run_again(local, wk->timeout); 466 run_again(local, wk->timeout);
@@ -465,6 +475,14 @@ ieee80211_authenticate(struct ieee80211_work *wk)
465 struct ieee80211_sub_if_data *sdata = wk->sdata; 475 struct ieee80211_sub_if_data *sdata = wk->sdata;
466 struct ieee80211_local *local = sdata->local; 476 struct ieee80211_local *local = sdata->local;
467 477
478 if (!wk->probe_auth.synced) {
479 int ret = drv_tx_sync(local, sdata, wk->filter_ta,
480 IEEE80211_TX_SYNC_AUTH);
481 if (ret)
482 return WORK_ACT_TIMEOUT;
483 }
484 wk->probe_auth.synced = true;
485
468 wk->probe_auth.tries++; 486 wk->probe_auth.tries++;
469 if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) { 487 if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) {
470 printk(KERN_DEBUG "%s: authentication with %pM" 488 printk(KERN_DEBUG "%s: authentication with %pM"
@@ -498,6 +516,14 @@ ieee80211_associate(struct ieee80211_work *wk)
498 struct ieee80211_sub_if_data *sdata = wk->sdata; 516 struct ieee80211_sub_if_data *sdata = wk->sdata;
499 struct ieee80211_local *local = sdata->local; 517 struct ieee80211_local *local = sdata->local;
500 518
519 if (!wk->assoc.synced) {
520 int ret = drv_tx_sync(local, sdata, wk->filter_ta,
521 IEEE80211_TX_SYNC_ASSOC);
522 if (ret)
523 return WORK_ACT_TIMEOUT;
524 }
525 wk->assoc.synced = true;
526
501 wk->assoc.tries++; 527 wk->assoc.tries++;
502 if (wk->assoc.tries > IEEE80211_ASSOC_MAX_TRIES) { 528 if (wk->assoc.tries > IEEE80211_ASSOC_MAX_TRIES) {
503 printk(KERN_DEBUG "%s: association with %pM" 529 printk(KERN_DEBUG "%s: association with %pM"
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 880dbe2e6f94..645437cfc464 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
@@ -918,7 +922,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
918 * Configure power management to the driver here so that its 922 * Configure power management to the driver here so that its
919 * correctly set also after interface type changes etc. 923 * correctly set also after interface type changes etc.
920 */ 924 */
921 if (wdev->iftype == NL80211_IFTYPE_STATION && 925 if ((wdev->iftype == NL80211_IFTYPE_STATION ||
926 wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) &&
922 rdev->ops->set_power_mgmt) 927 rdev->ops->set_power_mgmt)
923 if (rdev->ops->set_power_mgmt(wdev->wiphy, dev, 928 if (rdev->ops->set_power_mgmt(wdev->wiphy, dev,
924 wdev->ps, 929 wdev->ps,
diff --git a/net/wireless/core.h b/net/wireless/core.h
index a570ff9214ec..8672e028022f 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -447,6 +447,10 @@ int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
447 447
448u16 cfg80211_calculate_bitrate(struct rate_info *rate); 448u16 cfg80211_calculate_bitrate(struct rate_info *rate);
449 449
450int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
451 const u8 *rates, unsigned int n_rates,
452 u32 *mask);
453
450int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, 454int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
451 u32 beacon_int); 455 u32 beacon_int);
452 456
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 6a82c898f831..28d2aa109bee 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -177,6 +177,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
177 [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 }, 177 [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 },
178 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 }, 178 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
179 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED }, 179 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
180 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
180}; 181};
181 182
182/* policy for the key attributes */ 183/* policy for the key attributes */
@@ -205,6 +206,10 @@ nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
205 [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG }, 206 [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
206 [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG }, 207 [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
207 [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED }, 208 [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
209 [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG },
210 [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
211 [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
212 [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
208}; 213};
209 214
210/* policy for GTK rekey offload attributes */ 215/* policy for GTK rekey offload attributes */
@@ -692,8 +697,12 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
692 dev->wiphy.coverage_class); 697 dev->wiphy.coverage_class);
693 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS, 698 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
694 dev->wiphy.max_scan_ssids); 699 dev->wiphy.max_scan_ssids);
700 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
701 dev->wiphy.max_sched_scan_ssids);
695 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, 702 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
696 dev->wiphy.max_scan_ie_len); 703 dev->wiphy.max_scan_ie_len);
704 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
705 dev->wiphy.max_sched_scan_ie_len);
697 706
698 if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) 707 if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)
699 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); 708 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN);
@@ -929,6 +938,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); 938 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
930 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT) 939 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT)
931 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT); 940 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
941 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY)
942 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED);
943 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE)
944 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE);
945 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ)
946 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST);
947 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_4WAY_HANDSHAKE)
948 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE);
949 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_RFKILL_RELEASE)
950 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE);
932 if (dev->wiphy.wowlan.n_patterns) { 951 if (dev->wiphy.wowlan.n_patterns) {
933 struct nl80211_wowlan_pattern_support pat = { 952 struct nl80211_wowlan_pattern_support pat = {
934 .max_patterns = dev->wiphy.wowlan.n_patterns, 953 .max_patterns = dev->wiphy.wowlan.n_patterns,
@@ -3306,7 +3325,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3306 struct nlattr *attr; 3325 struct nlattr *attr;
3307 struct wiphy *wiphy; 3326 struct wiphy *wiphy;
3308 int err, tmp, n_ssids = 0, n_channels, i; 3327 int err, tmp, n_ssids = 0, n_channels, i;
3309 enum ieee80211_band band;
3310 size_t ie_len; 3328 size_t ie_len;
3311 3329
3312 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) 3330 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
@@ -3326,6 +3344,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3326 if (!n_channels) 3344 if (!n_channels)
3327 return -EINVAL; 3345 return -EINVAL;
3328 } else { 3346 } else {
3347 enum ieee80211_band band;
3329 n_channels = 0; 3348 n_channels = 0;
3330 3349
3331 for (band = 0; band < IEEE80211_NUM_BANDS; band++) 3350 for (band = 0; band < IEEE80211_NUM_BANDS; band++)
@@ -3386,6 +3405,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3386 i++; 3405 i++;
3387 } 3406 }
3388 } else { 3407 } else {
3408 enum ieee80211_band band;
3409
3389 /* all channels */ 3410 /* all channels */
3390 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 3411 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
3391 int j; 3412 int j;
@@ -3432,6 +3453,30 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3432 request->ie_len); 3453 request->ie_len);
3433 } 3454 }
3434 3455
3456 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
3457 if (wiphy->bands[i])
3458 request->rates[i] =
3459 (1 << wiphy->bands[i]->n_bitrates) - 1;
3460
3461 if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) {
3462 nla_for_each_nested(attr,
3463 info->attrs[NL80211_ATTR_SCAN_SUPP_RATES],
3464 tmp) {
3465 enum ieee80211_band band = nla_type(attr);
3466
3467 if (band < 0 || band > IEEE80211_NUM_BANDS) {
3468 err = -EINVAL;
3469 goto out_free;
3470 }
3471 err = ieee80211_get_ratemask(wiphy->bands[band],
3472 nla_data(attr),
3473 nla_len(attr),
3474 &request->rates[band]);
3475 if (err)
3476 goto out_free;
3477 }
3478 }
3479
3435 request->dev = dev; 3480 request->dev = dev;
3436 request->wiphy = &rdev->wiphy; 3481 request->wiphy = &rdev->wiphy;
3437 3482
@@ -3497,7 +3542,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
3497 tmp) 3542 tmp)
3498 n_ssids++; 3543 n_ssids++;
3499 3544
3500 if (n_ssids > wiphy->max_scan_ssids) 3545 if (n_ssids > wiphy->max_sched_scan_ssids)
3501 return -EINVAL; 3546 return -EINVAL;
3502 3547
3503 if (info->attrs[NL80211_ATTR_IE]) 3548 if (info->attrs[NL80211_ATTR_IE])
@@ -3505,7 +3550,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
3505 else 3550 else
3506 ie_len = 0; 3551 ie_len = 0;
3507 3552
3508 if (ie_len > wiphy->max_scan_ie_len) 3553 if (ie_len > wiphy->max_sched_scan_ie_len)
3509 return -EINVAL; 3554 return -EINVAL;
3510 3555
3511 mutex_lock(&rdev->sched_scan_mtx); 3556 mutex_lock(&rdev->sched_scan_mtx);
@@ -4318,25 +4363,12 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
4318 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); 4363 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
4319 struct ieee80211_supported_band *sband = 4364 struct ieee80211_supported_band *sband =
4320 wiphy->bands[ibss.channel->band]; 4365 wiphy->bands[ibss.channel->band];
4321 int i, j; 4366 int err;
4322 4367
4323 if (n_rates == 0) 4368 err = ieee80211_get_ratemask(sband, rates, n_rates,
4324 return -EINVAL; 4369 &ibss.basic_rates);
4325 4370 if (err)
4326 for (i = 0; i < n_rates; i++) { 4371 return err;
4327 int rate = (rates[i] & 0x7f) * 5;
4328 bool found = false;
4329
4330 for (j = 0; j < sband->n_bitrates; j++) {
4331 if (sband->bitrates[j].bitrate == rate) {
4332 found = true;
4333 ibss.basic_rates |= BIT(j);
4334 break;
4335 }
4336 }
4337 if (!found)
4338 return -EINVAL;
4339 }
4340 } 4372 }
4341 4373
4342 if (info->attrs[NL80211_ATTR_MCAST_RATE] && 4374 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
@@ -5272,6 +5304,14 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
5272 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT); 5304 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
5273 if (rdev->wowlan->magic_pkt) 5305 if (rdev->wowlan->magic_pkt)
5274 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT); 5306 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
5307 if (rdev->wowlan->gtk_rekey_failure)
5308 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE);
5309 if (rdev->wowlan->eap_identity_req)
5310 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST);
5311 if (rdev->wowlan->four_way_handshake)
5312 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE);
5313 if (rdev->wowlan->rfkill_release)
5314 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE);
5275 if (rdev->wowlan->n_patterns) { 5315 if (rdev->wowlan->n_patterns) {
5276 struct nlattr *nl_pats, *nl_pat; 5316 struct nlattr *nl_pats, *nl_pat;
5277 int i, pat_len; 5317 int i, pat_len;
@@ -5348,6 +5388,33 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
5348 new_triggers.magic_pkt = true; 5388 new_triggers.magic_pkt = true;
5349 } 5389 }
5350 5390
5391 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED])
5392 return -EINVAL;
5393
5394 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) {
5395 if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE))
5396 return -EINVAL;
5397 new_triggers.gtk_rekey_failure = true;
5398 }
5399
5400 if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) {
5401 if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ))
5402 return -EINVAL;
5403 new_triggers.eap_identity_req = true;
5404 }
5405
5406 if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) {
5407 if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE))
5408 return -EINVAL;
5409 new_triggers.four_way_handshake = true;
5410 }
5411
5412 if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) {
5413 if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE))
5414 return -EINVAL;
5415 new_triggers.rfkill_release = true;
5416 }
5417
5351 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) { 5418 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
5352 struct nlattr *pat; 5419 struct nlattr *pat;
5353 int n_patterns = 0; 5420 int n_patterns = 0;
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 1c4672e35144..2936cb809152 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -862,6 +862,10 @@ int cfg80211_wext_siwscan(struct net_device *dev,
862 creq->n_ssids = 0; 862 creq->n_ssids = 0;
863 } 863 }
864 864
865 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
866 if (wiphy->bands[i])
867 creq->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
868
865 rdev->scan_req = creq; 869 rdev->scan_req = creq;
866 err = rdev->ops->scan(wiphy, dev, creq); 870 err = rdev->ops->scan(wiphy, dev, creq);
867 if (err) { 871 if (err) {
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 4d7b83fbc32f..be75a3a0424e 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1006,3 +1006,41 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
1006 1006
1007 return -EBUSY; 1007 return -EBUSY;
1008} 1008}
1009
1010int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
1011 const u8 *rates, unsigned int n_rates,
1012 u32 *mask)
1013{
1014 int i, j;
1015
1016 if (!sband)
1017 return -EINVAL;
1018
1019 if (n_rates == 0 || n_rates > NL80211_MAX_SUPP_RATES)
1020 return -EINVAL;
1021
1022 *mask = 0;
1023
1024 for (i = 0; i < n_rates; i++) {
1025 int rate = (rates[i] & 0x7f) * 5;
1026 bool found = false;
1027
1028 for (j = 0; j < sband->n_bitrates; j++) {
1029 if (sband->bitrates[j].bitrate == rate) {
1030 found = true;
1031 *mask |= BIT(j);
1032 break;
1033 }
1034 }
1035 if (!found)
1036 return -EINVAL;
1037 }
1038
1039 /*
1040 * mask must have at least one bit set here since we
1041 * didn't accept a 0-length rates array nor allowed
1042 * entries in the array that didn't exist
1043 */
1044
1045 return 0;
1046}