aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/8021q/vlan_core.c4
-rw-r--r--net/8021q/vlan_dev.c23
-rw-r--r--net/core/datagram.c112
-rw-r--r--net/core/dev.c92
-rw-r--r--net/core/drop_monitor.c13
-rw-r--r--net/core/iovec.c33
-rw-r--r--net/ipv4/af_inet.c2
-rw-r--r--net/ipv4/inet_diag.c2
-rw-r--r--net/ipv4/ip_input.c13
-rw-r--r--net/ipv4/ip_output.c12
-rw-r--r--net/ipv4/proc.c10
-rw-r--r--net/ipv4/syncookies.c5
-rw-r--r--net/ipv4/tcp_ipv4.c2
-rw-r--r--net/ipv6/ip6_input.c7
-rw-r--r--net/ipv6/ip6_output.c9
-rw-r--r--net/ipv6/mcast.c19
-rw-r--r--net/ipv6/ndisc.c4
-rw-r--r--net/ipv6/proc.c10
-rw-r--r--net/ipv6/raw.c2
-rw-r--r--net/ipv6/syncookies.c4
-rw-r--r--net/ipv6/tcp_ipv6.c2
-rw-r--r--net/iucv/af_iucv.c408
-rw-r--r--net/iucv/iucv.c43
-rw-r--r--net/mac80211/Kconfig16
-rw-r--r--net/mac80211/cfg.c59
-rw-r--r--net/mac80211/debugfs.c8
-rw-r--r--net/mac80211/event.c17
-rw-r--r--net/mac80211/ht.c84
-rw-r--r--net/mac80211/ibss.c347
-rw-r--r--net/mac80211/ieee80211_i.h85
-rw-r--r--net/mac80211/iface.c16
-rw-r--r--net/mac80211/main.c122
-rw-r--r--net/mac80211/mlme.c445
-rw-r--r--net/mac80211/pm.c121
-rw-r--r--net/mac80211/rx.c2
-rw-r--r--net/mac80211/scan.c28
-rw-r--r--net/mac80211/spectmgmt.c2
-rw-r--r--net/mac80211/sta_info.c71
-rw-r--r--net/mac80211/sta_info.h3
-rw-r--r--net/mac80211/tx.c35
-rw-r--r--net/mac80211/util.c240
-rw-r--r--net/mac80211/wext.c270
-rw-r--r--net/mac80211/wpa.c2
-rw-r--r--net/rds/af_rds.c1
-rw-r--r--net/rds/connection.c4
-rw-r--r--net/rds/ib.c4
-rw-r--r--net/rds/ib.h2
-rw-r--r--net/rds/ib_recv.c2
-rw-r--r--net/rds/ib_ring.c2
-rw-r--r--net/rds/ib_send.c10
-rw-r--r--net/rds/info.c5
-rw-r--r--net/rds/iw.c4
-rw-r--r--net/rds/iw.h2
-rw-r--r--net/rds/iw_recv.c2
-rw-r--r--net/rds/iw_ring.c2
-rw-r--r--net/rds/iw_send.c10
-rw-r--r--net/rds/rdma.c7
-rw-r--r--net/rds/rdma_transport.c12
-rw-r--r--net/rds/rds.h2
-rw-r--r--net/rds/send.c10
-rw-r--r--net/rfkill/rfkill-input.c69
-rw-r--r--net/rfkill/rfkill.c54
-rw-r--r--net/sctp/output.c17
-rw-r--r--net/wimax/op-rfkill.c9
-rw-r--r--net/wireless/Makefile2
-rw-r--r--net/wireless/core.c27
-rw-r--r--net/wireless/core.h15
-rw-r--r--net/wireless/ibss.c369
-rw-r--r--net/wireless/mlme.c50
-rw-r--r--net/wireless/nl80211.c639
-rw-r--r--net/wireless/nl80211.h32
-rw-r--r--net/wireless/reg.c35
-rw-r--r--net/wireless/scan.c53
-rw-r--r--net/wireless/util.c6
-rw-r--r--net/wireless/wext-compat.c236
75 files changed, 3069 insertions, 1429 deletions
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index c67fe6f75653..7f7de1a04de6 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -114,9 +114,9 @@ int vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
114EXPORT_SYMBOL(vlan_gro_receive); 114EXPORT_SYMBOL(vlan_gro_receive);
115 115
116int vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp, 116int vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
117 unsigned int vlan_tci, struct napi_gro_fraginfo *info) 117 unsigned int vlan_tci)
118{ 118{
119 struct sk_buff *skb = napi_fraginfo_skb(napi, info); 119 struct sk_buff *skb = napi_frags_skb(napi);
120 120
121 if (!skb) 121 if (!skb)
122 return NET_RX_DROP; 122 return NET_RX_DROP;
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index b4b9068e55a7..25ba41e35338 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -671,13 +671,7 @@ static int vlan_ethtool_get_settings(struct net_device *dev,
671 struct ethtool_cmd *cmd) 671 struct ethtool_cmd *cmd)
672{ 672{
673 const struct vlan_dev_info *vlan = vlan_dev_info(dev); 673 const struct vlan_dev_info *vlan = vlan_dev_info(dev);
674 struct net_device *real_dev = vlan->real_dev; 674 return dev_ethtool_get_settings(vlan->real_dev, cmd);
675
676 if (!real_dev->ethtool_ops ||
677 !real_dev->ethtool_ops->get_settings)
678 return -EOPNOTSUPP;
679
680 return real_dev->ethtool_ops->get_settings(real_dev, cmd);
681} 675}
682 676
683static void vlan_ethtool_get_drvinfo(struct net_device *dev, 677static void vlan_ethtool_get_drvinfo(struct net_device *dev,
@@ -691,24 +685,13 @@ static void vlan_ethtool_get_drvinfo(struct net_device *dev,
691static u32 vlan_ethtool_get_rx_csum(struct net_device *dev) 685static u32 vlan_ethtool_get_rx_csum(struct net_device *dev)
692{ 686{
693 const struct vlan_dev_info *vlan = vlan_dev_info(dev); 687 const struct vlan_dev_info *vlan = vlan_dev_info(dev);
694 struct net_device *real_dev = vlan->real_dev; 688 return dev_ethtool_get_rx_csum(vlan->real_dev);
695
696 if (real_dev->ethtool_ops == NULL ||
697 real_dev->ethtool_ops->get_rx_csum == NULL)
698 return 0;
699 return real_dev->ethtool_ops->get_rx_csum(real_dev);
700} 689}
701 690
702static u32 vlan_ethtool_get_flags(struct net_device *dev) 691static u32 vlan_ethtool_get_flags(struct net_device *dev)
703{ 692{
704 const struct vlan_dev_info *vlan = vlan_dev_info(dev); 693 const struct vlan_dev_info *vlan = vlan_dev_info(dev);
705 struct net_device *real_dev = vlan->real_dev; 694 return dev_ethtool_get_flags(vlan->real_dev);
706
707 if (!(real_dev->features & NETIF_F_HW_VLAN_RX) ||
708 real_dev->ethtool_ops == NULL ||
709 real_dev->ethtool_ops->get_flags == NULL)
710 return 0;
711 return real_dev->ethtool_ops->get_flags(real_dev);
712} 695}
713 696
714static const struct ethtool_ops vlan_ethtool_ops = { 697static const struct ethtool_ops vlan_ethtool_ops = {
diff --git a/net/core/datagram.c b/net/core/datagram.c
index b01a76abe1d2..22ea437c5023 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -351,17 +351,111 @@ fault:
351} 351}
352 352
353/** 353/**
354 * skb_copy_datagram_const_iovec - Copy a datagram to an iovec.
355 * @skb: buffer to copy
356 * @offset: offset in the buffer to start copying from
357 * @to: io vector to copy to
358 * @to_offset: offset in the io vector to start copying to
359 * @len: amount of data to copy from buffer to iovec
360 *
361 * Returns 0 or -EFAULT.
362 * Note: the iovec is not modified during the copy.
363 */
364int skb_copy_datagram_const_iovec(const struct sk_buff *skb, int offset,
365 const struct iovec *to, int to_offset,
366 int len)
367{
368 int start = skb_headlen(skb);
369 int i, copy = start - offset;
370
371 /* Copy header. */
372 if (copy > 0) {
373 if (copy > len)
374 copy = len;
375 if (memcpy_toiovecend(to, skb->data + offset, to_offset, copy))
376 goto fault;
377 if ((len -= copy) == 0)
378 return 0;
379 offset += copy;
380 to_offset += copy;
381 }
382
383 /* Copy paged appendix. Hmm... why does this look so complicated? */
384 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
385 int end;
386
387 WARN_ON(start > offset + len);
388
389 end = start + skb_shinfo(skb)->frags[i].size;
390 if ((copy = end - offset) > 0) {
391 int err;
392 u8 *vaddr;
393 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
394 struct page *page = frag->page;
395
396 if (copy > len)
397 copy = len;
398 vaddr = kmap(page);
399 err = memcpy_toiovecend(to, vaddr + frag->page_offset +
400 offset - start, to_offset, copy);
401 kunmap(page);
402 if (err)
403 goto fault;
404 if (!(len -= copy))
405 return 0;
406 offset += copy;
407 to_offset += copy;
408 }
409 start = end;
410 }
411
412 if (skb_shinfo(skb)->frag_list) {
413 struct sk_buff *list = skb_shinfo(skb)->frag_list;
414
415 for (; list; list = list->next) {
416 int end;
417
418 WARN_ON(start > offset + len);
419
420 end = start + list->len;
421 if ((copy = end - offset) > 0) {
422 if (copy > len)
423 copy = len;
424 if (skb_copy_datagram_const_iovec(list,
425 offset - start,
426 to, to_offset,
427 copy))
428 goto fault;
429 if ((len -= copy) == 0)
430 return 0;
431 offset += copy;
432 to_offset += copy;
433 }
434 start = end;
435 }
436 }
437 if (!len)
438 return 0;
439
440fault:
441 return -EFAULT;
442}
443EXPORT_SYMBOL(skb_copy_datagram_const_iovec);
444
445/**
354 * skb_copy_datagram_from_iovec - Copy a datagram from an iovec. 446 * skb_copy_datagram_from_iovec - Copy a datagram from an iovec.
355 * @skb: buffer to copy 447 * @skb: buffer to copy
356 * @offset: offset in the buffer to start copying to 448 * @offset: offset in the buffer to start copying to
357 * @from: io vector to copy to 449 * @from: io vector to copy to
450 * @from_offset: offset in the io vector to start copying from
358 * @len: amount of data to copy to buffer from iovec 451 * @len: amount of data to copy to buffer from iovec
359 * 452 *
360 * Returns 0 or -EFAULT. 453 * Returns 0 or -EFAULT.
361 * Note: the iovec is modified during the copy. 454 * Note: the iovec is not modified during the copy.
362 */ 455 */
363int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, 456int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
364 struct iovec *from, int len) 457 const struct iovec *from, int from_offset,
458 int len)
365{ 459{
366 int start = skb_headlen(skb); 460 int start = skb_headlen(skb);
367 int i, copy = start - offset; 461 int i, copy = start - offset;
@@ -370,11 +464,12 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
370 if (copy > 0) { 464 if (copy > 0) {
371 if (copy > len) 465 if (copy > len)
372 copy = len; 466 copy = len;
373 if (memcpy_fromiovec(skb->data + offset, from, copy)) 467 if (memcpy_fromiovecend(skb->data + offset, from, 0, copy))
374 goto fault; 468 goto fault;
375 if ((len -= copy) == 0) 469 if ((len -= copy) == 0)
376 return 0; 470 return 0;
377 offset += copy; 471 offset += copy;
472 from_offset += copy;
378 } 473 }
379 474
380 /* Copy paged appendix. Hmm... why does this look so complicated? */ 475 /* Copy paged appendix. Hmm... why does this look so complicated? */
@@ -393,8 +488,9 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
393 if (copy > len) 488 if (copy > len)
394 copy = len; 489 copy = len;
395 vaddr = kmap(page); 490 vaddr = kmap(page);
396 err = memcpy_fromiovec(vaddr + frag->page_offset + 491 err = memcpy_fromiovecend(vaddr + frag->page_offset +
397 offset - start, from, copy); 492 offset - start,
493 from, from_offset, copy);
398 kunmap(page); 494 kunmap(page);
399 if (err) 495 if (err)
400 goto fault; 496 goto fault;
@@ -402,6 +498,7 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
402 if (!(len -= copy)) 498 if (!(len -= copy))
403 return 0; 499 return 0;
404 offset += copy; 500 offset += copy;
501 from_offset += copy;
405 } 502 }
406 start = end; 503 start = end;
407 } 504 }
@@ -420,11 +517,14 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
420 copy = len; 517 copy = len;
421 if (skb_copy_datagram_from_iovec(list, 518 if (skb_copy_datagram_from_iovec(list,
422 offset - start, 519 offset - start,
423 from, copy)) 520 from,
521 from_offset,
522 copy))
424 goto fault; 523 goto fault;
425 if ((len -= copy) == 0) 524 if ((len -= copy) == 0)
426 return 0; 525 return 0;
427 offset += copy; 526 offset += copy;
527 from_offset += copy;
428 } 528 }
429 start = end; 529 start = end;
430 } 530 }
diff --git a/net/core/dev.c b/net/core/dev.c
index 308a7d0c277f..6785b067ad50 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2378,18 +2378,13 @@ void *skb_gro_header(struct sk_buff *skb, unsigned int hlen)
2378 unsigned int offset = skb_gro_offset(skb); 2378 unsigned int offset = skb_gro_offset(skb);
2379 2379
2380 hlen += offset; 2380 hlen += offset;
2381 if (hlen <= skb_headlen(skb)) 2381 if (unlikely(skb_headlen(skb) ||
2382 return skb->data + offset; 2382 skb_shinfo(skb)->frags[0].size < hlen ||
2383
2384 if (unlikely(!skb_shinfo(skb)->nr_frags ||
2385 skb_shinfo(skb)->frags[0].size <=
2386 hlen - skb_headlen(skb) ||
2387 PageHighMem(skb_shinfo(skb)->frags[0].page))) 2383 PageHighMem(skb_shinfo(skb)->frags[0].page)))
2388 return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL; 2384 return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL;
2389 2385
2390 return page_address(skb_shinfo(skb)->frags[0].page) + 2386 return page_address(skb_shinfo(skb)->frags[0].page) +
2391 skb_shinfo(skb)->frags[0].page_offset + 2387 skb_shinfo(skb)->frags[0].page_offset + offset;
2392 offset - skb_headlen(skb);
2393} 2388}
2394EXPORT_SYMBOL(skb_gro_header); 2389EXPORT_SYMBOL(skb_gro_header);
2395 2390
@@ -2525,16 +2520,10 @@ void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb)
2525} 2520}
2526EXPORT_SYMBOL(napi_reuse_skb); 2521EXPORT_SYMBOL(napi_reuse_skb);
2527 2522
2528struct sk_buff *napi_fraginfo_skb(struct napi_struct *napi, 2523struct sk_buff *napi_get_frags(struct napi_struct *napi)
2529 struct napi_gro_fraginfo *info)
2530{ 2524{
2531 struct net_device *dev = napi->dev; 2525 struct net_device *dev = napi->dev;
2532 struct sk_buff *skb = napi->skb; 2526 struct sk_buff *skb = napi->skb;
2533 struct ethhdr *eth;
2534 skb_frag_t *frag;
2535 int i;
2536
2537 napi->skb = NULL;
2538 2527
2539 if (!skb) { 2528 if (!skb) {
2540 skb = netdev_alloc_skb(dev, GRO_MAX_HEAD + NET_IP_ALIGN); 2529 skb = netdev_alloc_skb(dev, GRO_MAX_HEAD + NET_IP_ALIGN);
@@ -2542,47 +2531,14 @@ struct sk_buff *napi_fraginfo_skb(struct napi_struct *napi,
2542 goto out; 2531 goto out;
2543 2532
2544 skb_reserve(skb, NET_IP_ALIGN); 2533 skb_reserve(skb, NET_IP_ALIGN);
2545 }
2546
2547 BUG_ON(info->nr_frags > MAX_SKB_FRAGS);
2548 frag = info->frags;
2549 2534
2550 for (i = 0; i < info->nr_frags; i++) { 2535 napi->skb = skb;
2551 skb_fill_page_desc(skb, i, frag->page, frag->page_offset,
2552 frag->size);
2553 frag++;
2554 }
2555 skb_shinfo(skb)->nr_frags = info->nr_frags;
2556
2557 skb->data_len = info->len;
2558 skb->len += info->len;
2559 skb->truesize += info->len;
2560
2561 skb_reset_mac_header(skb);
2562 skb_gro_reset_offset(skb);
2563
2564 eth = skb_gro_header(skb, sizeof(*eth));
2565 if (!eth) {
2566 napi_reuse_skb(napi, skb);
2567 skb = NULL;
2568 goto out;
2569 } 2536 }
2570 2537
2571 skb_gro_pull(skb, sizeof(*eth));
2572
2573 /*
2574 * This works because the only protocols we care about don't require
2575 * special handling. We'll fix it up properly at the end.
2576 */
2577 skb->protocol = eth->h_proto;
2578
2579 skb->ip_summed = info->ip_summed;
2580 skb->csum = info->csum;
2581
2582out: 2538out:
2583 return skb; 2539 return skb;
2584} 2540}
2585EXPORT_SYMBOL(napi_fraginfo_skb); 2541EXPORT_SYMBOL(napi_get_frags);
2586 2542
2587int napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb, int ret) 2543int napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb, int ret)
2588{ 2544{
@@ -2612,9 +2568,39 @@ int napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb, int ret)
2612} 2568}
2613EXPORT_SYMBOL(napi_frags_finish); 2569EXPORT_SYMBOL(napi_frags_finish);
2614 2570
2615int napi_gro_frags(struct napi_struct *napi, struct napi_gro_fraginfo *info) 2571struct sk_buff *napi_frags_skb(struct napi_struct *napi)
2572{
2573 struct sk_buff *skb = napi->skb;
2574 struct ethhdr *eth;
2575
2576 napi->skb = NULL;
2577
2578 skb_reset_mac_header(skb);
2579 skb_gro_reset_offset(skb);
2580
2581 eth = skb_gro_header(skb, sizeof(*eth));
2582 if (!eth) {
2583 napi_reuse_skb(napi, skb);
2584 skb = NULL;
2585 goto out;
2586 }
2587
2588 skb_gro_pull(skb, sizeof(*eth));
2589
2590 /*
2591 * This works because the only protocols we care about don't require
2592 * special handling. We'll fix it up properly at the end.
2593 */
2594 skb->protocol = eth->h_proto;
2595
2596out:
2597 return skb;
2598}
2599EXPORT_SYMBOL(napi_frags_skb);
2600
2601int napi_gro_frags(struct napi_struct *napi)
2616{ 2602{
2617 struct sk_buff *skb = napi_fraginfo_skb(napi, info); 2603 struct sk_buff *skb = napi_frags_skb(napi);
2618 2604
2619 if (!skb) 2605 if (!skb)
2620 return NET_RX_DROP; 2606 return NET_RX_DROP;
@@ -2718,7 +2704,7 @@ void netif_napi_del(struct napi_struct *napi)
2718 struct sk_buff *skb, *next; 2704 struct sk_buff *skb, *next;
2719 2705
2720 list_del_init(&napi->dev_list); 2706 list_del_init(&napi->dev_list);
2721 kfree_skb(napi->skb); 2707 napi_free_frags(napi);
2722 2708
2723 for (skb = napi->gro_list; skb; skb = next) { 2709 for (skb = napi->gro_list; skb; skb = next) {
2724 next = skb->next; 2710 next = skb->next;
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index 9fd0dc3cca99..2797b711a978 100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -51,7 +51,7 @@ static struct genl_family net_drop_monitor_family = {
51 .id = GENL_ID_GENERATE, 51 .id = GENL_ID_GENERATE,
52 .hdrsize = 0, 52 .hdrsize = 0,
53 .name = "NET_DM", 53 .name = "NET_DM",
54 .version = 1, 54 .version = 2,
55 .maxattr = NET_DM_CMD_MAX, 55 .maxattr = NET_DM_CMD_MAX,
56}; 56};
57 57
@@ -65,13 +65,17 @@ static void reset_per_cpu_data(struct per_cpu_dm_data *data)
65{ 65{
66 size_t al; 66 size_t al;
67 struct net_dm_alert_msg *msg; 67 struct net_dm_alert_msg *msg;
68 struct nlattr *nla;
68 69
69 al = sizeof(struct net_dm_alert_msg); 70 al = sizeof(struct net_dm_alert_msg);
70 al += dm_hit_limit * sizeof(struct net_dm_drop_point); 71 al += dm_hit_limit * sizeof(struct net_dm_drop_point);
72 al += sizeof(struct nlattr);
73
71 data->skb = genlmsg_new(al, GFP_KERNEL); 74 data->skb = genlmsg_new(al, GFP_KERNEL);
72 genlmsg_put(data->skb, 0, 0, &net_drop_monitor_family, 75 genlmsg_put(data->skb, 0, 0, &net_drop_monitor_family,
73 0, NET_DM_CMD_ALERT); 76 0, NET_DM_CMD_ALERT);
74 msg = __nla_reserve_nohdr(data->skb, sizeof(struct net_dm_alert_msg)); 77 nla = nla_reserve(data->skb, NLA_UNSPEC, sizeof(struct net_dm_alert_msg));
78 msg = nla_data(nla);
75 memset(msg, 0, al); 79 memset(msg, 0, al);
76 atomic_set(&data->dm_hit_count, dm_hit_limit); 80 atomic_set(&data->dm_hit_count, dm_hit_limit);
77} 81}
@@ -115,6 +119,7 @@ static void trace_kfree_skb_hit(struct sk_buff *skb, void *location)
115{ 119{
116 struct net_dm_alert_msg *msg; 120 struct net_dm_alert_msg *msg;
117 struct nlmsghdr *nlh; 121 struct nlmsghdr *nlh;
122 struct nlattr *nla;
118 int i; 123 int i;
119 struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data); 124 struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data);
120 125
@@ -127,7 +132,8 @@ static void trace_kfree_skb_hit(struct sk_buff *skb, void *location)
127 } 132 }
128 133
129 nlh = (struct nlmsghdr *)data->skb->data; 134 nlh = (struct nlmsghdr *)data->skb->data;
130 msg = genlmsg_data(nlmsg_data(nlh)); 135 nla = genlmsg_data(nlmsg_data(nlh));
136 msg = nla_data(nla);
131 for (i = 0; i < msg->entries; i++) { 137 for (i = 0; i < msg->entries; i++) {
132 if (!memcmp(&location, msg->points[i].pc, sizeof(void *))) { 138 if (!memcmp(&location, msg->points[i].pc, sizeof(void *))) {
133 msg->points[i].count++; 139 msg->points[i].count++;
@@ -139,6 +145,7 @@ static void trace_kfree_skb_hit(struct sk_buff *skb, void *location)
139 * We need to create a new entry 145 * We need to create a new entry
140 */ 146 */
141 __nla_reserve_nohdr(data->skb, sizeof(struct net_dm_drop_point)); 147 __nla_reserve_nohdr(data->skb, sizeof(struct net_dm_drop_point));
148 nla->nla_len += NLA_ALIGN(sizeof(struct net_dm_drop_point));
142 memcpy(msg->points[msg->entries].pc, &location, sizeof(void *)); 149 memcpy(msg->points[msg->entries].pc, &location, sizeof(void *));
143 msg->points[msg->entries].count = 1; 150 msg->points[msg->entries].count = 1;
144 msg->entries++; 151 msg->entries++;
diff --git a/net/core/iovec.c b/net/core/iovec.c
index 4c9c0121c9da..40a76ce19d9f 100644
--- a/net/core/iovec.c
+++ b/net/core/iovec.c
@@ -98,6 +98,31 @@ int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len)
98} 98}
99 99
100/* 100/*
101 * Copy kernel to iovec. Returns -EFAULT on error.
102 */
103
104int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata,
105 int offset, int len)
106{
107 int copy;
108 for (; len > 0; ++iov) {
109 /* Skip over the finished iovecs */
110 if (unlikely(offset >= iov->iov_len)) {
111 offset -= iov->iov_len;
112 continue;
113 }
114 copy = min_t(unsigned int, iov->iov_len - offset, len);
115 offset = 0;
116 if (copy_to_user(iov->iov_base, kdata, copy))
117 return -EFAULT;
118 kdata += copy;
119 len -= copy;
120 }
121
122 return 0;
123}
124
125/*
101 * Copy iovec to kernel. Returns -EFAULT on error. 126 * Copy iovec to kernel. Returns -EFAULT on error.
102 * 127 *
103 * Note: this modifies the original iovec. 128 * Note: this modifies the original iovec.
@@ -122,10 +147,11 @@ int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len)
122} 147}
123 148
124/* 149/*
125 * For use with ip_build_xmit 150 * Copy iovec from kernel. Returns -EFAULT on error.
126 */ 151 */
127int memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, int offset, 152
128 int len) 153int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
154 int offset, int len)
129{ 155{
130 /* Skip over the finished iovecs */ 156 /* Skip over the finished iovecs */
131 while (offset >= iov->iov_len) { 157 while (offset >= iov->iov_len) {
@@ -236,3 +262,4 @@ EXPORT_SYMBOL(csum_partial_copy_fromiovecend);
236EXPORT_SYMBOL(memcpy_fromiovec); 262EXPORT_SYMBOL(memcpy_fromiovec);
237EXPORT_SYMBOL(memcpy_fromiovecend); 263EXPORT_SYMBOL(memcpy_fromiovecend);
238EXPORT_SYMBOL(memcpy_toiovec); 264EXPORT_SYMBOL(memcpy_toiovec);
265EXPORT_SYMBOL(memcpy_toiovecend);
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 7f03373b8c07..170689681aa2 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1003,8 +1003,6 @@ void inet_register_protosw(struct inet_protosw *p)
1003out: 1003out:
1004 spin_unlock_bh(&inetsw_lock); 1004 spin_unlock_bh(&inetsw_lock);
1005 1005
1006 synchronize_net();
1007
1008 return; 1006 return;
1009 1007
1010out_permanent: 1008out_permanent:
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 588a7796e3e3..b0b273503e2a 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -198,8 +198,6 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
198 tmo = 0; 198 tmo = 0;
199 199
200 r->idiag_family = tw->tw_family; 200 r->idiag_family = tw->tw_family;
201 r->idiag_state = tw->tw_state;
202 r->idiag_timer = 0;
203 r->idiag_retrans = 0; 201 r->idiag_retrans = 0;
204 r->id.idiag_if = tw->tw_bound_dev_if; 202 r->id.idiag_if = tw->tw_bound_dev_if;
205 r->id.idiag_cookie[0] = (u32)(unsigned long)tw; 203 r->id.idiag_cookie[0] = (u32)(unsigned long)tw;
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 1a58a6fa1dc0..40f6206b2aa9 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -358,10 +358,12 @@ static int ip_rcv_finish(struct sk_buff *skb)
358 goto drop; 358 goto drop;
359 359
360 rt = skb->rtable; 360 rt = skb->rtable;
361 if (rt->rt_type == RTN_MULTICAST) 361 if (rt->rt_type == RTN_MULTICAST) {
362 IP_INC_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INMCASTPKTS); 362 IP_UPD_PO_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INMCAST,
363 else if (rt->rt_type == RTN_BROADCAST) 363 skb->len);
364 IP_INC_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INBCASTPKTS); 364 } else if (rt->rt_type == RTN_BROADCAST)
365 IP_UPD_PO_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INBCAST,
366 skb->len);
365 367
366 return dst_input(skb); 368 return dst_input(skb);
367 369
@@ -384,7 +386,8 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
384 if (skb->pkt_type == PACKET_OTHERHOST) 386 if (skb->pkt_type == PACKET_OTHERHOST)
385 goto drop; 387 goto drop;
386 388
387 IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INRECEIVES); 389
390 IP_UPD_PO_STATS_BH(dev_net(dev), IPSTATS_MIB_IN, skb->len);
388 391
389 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { 392 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
390 IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS); 393 IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS);
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 3e7e910c7c0f..ea19c37ccc0c 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -181,10 +181,10 @@ static inline int ip_finish_output2(struct sk_buff *skb)
181 struct net_device *dev = dst->dev; 181 struct net_device *dev = dst->dev;
182 unsigned int hh_len = LL_RESERVED_SPACE(dev); 182 unsigned int hh_len = LL_RESERVED_SPACE(dev);
183 183
184 if (rt->rt_type == RTN_MULTICAST) 184 if (rt->rt_type == RTN_MULTICAST) {
185 IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTMCASTPKTS); 185 IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUTMCAST, skb->len);
186 else if (rt->rt_type == RTN_BROADCAST) 186 } else if (rt->rt_type == RTN_BROADCAST)
187 IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTBCASTPKTS); 187 IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUTBCAST, skb->len);
188 188
189 /* Be paranoid, rather than too clever. */ 189 /* Be paranoid, rather than too clever. */
190 if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) { 190 if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) {
@@ -244,7 +244,7 @@ int ip_mc_output(struct sk_buff *skb)
244 /* 244 /*
245 * If the indicated interface is up and running, send the packet. 245 * If the indicated interface is up and running, send the packet.
246 */ 246 */
247 IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTREQUESTS); 247 IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUT, skb->len);
248 248
249 skb->dev = dev; 249 skb->dev = dev;
250 skb->protocol = htons(ETH_P_IP); 250 skb->protocol = htons(ETH_P_IP);
@@ -298,7 +298,7 @@ int ip_output(struct sk_buff *skb)
298{ 298{
299 struct net_device *dev = skb->dst->dev; 299 struct net_device *dev = skb->dst->dev;
300 300
301 IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTREQUESTS); 301 IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUT, skb->len);
302 302
303 skb->dev = dev; 303 skb->dev = dev;
304 skb->protocol = htons(ETH_P_IP); 304 skb->protocol = htons(ETH_P_IP);
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index cf0cdeeb1db0..f25542c48b7d 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -90,14 +90,14 @@ static const struct file_operations sockstat_seq_fops = {
90 90
91/* snmp items */ 91/* snmp items */
92static const struct snmp_mib snmp4_ipstats_list[] = { 92static const struct snmp_mib snmp4_ipstats_list[] = {
93 SNMP_MIB_ITEM("InReceives", IPSTATS_MIB_INRECEIVES), 93 SNMP_MIB_ITEM("InReceives", IPSTATS_MIB_INPKTS),
94 SNMP_MIB_ITEM("InHdrErrors", IPSTATS_MIB_INHDRERRORS), 94 SNMP_MIB_ITEM("InHdrErrors", IPSTATS_MIB_INHDRERRORS),
95 SNMP_MIB_ITEM("InAddrErrors", IPSTATS_MIB_INADDRERRORS), 95 SNMP_MIB_ITEM("InAddrErrors", IPSTATS_MIB_INADDRERRORS),
96 SNMP_MIB_ITEM("ForwDatagrams", IPSTATS_MIB_OUTFORWDATAGRAMS), 96 SNMP_MIB_ITEM("ForwDatagrams", IPSTATS_MIB_OUTFORWDATAGRAMS),
97 SNMP_MIB_ITEM("InUnknownProtos", IPSTATS_MIB_INUNKNOWNPROTOS), 97 SNMP_MIB_ITEM("InUnknownProtos", IPSTATS_MIB_INUNKNOWNPROTOS),
98 SNMP_MIB_ITEM("InDiscards", IPSTATS_MIB_INDISCARDS), 98 SNMP_MIB_ITEM("InDiscards", IPSTATS_MIB_INDISCARDS),
99 SNMP_MIB_ITEM("InDelivers", IPSTATS_MIB_INDELIVERS), 99 SNMP_MIB_ITEM("InDelivers", IPSTATS_MIB_INDELIVERS),
100 SNMP_MIB_ITEM("OutRequests", IPSTATS_MIB_OUTREQUESTS), 100 SNMP_MIB_ITEM("OutRequests", IPSTATS_MIB_OUTPKTS),
101 SNMP_MIB_ITEM("OutDiscards", IPSTATS_MIB_OUTDISCARDS), 101 SNMP_MIB_ITEM("OutDiscards", IPSTATS_MIB_OUTDISCARDS),
102 SNMP_MIB_ITEM("OutNoRoutes", IPSTATS_MIB_OUTNOROUTES), 102 SNMP_MIB_ITEM("OutNoRoutes", IPSTATS_MIB_OUTNOROUTES),
103 SNMP_MIB_ITEM("ReasmTimeout", IPSTATS_MIB_REASMTIMEOUT), 103 SNMP_MIB_ITEM("ReasmTimeout", IPSTATS_MIB_REASMTIMEOUT),
@@ -118,6 +118,12 @@ static const struct snmp_mib snmp4_ipextstats_list[] = {
118 SNMP_MIB_ITEM("OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS), 118 SNMP_MIB_ITEM("OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS),
119 SNMP_MIB_ITEM("InBcastPkts", IPSTATS_MIB_INBCASTPKTS), 119 SNMP_MIB_ITEM("InBcastPkts", IPSTATS_MIB_INBCASTPKTS),
120 SNMP_MIB_ITEM("OutBcastPkts", IPSTATS_MIB_OUTBCASTPKTS), 120 SNMP_MIB_ITEM("OutBcastPkts", IPSTATS_MIB_OUTBCASTPKTS),
121 SNMP_MIB_ITEM("InOctets", IPSTATS_MIB_INOCTETS),
122 SNMP_MIB_ITEM("OutOctets", IPSTATS_MIB_OUTOCTETS),
123 SNMP_MIB_ITEM("InMcastOctets", IPSTATS_MIB_INMCASTOCTETS),
124 SNMP_MIB_ITEM("OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS),
125 SNMP_MIB_ITEM("InBcastOctets", IPSTATS_MIB_INBCASTOCTETS),
126 SNMP_MIB_ITEM("OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS),
121 SNMP_MIB_SENTINEL 127 SNMP_MIB_SENTINEL
122}; 128};
123 129
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index b35a950d2e06..cd2b97f1b6e1 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -161,13 +161,12 @@ static __u16 const msstab[] = {
161 */ 161 */
162__u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp) 162__u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp)
163{ 163{
164 struct tcp_sock *tp = tcp_sk(sk);
165 const struct iphdr *iph = ip_hdr(skb); 164 const struct iphdr *iph = ip_hdr(skb);
166 const struct tcphdr *th = tcp_hdr(skb); 165 const struct tcphdr *th = tcp_hdr(skb);
167 int mssind; 166 int mssind;
168 const __u16 mss = *mssp; 167 const __u16 mss = *mssp;
169 168
170 tp->last_synq_overflow = jiffies; 169 tcp_synq_overflow(sk);
171 170
172 /* XXX sort msstab[] by probability? Binary search? */ 171 /* XXX sort msstab[] by probability? Binary search? */
173 for (mssind = 0; mss > msstab[mssind + 1]; mssind++) 172 for (mssind = 0; mss > msstab[mssind + 1]; mssind++)
@@ -268,7 +267,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
268 if (!sysctl_tcp_syncookies || !th->ack) 267 if (!sysctl_tcp_syncookies || !th->ack)
269 goto out; 268 goto out;
270 269
271 if (time_after(jiffies, tp->last_synq_overflow + TCP_TIMEOUT_INIT) || 270 if (tcp_synq_no_recent_overflow(sk) ||
272 (mss = cookie_check(skb, cookie)) == 0) { 271 (mss = cookie_check(skb, cookie)) == 0) {
273 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESFAILED); 272 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESFAILED);
274 goto out; 273 goto out;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 5d427f86b414..bda74e8aed7e 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2343,7 +2343,7 @@ void tcp4_proc_exit(void)
2343 2343
2344struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *skb) 2344struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *skb)
2345{ 2345{
2346 struct iphdr *iph = ip_hdr(skb); 2346 struct iphdr *iph = skb_gro_network_header(skb);
2347 2347
2348 switch (skb->ip_summed) { 2348 switch (skb->ip_summed) {
2349 case CHECKSUM_COMPLETE: 2349 case CHECKSUM_COMPLETE:
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 8f04bd9da274..bc1a920c34a1 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -70,7 +70,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
70 70
71 idev = __in6_dev_get(skb->dev); 71 idev = __in6_dev_get(skb->dev);
72 72
73 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INRECEIVES); 73 IP6_UPD_PO_STATS_BH(net, idev, IPSTATS_MIB_IN, skb->len);
74 74
75 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL || 75 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL ||
76 !idev || unlikely(idev->cnf.disable_ipv6)) { 76 !idev || unlikely(idev->cnf.disable_ipv6)) {
@@ -242,8 +242,9 @@ int ip6_mc_input(struct sk_buff *skb)
242 struct ipv6hdr *hdr; 242 struct ipv6hdr *hdr;
243 int deliver; 243 int deliver;
244 244
245 IP6_INC_STATS_BH(dev_net(skb->dst->dev), 245 IP6_UPD_PO_STATS_BH(dev_net(skb->dst->dev),
246 ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS); 246 ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCAST,
247 skb->len);
247 248
248 hdr = ipv6_hdr(skb); 249 hdr = ipv6_hdr(skb);
249 deliver = ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL); 250 deliver = ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL);
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 9fb49c3b518a..735a2bf4b5f1 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -159,7 +159,8 @@ static int ip6_output2(struct sk_buff *skb)
159 } 159 }
160 } 160 }
161 161
162 IP6_INC_STATS(dev_net(dev), idev, IPSTATS_MIB_OUTMCASTPKTS); 162 IP6_UPD_PO_STATS(dev_net(dev), idev, IPSTATS_MIB_OUTMCAST,
163 skb->len);
163 } 164 }
164 165
165 return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev, 166 return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev,
@@ -275,8 +276,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
275 276
276 mtu = dst_mtu(dst); 277 mtu = dst_mtu(dst);
277 if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) { 278 if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) {
278 IP6_INC_STATS(net, ip6_dst_idev(skb->dst), 279 IP6_UPD_PO_STATS(net, ip6_dst_idev(skb->dst),
279 IPSTATS_MIB_OUTREQUESTS); 280 IPSTATS_MIB_OUT, skb->len);
280 return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, 281 return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
281 dst_output); 282 dst_output);
282 } 283 }
@@ -1516,7 +1517,7 @@ int ip6_push_pending_frames(struct sock *sk)
1516 skb->mark = sk->sk_mark; 1517 skb->mark = sk->sk_mark;
1517 1518
1518 skb->dst = dst_clone(&rt->u.dst); 1519 skb->dst = dst_clone(&rt->u.dst);
1519 IP6_INC_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS); 1520 IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
1520 if (proto == IPPROTO_ICMPV6) { 1521 if (proto == IPPROTO_ICMPV6) {
1521 struct inet6_dev *idev = ip6_dst_idev(skb->dst); 1522 struct inet6_dev *idev = ip6_dst_idev(skb->dst);
1522 1523
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index a51fb33e6864..4b48819a5b8d 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1449,7 +1449,8 @@ static void mld_sendpack(struct sk_buff *skb)
1449 int err; 1449 int err;
1450 struct flowi fl; 1450 struct flowi fl;
1451 1451
1452 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS); 1452 IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
1453
1453 payload_len = (skb->tail - skb->network_header) - sizeof(*pip6); 1454 payload_len = (skb->tail - skb->network_header) - sizeof(*pip6);
1454 mldlen = skb->tail - skb->transport_header; 1455 mldlen = skb->tail - skb->transport_header;
1455 pip6->payload_len = htons(payload_len); 1456 pip6->payload_len = htons(payload_len);
@@ -1473,13 +1474,15 @@ static void mld_sendpack(struct sk_buff *skb)
1473 if (err) 1474 if (err)
1474 goto err_out; 1475 goto err_out;
1475 1476
1477 payload_len = skb->len;
1478
1476 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev, 1479 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
1477 dst_output); 1480 dst_output);
1478out: 1481out:
1479 if (!err) { 1482 if (!err) {
1480 ICMP6MSGOUT_INC_STATS_BH(net, idev, ICMPV6_MLD2_REPORT); 1483 ICMP6MSGOUT_INC_STATS_BH(net, idev, ICMPV6_MLD2_REPORT);
1481 ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); 1484 ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS);
1482 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTMCASTPKTS); 1485 IP6_UPD_PO_STATS_BH(net, idev, IPSTATS_MIB_OUTMCAST, payload_len);
1483 } else 1486 } else
1484 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTDISCARDS); 1487 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTDISCARDS);
1485 1488
@@ -1773,10 +1776,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1773 IPV6_TLV_PADN, 0 }; 1776 IPV6_TLV_PADN, 0 };
1774 struct flowi fl; 1777 struct flowi fl;
1775 1778
1776 rcu_read_lock();
1777 IP6_INC_STATS(net, __in6_dev_get(dev),
1778 IPSTATS_MIB_OUTREQUESTS);
1779 rcu_read_unlock();
1780 if (type == ICMPV6_MGM_REDUCTION) 1779 if (type == ICMPV6_MGM_REDUCTION)
1781 snd_addr = &in6addr_linklocal_allrouters; 1780 snd_addr = &in6addr_linklocal_allrouters;
1782 else 1781 else
@@ -1786,6 +1785,11 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1786 payload_len = len + sizeof(ra); 1785 payload_len = len + sizeof(ra);
1787 full_len = sizeof(struct ipv6hdr) + payload_len; 1786 full_len = sizeof(struct ipv6hdr) + payload_len;
1788 1787
1788 rcu_read_lock();
1789 IP6_UPD_PO_STATS(net, __in6_dev_get(dev),
1790 IPSTATS_MIB_OUT, full_len);
1791 rcu_read_unlock();
1792
1789 skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + full_len, 1, &err); 1793 skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + full_len, 1, &err);
1790 1794
1791 if (skb == NULL) { 1795 if (skb == NULL) {
@@ -1838,13 +1842,14 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1838 if (err) 1842 if (err)
1839 goto err_out; 1843 goto err_out;
1840 1844
1845
1841 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev, 1846 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
1842 dst_output); 1847 dst_output);
1843out: 1848out:
1844 if (!err) { 1849 if (!err) {
1845 ICMP6MSGOUT_INC_STATS(net, idev, type); 1850 ICMP6MSGOUT_INC_STATS(net, idev, type);
1846 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS); 1851 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
1847 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTMCASTPKTS); 1852 IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, full_len);
1848 } else 1853 } else
1849 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS); 1854 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
1850 1855
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 9f061d1adbc2..ab65cc51b00e 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -533,7 +533,7 @@ void ndisc_send_skb(struct sk_buff *skb,
533 skb->dst = dst; 533 skb->dst = dst;
534 534
535 idev = in6_dev_get(dst->dev); 535 idev = in6_dev_get(dst->dev);
536 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS); 536 IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
537 537
538 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, 538 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
539 dst_output); 539 dst_output);
@@ -1613,7 +1613,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1613 1613
1614 buff->dst = dst; 1614 buff->dst = dst;
1615 idev = in6_dev_get(dst->dev); 1615 idev = in6_dev_get(dst->dev);
1616 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS); 1616 IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
1617 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev, 1617 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev,
1618 dst_output); 1618 dst_output);
1619 if (!err) { 1619 if (!err) {
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index 97c17fdd6f75..590ddefb7ffc 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -61,7 +61,7 @@ static const struct file_operations sockstat6_seq_fops = {
61 61
62static struct snmp_mib snmp6_ipstats_list[] = { 62static struct snmp_mib snmp6_ipstats_list[] = {
63/* ipv6 mib according to RFC 2465 */ 63/* ipv6 mib according to RFC 2465 */
64 SNMP_MIB_ITEM("Ip6InReceives", IPSTATS_MIB_INRECEIVES), 64 SNMP_MIB_ITEM("Ip6InReceives", IPSTATS_MIB_INPKTS),
65 SNMP_MIB_ITEM("Ip6InHdrErrors", IPSTATS_MIB_INHDRERRORS), 65 SNMP_MIB_ITEM("Ip6InHdrErrors", IPSTATS_MIB_INHDRERRORS),
66 SNMP_MIB_ITEM("Ip6InTooBigErrors", IPSTATS_MIB_INTOOBIGERRORS), 66 SNMP_MIB_ITEM("Ip6InTooBigErrors", IPSTATS_MIB_INTOOBIGERRORS),
67 SNMP_MIB_ITEM("Ip6InNoRoutes", IPSTATS_MIB_INNOROUTES), 67 SNMP_MIB_ITEM("Ip6InNoRoutes", IPSTATS_MIB_INNOROUTES),
@@ -71,7 +71,7 @@ static struct snmp_mib snmp6_ipstats_list[] = {
71 SNMP_MIB_ITEM("Ip6InDiscards", IPSTATS_MIB_INDISCARDS), 71 SNMP_MIB_ITEM("Ip6InDiscards", IPSTATS_MIB_INDISCARDS),
72 SNMP_MIB_ITEM("Ip6InDelivers", IPSTATS_MIB_INDELIVERS), 72 SNMP_MIB_ITEM("Ip6InDelivers", IPSTATS_MIB_INDELIVERS),
73 SNMP_MIB_ITEM("Ip6OutForwDatagrams", IPSTATS_MIB_OUTFORWDATAGRAMS), 73 SNMP_MIB_ITEM("Ip6OutForwDatagrams", IPSTATS_MIB_OUTFORWDATAGRAMS),
74 SNMP_MIB_ITEM("Ip6OutRequests", IPSTATS_MIB_OUTREQUESTS), 74 SNMP_MIB_ITEM("Ip6OutRequests", IPSTATS_MIB_OUTPKTS),
75 SNMP_MIB_ITEM("Ip6OutDiscards", IPSTATS_MIB_OUTDISCARDS), 75 SNMP_MIB_ITEM("Ip6OutDiscards", IPSTATS_MIB_OUTDISCARDS),
76 SNMP_MIB_ITEM("Ip6OutNoRoutes", IPSTATS_MIB_OUTNOROUTES), 76 SNMP_MIB_ITEM("Ip6OutNoRoutes", IPSTATS_MIB_OUTNOROUTES),
77 SNMP_MIB_ITEM("Ip6ReasmTimeout", IPSTATS_MIB_REASMTIMEOUT), 77 SNMP_MIB_ITEM("Ip6ReasmTimeout", IPSTATS_MIB_REASMTIMEOUT),
@@ -83,6 +83,12 @@ static struct snmp_mib snmp6_ipstats_list[] = {
83 SNMP_MIB_ITEM("Ip6FragCreates", IPSTATS_MIB_FRAGCREATES), 83 SNMP_MIB_ITEM("Ip6FragCreates", IPSTATS_MIB_FRAGCREATES),
84 SNMP_MIB_ITEM("Ip6InMcastPkts", IPSTATS_MIB_INMCASTPKTS), 84 SNMP_MIB_ITEM("Ip6InMcastPkts", IPSTATS_MIB_INMCASTPKTS),
85 SNMP_MIB_ITEM("Ip6OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS), 85 SNMP_MIB_ITEM("Ip6OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS),
86 SNMP_MIB_ITEM("Ip6InOctets", IPSTATS_MIB_INOCTETS),
87 SNMP_MIB_ITEM("Ip6OutOctets", IPSTATS_MIB_OUTOCTETS),
88 SNMP_MIB_ITEM("Ip6InMcastOctets", IPSTATS_MIB_INMCASTOCTETS),
89 SNMP_MIB_ITEM("Ip6OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS),
90 SNMP_MIB_ITEM("Ip6InBcastOctets", IPSTATS_MIB_INBCASTOCTETS),
91 SNMP_MIB_ITEM("Ip6OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS),
86 SNMP_MIB_SENTINEL 92 SNMP_MIB_SENTINEL
87}; 93};
88 94
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 61f6827e5906..e99307fba0b1 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -638,7 +638,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
638 if (err) 638 if (err)
639 goto error_fault; 639 goto error_fault;
640 640
641 IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS); 641 IP6_UPD_PO_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
642 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev, 642 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
643 dst_output); 643 dst_output);
644 if (err > 0) 644 if (err > 0)
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 711175e0571f..8c2513982b61 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -131,7 +131,7 @@ __u32 cookie_v6_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp)
131 int mssind; 131 int mssind;
132 const __u16 mss = *mssp; 132 const __u16 mss = *mssp;
133 133
134 tcp_sk(sk)->last_synq_overflow = jiffies; 134 tcp_synq_overflow(sk);
135 135
136 for (mssind = 0; mss > msstab[mssind + 1]; mssind++) 136 for (mssind = 0; mss > msstab[mssind + 1]; mssind++)
137 ; 137 ;
@@ -175,7 +175,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
175 if (!sysctl_tcp_syncookies || !th->ack) 175 if (!sysctl_tcp_syncookies || !th->ack)
176 goto out; 176 goto out;
177 177
178 if (time_after(jiffies, tp->last_synq_overflow + TCP_TIMEOUT_INIT) || 178 if (tcp_synq_no_recent_overflow(sk) ||
179 (mss = cookie_check(skb, cookie)) == 0) { 179 (mss = cookie_check(skb, cookie)) == 0) {
180 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESFAILED); 180 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESFAILED);
181 goto out; 181 goto out;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 4b5aa1854260..d9dd94b6bf66 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -943,7 +943,7 @@ static int tcp_v6_gso_send_check(struct sk_buff *skb)
943 943
944struct sk_buff **tcp6_gro_receive(struct sk_buff **head, struct sk_buff *skb) 944struct sk_buff **tcp6_gro_receive(struct sk_buff **head, struct sk_buff *skb)
945{ 945{
946 struct ipv6hdr *iph = ipv6_hdr(skb); 946 struct ipv6hdr *iph = skb_gro_network_header(skb);
947 947
948 switch (skb->ip_summed) { 948 switch (skb->ip_summed) {
949 case CHECKSUM_COMPLETE: 949 case CHECKSUM_COMPLETE:
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index b51c9187c347..a9b3a6f9ea95 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -29,10 +29,7 @@
29#include <net/iucv/iucv.h> 29#include <net/iucv/iucv.h>
30#include <net/iucv/af_iucv.h> 30#include <net/iucv/af_iucv.h>
31 31
32#define CONFIG_IUCV_SOCK_DEBUG 1 32#define VERSION "1.1"
33
34#define IPRMDATA 0x80
35#define VERSION "1.0"
36 33
37static char iucv_userid[80]; 34static char iucv_userid[80];
38 35
@@ -44,6 +41,19 @@ static struct proto iucv_proto = {
44 .obj_size = sizeof(struct iucv_sock), 41 .obj_size = sizeof(struct iucv_sock),
45}; 42};
46 43
44/* special AF_IUCV IPRM messages */
45static const u8 iprm_shutdown[8] =
46 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
47
48#define TRGCLS_SIZE (sizeof(((struct iucv_message *)0)->class))
49
50/* macros to set/get socket control buffer at correct offset */
51#define CB_TAG(skb) ((skb)->cb) /* iucv message tag */
52#define CB_TAG_LEN (sizeof(((struct iucv_message *) 0)->tag))
53#define CB_TRGCLS(skb) ((skb)->cb + CB_TAG_LEN) /* iucv msg target class */
54#define CB_TRGCLS_LEN (TRGCLS_SIZE)
55
56
47static void iucv_sock_kill(struct sock *sk); 57static void iucv_sock_kill(struct sock *sk);
48static void iucv_sock_close(struct sock *sk); 58static void iucv_sock_close(struct sock *sk);
49 59
@@ -54,6 +64,7 @@ static void iucv_callback_connack(struct iucv_path *, u8 ipuser[16]);
54static int iucv_callback_connreq(struct iucv_path *, u8 ipvmid[8], 64static int iucv_callback_connreq(struct iucv_path *, u8 ipvmid[8],
55 u8 ipuser[16]); 65 u8 ipuser[16]);
56static void iucv_callback_connrej(struct iucv_path *, u8 ipuser[16]); 66static void iucv_callback_connrej(struct iucv_path *, u8 ipuser[16]);
67static void iucv_callback_shutdown(struct iucv_path *, u8 ipuser[16]);
57 68
58static struct iucv_sock_list iucv_sk_list = { 69static struct iucv_sock_list iucv_sk_list = {
59 .lock = __RW_LOCK_UNLOCKED(iucv_sk_list.lock), 70 .lock = __RW_LOCK_UNLOCKED(iucv_sk_list.lock),
@@ -65,7 +76,8 @@ static struct iucv_handler af_iucv_handler = {
65 .path_complete = iucv_callback_connack, 76 .path_complete = iucv_callback_connack,
66 .path_severed = iucv_callback_connrej, 77 .path_severed = iucv_callback_connrej,
67 .message_pending = iucv_callback_rx, 78 .message_pending = iucv_callback_rx,
68 .message_complete = iucv_callback_txdone 79 .message_complete = iucv_callback_txdone,
80 .path_quiesced = iucv_callback_shutdown,
69}; 81};
70 82
71static inline void high_nmcpy(unsigned char *dst, char *src) 83static inline void high_nmcpy(unsigned char *dst, char *src)
@@ -78,6 +90,37 @@ static inline void low_nmcpy(unsigned char *dst, char *src)
78 memcpy(&dst[8], src, 8); 90 memcpy(&dst[8], src, 8);
79} 91}
80 92
93/**
94 * iucv_msg_length() - Returns the length of an iucv message.
95 * @msg: Pointer to struct iucv_message, MUST NOT be NULL
96 *
97 * The function returns the length of the specified iucv message @msg of data
98 * stored in a buffer and of data stored in the parameter list (PRMDATA).
99 *
100 * For IUCV_IPRMDATA, AF_IUCV uses the following convention to transport socket
101 * data:
102 * PRMDATA[0..6] socket data (max 7 bytes);
103 * PRMDATA[7] socket data length value (len is 0xff - PRMDATA[7])
104 *
105 * The socket data length is computed by substracting the socket data length
106 * value from 0xFF.
107 * If the socket data len is greater 7, then PRMDATA can be used for special
108 * notifications (see iucv_sock_shutdown); and further,
109 * if the socket data len is > 7, the function returns 8.
110 *
111 * Use this function to allocate socket buffers to store iucv message data.
112 */
113static inline size_t iucv_msg_length(struct iucv_message *msg)
114{
115 size_t datalen;
116
117 if (msg->flags & IUCV_IPRMDATA) {
118 datalen = 0xff - msg->rmmsg[7];
119 return (datalen < 8) ? datalen : 8;
120 }
121 return msg->length;
122}
123
81/* Timers */ 124/* Timers */
82static void iucv_sock_timeout(unsigned long arg) 125static void iucv_sock_timeout(unsigned long arg)
83{ 126{
@@ -225,6 +268,8 @@ static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio)
225 spin_lock_init(&iucv_sk(sk)->message_q.lock); 268 spin_lock_init(&iucv_sk(sk)->message_q.lock);
226 skb_queue_head_init(&iucv_sk(sk)->backlog_skb_q); 269 skb_queue_head_init(&iucv_sk(sk)->backlog_skb_q);
227 iucv_sk(sk)->send_tag = 0; 270 iucv_sk(sk)->send_tag = 0;
271 iucv_sk(sk)->flags = 0;
272 iucv_sk(sk)->msglimit = IUCV_QUEUELEN_DEFAULT;
228 iucv_sk(sk)->path = NULL; 273 iucv_sk(sk)->path = NULL;
229 memset(&iucv_sk(sk)->src_user_id , 0, 32); 274 memset(&iucv_sk(sk)->src_user_id , 0, 32);
230 275
@@ -248,11 +293,22 @@ static int iucv_sock_create(struct net *net, struct socket *sock, int protocol)
248{ 293{
249 struct sock *sk; 294 struct sock *sk;
250 295
251 if (sock->type != SOCK_STREAM) 296 if (protocol && protocol != PF_IUCV)
252 return -ESOCKTNOSUPPORT; 297 return -EPROTONOSUPPORT;
253 298
254 sock->state = SS_UNCONNECTED; 299 sock->state = SS_UNCONNECTED;
255 sock->ops = &iucv_sock_ops; 300
301 switch (sock->type) {
302 case SOCK_STREAM:
303 sock->ops = &iucv_sock_ops;
304 break;
305 case SOCK_SEQPACKET:
306 /* currently, proto ops can handle both sk types */
307 sock->ops = &iucv_sock_ops;
308 break;
309 default:
310 return -ESOCKTNOSUPPORT;
311 }
256 312
257 sk = iucv_sock_alloc(sock, protocol, GFP_KERNEL); 313 sk = iucv_sock_alloc(sock, protocol, GFP_KERNEL);
258 if (!sk) 314 if (!sk)
@@ -463,11 +519,9 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
463 if (sk->sk_state != IUCV_OPEN && sk->sk_state != IUCV_BOUND) 519 if (sk->sk_state != IUCV_OPEN && sk->sk_state != IUCV_BOUND)
464 return -EBADFD; 520 return -EBADFD;
465 521
466 if (sk->sk_type != SOCK_STREAM) 522 if (sk->sk_type != SOCK_STREAM && sk->sk_type != SOCK_SEQPACKET)
467 return -EINVAL; 523 return -EINVAL;
468 524
469 iucv = iucv_sk(sk);
470
471 if (sk->sk_state == IUCV_OPEN) { 525 if (sk->sk_state == IUCV_OPEN) {
472 err = iucv_sock_autobind(sk); 526 err = iucv_sock_autobind(sk);
473 if (unlikely(err)) 527 if (unlikely(err))
@@ -486,8 +540,8 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
486 540
487 iucv = iucv_sk(sk); 541 iucv = iucv_sk(sk);
488 /* Create path. */ 542 /* Create path. */
489 iucv->path = iucv_path_alloc(IUCV_QUEUELEN_DEFAULT, 543 iucv->path = iucv_path_alloc(iucv->msglimit,
490 IPRMDATA, GFP_KERNEL); 544 IUCV_IPRMDATA, GFP_KERNEL);
491 if (!iucv->path) { 545 if (!iucv->path) {
492 err = -ENOMEM; 546 err = -ENOMEM;
493 goto done; 547 goto done;
@@ -521,8 +575,7 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
521 } 575 }
522 576
523 if (sk->sk_state == IUCV_DISCONN) { 577 if (sk->sk_state == IUCV_DISCONN) {
524 release_sock(sk); 578 err = -ECONNREFUSED;
525 return -ECONNREFUSED;
526 } 579 }
527 580
528 if (err) { 581 if (err) {
@@ -545,7 +598,10 @@ static int iucv_sock_listen(struct socket *sock, int backlog)
545 lock_sock(sk); 598 lock_sock(sk);
546 599
547 err = -EINVAL; 600 err = -EINVAL;
548 if (sk->sk_state != IUCV_BOUND || sock->type != SOCK_STREAM) 601 if (sk->sk_state != IUCV_BOUND)
602 goto done;
603
604 if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
549 goto done; 605 goto done;
550 606
551 sk->sk_max_ack_backlog = backlog; 607 sk->sk_max_ack_backlog = backlog;
@@ -636,6 +692,30 @@ static int iucv_sock_getname(struct socket *sock, struct sockaddr *addr,
636 return 0; 692 return 0;
637} 693}
638 694
695/**
696 * iucv_send_iprm() - Send socket data in parameter list of an iucv message.
697 * @path: IUCV path
698 * @msg: Pointer to a struct iucv_message
699 * @skb: The socket data to send, skb->len MUST BE <= 7
700 *
701 * Send the socket data in the parameter list in the iucv message
702 * (IUCV_IPRMDATA). The socket data is stored at index 0 to 6 in the parameter
703 * list and the socket data len at index 7 (last byte).
704 * See also iucv_msg_length().
705 *
706 * Returns the error code from the iucv_message_send() call.
707 */
708static int iucv_send_iprm(struct iucv_path *path, struct iucv_message *msg,
709 struct sk_buff *skb)
710{
711 u8 prmdata[8];
712
713 memcpy(prmdata, (void *) skb->data, skb->len);
714 prmdata[7] = 0xff - (u8) skb->len;
715 return iucv_message_send(path, msg, IUCV_IPRMDATA, 0,
716 (void *) prmdata, 8);
717}
718
639static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock, 719static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
640 struct msghdr *msg, size_t len) 720 struct msghdr *msg, size_t len)
641{ 721{
@@ -643,6 +723,8 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
643 struct iucv_sock *iucv = iucv_sk(sk); 723 struct iucv_sock *iucv = iucv_sk(sk);
644 struct sk_buff *skb; 724 struct sk_buff *skb;
645 struct iucv_message txmsg; 725 struct iucv_message txmsg;
726 struct cmsghdr *cmsg;
727 int cmsg_done;
646 char user_id[9]; 728 char user_id[9];
647 char appl_id[9]; 729 char appl_id[9];
648 int err; 730 int err;
@@ -654,6 +736,10 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
654 if (msg->msg_flags & MSG_OOB) 736 if (msg->msg_flags & MSG_OOB)
655 return -EOPNOTSUPP; 737 return -EOPNOTSUPP;
656 738
739 /* SOCK_SEQPACKET: we do not support segmented records */
740 if (sk->sk_type == SOCK_SEQPACKET && !(msg->msg_flags & MSG_EOR))
741 return -EOPNOTSUPP;
742
657 lock_sock(sk); 743 lock_sock(sk);
658 744
659 if (sk->sk_shutdown & SEND_SHUTDOWN) { 745 if (sk->sk_shutdown & SEND_SHUTDOWN) {
@@ -662,6 +748,52 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
662 } 748 }
663 749
664 if (sk->sk_state == IUCV_CONNECTED) { 750 if (sk->sk_state == IUCV_CONNECTED) {
751 /* initialize defaults */
752 cmsg_done = 0; /* check for duplicate headers */
753 txmsg.class = 0;
754
755 /* iterate over control messages */
756 for (cmsg = CMSG_FIRSTHDR(msg); cmsg;
757 cmsg = CMSG_NXTHDR(msg, cmsg)) {
758
759 if (!CMSG_OK(msg, cmsg)) {
760 err = -EINVAL;
761 goto out;
762 }
763
764 if (cmsg->cmsg_level != SOL_IUCV)
765 continue;
766
767 if (cmsg->cmsg_type & cmsg_done) {
768 err = -EINVAL;
769 goto out;
770 }
771 cmsg_done |= cmsg->cmsg_type;
772
773 switch (cmsg->cmsg_type) {
774 case SCM_IUCV_TRGCLS:
775 if (cmsg->cmsg_len != CMSG_LEN(TRGCLS_SIZE)) {
776 err = -EINVAL;
777 goto out;
778 }
779
780 /* set iucv message target class */
781 memcpy(&txmsg.class,
782 (void *) CMSG_DATA(cmsg), TRGCLS_SIZE);
783
784 break;
785
786 default:
787 err = -EINVAL;
788 goto out;
789 break;
790 }
791 }
792
793 /* allocate one skb for each iucv message:
794 * this is fine for SOCK_SEQPACKET (unless we want to support
795 * segmented records using the MSG_EOR flag), but
796 * for SOCK_STREAM we might want to improve it in future */
665 if (!(skb = sock_alloc_send_skb(sk, len, 797 if (!(skb = sock_alloc_send_skb(sk, len,
666 msg->msg_flags & MSG_DONTWAIT, 798 msg->msg_flags & MSG_DONTWAIT,
667 &err))) 799 &err)))
@@ -672,13 +804,33 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
672 goto fail; 804 goto fail;
673 } 805 }
674 806
675 txmsg.class = 0; 807 /* increment and save iucv message tag for msg_completion cbk */
676 memcpy(&txmsg.class, skb->data, skb->len >= 4 ? 4 : skb->len);
677 txmsg.tag = iucv->send_tag++; 808 txmsg.tag = iucv->send_tag++;
678 memcpy(skb->cb, &txmsg.tag, 4); 809 memcpy(CB_TAG(skb), &txmsg.tag, CB_TAG_LEN);
679 skb_queue_tail(&iucv->send_skb_q, skb); 810 skb_queue_tail(&iucv->send_skb_q, skb);
680 err = iucv_message_send(iucv->path, &txmsg, 0, 0, 811
681 (void *) skb->data, skb->len); 812 if (((iucv->path->flags & IUCV_IPRMDATA) & iucv->flags)
813 && skb->len <= 7) {
814 err = iucv_send_iprm(iucv->path, &txmsg, skb);
815
816 /* on success: there is no message_complete callback
817 * for an IPRMDATA msg; remove skb from send queue */
818 if (err == 0) {
819 skb_unlink(skb, &iucv->send_skb_q);
820 kfree_skb(skb);
821 }
822
823 /* this error should never happen since the
824 * IUCV_IPRMDATA path flag is set... sever path */
825 if (err == 0x15) {
826 iucv_path_sever(iucv->path, NULL);
827 skb_unlink(skb, &iucv->send_skb_q);
828 err = -EPIPE;
829 goto fail;
830 }
831 } else
832 err = iucv_message_send(iucv->path, &txmsg, 0, 0,
833 (void *) skb->data, skb->len);
682 if (err) { 834 if (err) {
683 if (err == 3) { 835 if (err == 3) {
684 user_id[8] = 0; 836 user_id[8] = 0;
@@ -725,6 +877,10 @@ static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len)
725 if (!nskb) 877 if (!nskb)
726 return -ENOMEM; 878 return -ENOMEM;
727 879
880 /* copy target class to control buffer of new skb */
881 memcpy(CB_TRGCLS(nskb), CB_TRGCLS(skb), CB_TRGCLS_LEN);
882
883 /* copy data fragment */
728 memcpy(nskb->data, skb->data + copied, size); 884 memcpy(nskb->data, skb->data + copied, size);
729 copied += size; 885 copied += size;
730 dataleft -= size; 886 dataleft -= size;
@@ -744,19 +900,33 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb,
744 struct iucv_message *msg) 900 struct iucv_message *msg)
745{ 901{
746 int rc; 902 int rc;
903 unsigned int len;
904
905 len = iucv_msg_length(msg);
747 906
748 if (msg->flags & IPRMDATA) { 907 /* store msg target class in the second 4 bytes of skb ctrl buffer */
749 skb->data = NULL; 908 /* Note: the first 4 bytes are reserved for msg tag */
750 skb->len = 0; 909 memcpy(CB_TRGCLS(skb), &msg->class, CB_TRGCLS_LEN);
910
911 /* check for special IPRM messages (e.g. iucv_sock_shutdown) */
912 if ((msg->flags & IUCV_IPRMDATA) && len > 7) {
913 if (memcmp(msg->rmmsg, iprm_shutdown, 8) == 0) {
914 skb->data = NULL;
915 skb->len = 0;
916 }
751 } else { 917 } else {
752 rc = iucv_message_receive(path, msg, 0, skb->data, 918 rc = iucv_message_receive(path, msg, msg->flags & IUCV_IPRMDATA,
753 msg->length, NULL); 919 skb->data, len, NULL);
754 if (rc) { 920 if (rc) {
755 kfree_skb(skb); 921 kfree_skb(skb);
756 return; 922 return;
757 } 923 }
758 if (skb->truesize >= sk->sk_rcvbuf / 4) { 924 /* we need to fragment iucv messages for SOCK_STREAM only;
759 rc = iucv_fragment_skb(sk, skb, msg->length); 925 * for SOCK_SEQPACKET, it is only relevant if we support
926 * record segmentation using MSG_EOR (see also recvmsg()) */
927 if (sk->sk_type == SOCK_STREAM &&
928 skb->truesize >= sk->sk_rcvbuf / 4) {
929 rc = iucv_fragment_skb(sk, skb, len);
760 kfree_skb(skb); 930 kfree_skb(skb);
761 skb = NULL; 931 skb = NULL;
762 if (rc) { 932 if (rc) {
@@ -767,7 +937,7 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb,
767 } else { 937 } else {
768 skb_reset_transport_header(skb); 938 skb_reset_transport_header(skb);
769 skb_reset_network_header(skb); 939 skb_reset_network_header(skb);
770 skb->len = msg->length; 940 skb->len = len;
771 } 941 }
772 } 942 }
773 943
@@ -782,7 +952,7 @@ static void iucv_process_message_q(struct sock *sk)
782 struct sock_msg_q *p, *n; 952 struct sock_msg_q *p, *n;
783 953
784 list_for_each_entry_safe(p, n, &iucv->message_q.list, list) { 954 list_for_each_entry_safe(p, n, &iucv->message_q.list, list) {
785 skb = alloc_skb(p->msg.length, GFP_ATOMIC | GFP_DMA); 955 skb = alloc_skb(iucv_msg_length(&p->msg), GFP_ATOMIC | GFP_DMA);
786 if (!skb) 956 if (!skb)
787 break; 957 break;
788 iucv_process_message(sk, skb, p->path, &p->msg); 958 iucv_process_message(sk, skb, p->path, &p->msg);
@@ -799,7 +969,7 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
799 int noblock = flags & MSG_DONTWAIT; 969 int noblock = flags & MSG_DONTWAIT;
800 struct sock *sk = sock->sk; 970 struct sock *sk = sock->sk;
801 struct iucv_sock *iucv = iucv_sk(sk); 971 struct iucv_sock *iucv = iucv_sk(sk);
802 int target, copied = 0; 972 unsigned int copied, rlen;
803 struct sk_buff *skb, *rskb, *cskb; 973 struct sk_buff *skb, *rskb, *cskb;
804 int err = 0; 974 int err = 0;
805 975
@@ -812,8 +982,6 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
812 if (flags & (MSG_OOB)) 982 if (flags & (MSG_OOB))
813 return -EOPNOTSUPP; 983 return -EOPNOTSUPP;
814 984
815 target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);
816
817 /* receive/dequeue next skb: 985 /* receive/dequeue next skb:
818 * the function understands MSG_PEEK and, thus, does not dequeue skb */ 986 * the function understands MSG_PEEK and, thus, does not dequeue skb */
819 skb = skb_recv_datagram(sk, flags, noblock, &err); 987 skb = skb_recv_datagram(sk, flags, noblock, &err);
@@ -823,25 +991,45 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
823 return err; 991 return err;
824 } 992 }
825 993
826 copied = min_t(unsigned int, skb->len, len); 994 rlen = skb->len; /* real length of skb */
995 copied = min_t(unsigned int, rlen, len);
827 996
828 cskb = skb; 997 cskb = skb;
829 if (memcpy_toiovec(msg->msg_iov, cskb->data, copied)) { 998 if (memcpy_toiovec(msg->msg_iov, cskb->data, copied)) {
830 skb_queue_head(&sk->sk_receive_queue, skb); 999 if (!(flags & MSG_PEEK))
831 if (copied == 0) 1000 skb_queue_head(&sk->sk_receive_queue, skb);
832 return -EFAULT; 1001 return -EFAULT;
833 goto done;
834 } 1002 }
835 1003
836 len -= copied; 1004 /* SOCK_SEQPACKET: set MSG_TRUNC if recv buf size is too small */
1005 if (sk->sk_type == SOCK_SEQPACKET) {
1006 if (copied < rlen)
1007 msg->msg_flags |= MSG_TRUNC;
1008 /* each iucv message contains a complete record */
1009 msg->msg_flags |= MSG_EOR;
1010 }
1011
1012 /* create control message to store iucv msg target class:
1013 * get the trgcls from the control buffer of the skb due to
1014 * fragmentation of original iucv message. */
1015 err = put_cmsg(msg, SOL_IUCV, SCM_IUCV_TRGCLS,
1016 CB_TRGCLS_LEN, CB_TRGCLS(skb));
1017 if (err) {
1018 if (!(flags & MSG_PEEK))
1019 skb_queue_head(&sk->sk_receive_queue, skb);
1020 return err;
1021 }
837 1022
838 /* Mark read part of skb as used */ 1023 /* Mark read part of skb as used */
839 if (!(flags & MSG_PEEK)) { 1024 if (!(flags & MSG_PEEK)) {
840 skb_pull(skb, copied);
841 1025
842 if (skb->len) { 1026 /* SOCK_STREAM: re-queue skb if it contains unreceived data */
843 skb_queue_head(&sk->sk_receive_queue, skb); 1027 if (sk->sk_type == SOCK_STREAM) {
844 goto done; 1028 skb_pull(skb, copied);
1029 if (skb->len) {
1030 skb_queue_head(&sk->sk_receive_queue, skb);
1031 goto done;
1032 }
845 } 1033 }
846 1034
847 kfree_skb(skb); 1035 kfree_skb(skb);
@@ -866,7 +1054,11 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
866 } 1054 }
867 1055
868done: 1056done:
869 return err ? : copied; 1057 /* SOCK_SEQPACKET: return real length if MSG_TRUNC is set */
1058 if (sk->sk_type == SOCK_SEQPACKET && (flags & MSG_TRUNC))
1059 copied = rlen;
1060
1061 return copied;
870} 1062}
871 1063
872static inline unsigned int iucv_accept_poll(struct sock *parent) 1064static inline unsigned int iucv_accept_poll(struct sock *parent)
@@ -928,7 +1120,6 @@ static int iucv_sock_shutdown(struct socket *sock, int how)
928 struct iucv_sock *iucv = iucv_sk(sk); 1120 struct iucv_sock *iucv = iucv_sk(sk);
929 struct iucv_message txmsg; 1121 struct iucv_message txmsg;
930 int err = 0; 1122 int err = 0;
931 u8 prmmsg[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
932 1123
933 how++; 1124 how++;
934 1125
@@ -953,7 +1144,7 @@ static int iucv_sock_shutdown(struct socket *sock, int how)
953 txmsg.class = 0; 1144 txmsg.class = 0;
954 txmsg.tag = 0; 1145 txmsg.tag = 0;
955 err = iucv_message_send(iucv->path, &txmsg, IUCV_IPRMDATA, 0, 1146 err = iucv_message_send(iucv->path, &txmsg, IUCV_IPRMDATA, 0,
956 (void *) prmmsg, 8); 1147 (void *) iprm_shutdown, 8);
957 if (err) { 1148 if (err) {
958 switch (err) { 1149 switch (err) {
959 case 1: 1150 case 1:
@@ -1007,6 +1198,98 @@ static int iucv_sock_release(struct socket *sock)
1007 return err; 1198 return err;
1008} 1199}
1009 1200
1201/* getsockopt and setsockopt */
1202static int iucv_sock_setsockopt(struct socket *sock, int level, int optname,
1203 char __user *optval, int optlen)
1204{
1205 struct sock *sk = sock->sk;
1206 struct iucv_sock *iucv = iucv_sk(sk);
1207 int val;
1208 int rc;
1209
1210 if (level != SOL_IUCV)
1211 return -ENOPROTOOPT;
1212
1213 if (optlen < sizeof(int))
1214 return -EINVAL;
1215
1216 if (get_user(val, (int __user *) optval))
1217 return -EFAULT;
1218
1219 rc = 0;
1220
1221 lock_sock(sk);
1222 switch (optname) {
1223 case SO_IPRMDATA_MSG:
1224 if (val)
1225 iucv->flags |= IUCV_IPRMDATA;
1226 else
1227 iucv->flags &= ~IUCV_IPRMDATA;
1228 break;
1229 case SO_MSGLIMIT:
1230 switch (sk->sk_state) {
1231 case IUCV_OPEN:
1232 case IUCV_BOUND:
1233 if (val < 1 || val > (u16)(~0))
1234 rc = -EINVAL;
1235 else
1236 iucv->msglimit = val;
1237 break;
1238 default:
1239 rc = -EINVAL;
1240 break;
1241 }
1242 break;
1243 default:
1244 rc = -ENOPROTOOPT;
1245 break;
1246 }
1247 release_sock(sk);
1248
1249 return rc;
1250}
1251
1252static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
1253 char __user *optval, int __user *optlen)
1254{
1255 struct sock *sk = sock->sk;
1256 struct iucv_sock *iucv = iucv_sk(sk);
1257 int val, len;
1258
1259 if (level != SOL_IUCV)
1260 return -ENOPROTOOPT;
1261
1262 if (get_user(len, optlen))
1263 return -EFAULT;
1264
1265 if (len < 0)
1266 return -EINVAL;
1267
1268 len = min_t(unsigned int, len, sizeof(int));
1269
1270 switch (optname) {
1271 case SO_IPRMDATA_MSG:
1272 val = (iucv->flags & IUCV_IPRMDATA) ? 1 : 0;
1273 break;
1274 case SO_MSGLIMIT:
1275 lock_sock(sk);
1276 val = (iucv->path != NULL) ? iucv->path->msglim /* connected */
1277 : iucv->msglimit; /* default */
1278 release_sock(sk);
1279 break;
1280 default:
1281 return -ENOPROTOOPT;
1282 }
1283
1284 if (put_user(len, optlen))
1285 return -EFAULT;
1286 if (copy_to_user(optval, &val, len))
1287 return -EFAULT;
1288
1289 return 0;
1290}
1291
1292
1010/* Callback wrappers - called from iucv base support */ 1293/* Callback wrappers - called from iucv base support */
1011static int iucv_callback_connreq(struct iucv_path *path, 1294static int iucv_callback_connreq(struct iucv_path *path,
1012 u8 ipvmid[8], u8 ipuser[16]) 1295 u8 ipvmid[8], u8 ipuser[16])
@@ -1060,7 +1343,7 @@ static int iucv_callback_connreq(struct iucv_path *path,
1060 } 1343 }
1061 1344
1062 /* Create the new socket */ 1345 /* Create the new socket */
1063 nsk = iucv_sock_alloc(NULL, SOCK_STREAM, GFP_ATOMIC); 1346 nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC);
1064 if (!nsk) { 1347 if (!nsk) {
1065 err = iucv_path_sever(path, user_data); 1348 err = iucv_path_sever(path, user_data);
1066 iucv_path_free(path); 1349 iucv_path_free(path);
@@ -1083,7 +1366,9 @@ static int iucv_callback_connreq(struct iucv_path *path,
1083 memcpy(nuser_data + 8, niucv->src_name, 8); 1366 memcpy(nuser_data + 8, niucv->src_name, 8);
1084 ASCEBC(nuser_data + 8, 8); 1367 ASCEBC(nuser_data + 8, 8);
1085 1368
1086 path->msglim = IUCV_QUEUELEN_DEFAULT; 1369 /* set message limit for path based on msglimit of accepting socket */
1370 niucv->msglimit = iucv->msglimit;
1371 path->msglim = iucv->msglimit;
1087 err = iucv_path_accept(path, &af_iucv_handler, nuser_data, nsk); 1372 err = iucv_path_accept(path, &af_iucv_handler, nuser_data, nsk);
1088 if (err) { 1373 if (err) {
1089 err = iucv_path_sever(path, user_data); 1374 err = iucv_path_sever(path, user_data);
@@ -1131,19 +1416,17 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg)
1131 goto save_message; 1416 goto save_message;
1132 1417
1133 len = atomic_read(&sk->sk_rmem_alloc); 1418 len = atomic_read(&sk->sk_rmem_alloc);
1134 len += msg->length + sizeof(struct sk_buff); 1419 len += iucv_msg_length(msg) + sizeof(struct sk_buff);
1135 if (len > sk->sk_rcvbuf) 1420 if (len > sk->sk_rcvbuf)
1136 goto save_message; 1421 goto save_message;
1137 1422
1138 skb = alloc_skb(msg->length, GFP_ATOMIC | GFP_DMA); 1423 skb = alloc_skb(iucv_msg_length(msg), GFP_ATOMIC | GFP_DMA);
1139 if (!skb) 1424 if (!skb)
1140 goto save_message; 1425 goto save_message;
1141 1426
1142 iucv_process_message(sk, skb, path, msg); 1427 iucv_process_message(sk, skb, path, msg);
1143 goto out_unlock; 1428 goto out_unlock;
1144 1429
1145 return;
1146
1147save_message: 1430save_message:
1148 save_msg = kzalloc(sizeof(struct sock_msg_q), GFP_ATOMIC | GFP_DMA); 1431 save_msg = kzalloc(sizeof(struct sock_msg_q), GFP_ATOMIC | GFP_DMA);
1149 if (!save_msg) 1432 if (!save_msg)
@@ -1170,7 +1453,7 @@ static void iucv_callback_txdone(struct iucv_path *path,
1170 spin_lock_irqsave(&list->lock, flags); 1453 spin_lock_irqsave(&list->lock, flags);
1171 1454
1172 while (list_skb != (struct sk_buff *)list) { 1455 while (list_skb != (struct sk_buff *)list) {
1173 if (!memcmp(&msg->tag, list_skb->cb, 4)) { 1456 if (!memcmp(&msg->tag, CB_TAG(list_skb), CB_TAG_LEN)) {
1174 this = list_skb; 1457 this = list_skb;
1175 break; 1458 break;
1176 } 1459 }
@@ -1206,6 +1489,21 @@ static void iucv_callback_connrej(struct iucv_path *path, u8 ipuser[16])
1206 sk->sk_state_change(sk); 1489 sk->sk_state_change(sk);
1207} 1490}
1208 1491
1492/* called if the other communication side shuts down its RECV direction;
1493 * in turn, the callback sets SEND_SHUTDOWN to disable sending of data.
1494 */
1495static void iucv_callback_shutdown(struct iucv_path *path, u8 ipuser[16])
1496{
1497 struct sock *sk = path->private;
1498
1499 bh_lock_sock(sk);
1500 if (sk->sk_state != IUCV_CLOSED) {
1501 sk->sk_shutdown |= SEND_SHUTDOWN;
1502 sk->sk_state_change(sk);
1503 }
1504 bh_unlock_sock(sk);
1505}
1506
1209static struct proto_ops iucv_sock_ops = { 1507static struct proto_ops iucv_sock_ops = {
1210 .family = PF_IUCV, 1508 .family = PF_IUCV,
1211 .owner = THIS_MODULE, 1509 .owner = THIS_MODULE,
@@ -1222,8 +1520,8 @@ static struct proto_ops iucv_sock_ops = {
1222 .mmap = sock_no_mmap, 1520 .mmap = sock_no_mmap,
1223 .socketpair = sock_no_socketpair, 1521 .socketpair = sock_no_socketpair,
1224 .shutdown = iucv_sock_shutdown, 1522 .shutdown = iucv_sock_shutdown,
1225 .setsockopt = sock_no_setsockopt, 1523 .setsockopt = iucv_sock_setsockopt,
1226 .getsockopt = sock_no_getsockopt 1524 .getsockopt = iucv_sock_getsockopt,
1227}; 1525};
1228 1526
1229static struct net_proto_family iucv_sock_family_ops = { 1527static struct net_proto_family iucv_sock_family_ops = {
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c
index a35240f61ec3..61e8038a55ee 100644
--- a/net/iucv/iucv.c
+++ b/net/iucv/iucv.c
@@ -280,6 +280,7 @@ union iucv_param {
280 * Anchor for per-cpu IUCV command parameter block. 280 * Anchor for per-cpu IUCV command parameter block.
281 */ 281 */
282static union iucv_param *iucv_param[NR_CPUS]; 282static union iucv_param *iucv_param[NR_CPUS];
283static union iucv_param *iucv_param_irq[NR_CPUS];
283 284
284/** 285/**
285 * iucv_call_b2f0 286 * iucv_call_b2f0
@@ -358,7 +359,7 @@ static void iucv_allow_cpu(void *data)
358 * 0x10 - Flag to allow priority message completion interrupts 359 * 0x10 - Flag to allow priority message completion interrupts
359 * 0x08 - Flag to allow IUCV control interrupts 360 * 0x08 - Flag to allow IUCV control interrupts
360 */ 361 */
361 parm = iucv_param[cpu]; 362 parm = iucv_param_irq[cpu];
362 memset(parm, 0, sizeof(union iucv_param)); 363 memset(parm, 0, sizeof(union iucv_param));
363 parm->set_mask.ipmask = 0xf8; 364 parm->set_mask.ipmask = 0xf8;
364 iucv_call_b2f0(IUCV_SETMASK, parm); 365 iucv_call_b2f0(IUCV_SETMASK, parm);
@@ -379,7 +380,7 @@ static void iucv_block_cpu(void *data)
379 union iucv_param *parm; 380 union iucv_param *parm;
380 381
381 /* Disable all iucv interrupts. */ 382 /* Disable all iucv interrupts. */
382 parm = iucv_param[cpu]; 383 parm = iucv_param_irq[cpu];
383 memset(parm, 0, sizeof(union iucv_param)); 384 memset(parm, 0, sizeof(union iucv_param));
384 iucv_call_b2f0(IUCV_SETMASK, parm); 385 iucv_call_b2f0(IUCV_SETMASK, parm);
385 386
@@ -403,7 +404,7 @@ static void iucv_declare_cpu(void *data)
403 return; 404 return;
404 405
405 /* Declare interrupt buffer. */ 406 /* Declare interrupt buffer. */
406 parm = iucv_param[cpu]; 407 parm = iucv_param_irq[cpu];
407 memset(parm, 0, sizeof(union iucv_param)); 408 memset(parm, 0, sizeof(union iucv_param));
408 parm->db.ipbfadr1 = virt_to_phys(iucv_irq_data[cpu]); 409 parm->db.ipbfadr1 = virt_to_phys(iucv_irq_data[cpu]);
409 rc = iucv_call_b2f0(IUCV_DECLARE_BUFFER, parm); 410 rc = iucv_call_b2f0(IUCV_DECLARE_BUFFER, parm);
@@ -460,7 +461,7 @@ static void iucv_retrieve_cpu(void *data)
460 iucv_block_cpu(NULL); 461 iucv_block_cpu(NULL);
461 462
462 /* Retrieve interrupt buffer. */ 463 /* Retrieve interrupt buffer. */
463 parm = iucv_param[cpu]; 464 parm = iucv_param_irq[cpu];
464 iucv_call_b2f0(IUCV_RETRIEVE_BUFFER, parm); 465 iucv_call_b2f0(IUCV_RETRIEVE_BUFFER, parm);
465 466
466 /* Clear indication that an iucv buffer exists for this cpu. */ 467 /* Clear indication that an iucv buffer exists for this cpu. */
@@ -574,11 +575,22 @@ static int __cpuinit iucv_cpu_notify(struct notifier_block *self,
574 iucv_irq_data[cpu] = NULL; 575 iucv_irq_data[cpu] = NULL;
575 return NOTIFY_BAD; 576 return NOTIFY_BAD;
576 } 577 }
578 iucv_param_irq[cpu] = kmalloc_node(sizeof(union iucv_param),
579 GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
580 if (!iucv_param_irq[cpu]) {
581 kfree(iucv_param[cpu]);
582 iucv_param[cpu] = NULL;
583 kfree(iucv_irq_data[cpu]);
584 iucv_irq_data[cpu] = NULL;
585 return NOTIFY_BAD;
586 }
577 break; 587 break;
578 case CPU_UP_CANCELED: 588 case CPU_UP_CANCELED:
579 case CPU_UP_CANCELED_FROZEN: 589 case CPU_UP_CANCELED_FROZEN:
580 case CPU_DEAD: 590 case CPU_DEAD:
581 case CPU_DEAD_FROZEN: 591 case CPU_DEAD_FROZEN:
592 kfree(iucv_param_irq[cpu]);
593 iucv_param_irq[cpu] = NULL;
582 kfree(iucv_param[cpu]); 594 kfree(iucv_param[cpu]);
583 iucv_param[cpu] = NULL; 595 iucv_param[cpu] = NULL;
584 kfree(iucv_irq_data[cpu]); 596 kfree(iucv_irq_data[cpu]);
@@ -625,7 +637,7 @@ static int iucv_sever_pathid(u16 pathid, u8 userdata[16])
625{ 637{
626 union iucv_param *parm; 638 union iucv_param *parm;
627 639
628 parm = iucv_param[smp_processor_id()]; 640 parm = iucv_param_irq[smp_processor_id()];
629 memset(parm, 0, sizeof(union iucv_param)); 641 memset(parm, 0, sizeof(union iucv_param));
630 if (userdata) 642 if (userdata)
631 memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser)); 643 memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser));
@@ -918,10 +930,8 @@ int iucv_path_sever(struct iucv_path *path, u8 userdata[16])
918 if (iucv_active_cpu != smp_processor_id()) 930 if (iucv_active_cpu != smp_processor_id())
919 spin_lock_bh(&iucv_table_lock); 931 spin_lock_bh(&iucv_table_lock);
920 rc = iucv_sever_pathid(path->pathid, userdata); 932 rc = iucv_sever_pathid(path->pathid, userdata);
921 if (!rc) { 933 iucv_path_table[path->pathid] = NULL;
922 iucv_path_table[path->pathid] = NULL; 934 list_del_init(&path->list);
923 list_del_init(&path->list);
924 }
925 if (iucv_active_cpu != smp_processor_id()) 935 if (iucv_active_cpu != smp_processor_id())
926 spin_unlock_bh(&iucv_table_lock); 936 spin_unlock_bh(&iucv_table_lock);
927 preempt_enable(); 937 preempt_enable();
@@ -1378,6 +1388,8 @@ static void iucv_path_complete(struct iucv_irq_data *data)
1378 struct iucv_path_complete *ipc = (void *) data; 1388 struct iucv_path_complete *ipc = (void *) data;
1379 struct iucv_path *path = iucv_path_table[ipc->ippathid]; 1389 struct iucv_path *path = iucv_path_table[ipc->ippathid];
1380 1390
1391 if (path)
1392 path->flags = ipc->ipflags1;
1381 if (path && path->handler && path->handler->path_complete) 1393 if (path && path->handler && path->handler->path_complete)
1382 path->handler->path_complete(path, ipc->ipuser); 1394 path->handler->path_complete(path, ipc->ipuser);
1383} 1395}
@@ -1413,7 +1425,7 @@ static void iucv_path_severed(struct iucv_irq_data *data)
1413 else { 1425 else {
1414 iucv_sever_pathid(path->pathid, NULL); 1426 iucv_sever_pathid(path->pathid, NULL);
1415 iucv_path_table[path->pathid] = NULL; 1427 iucv_path_table[path->pathid] = NULL;
1416 list_del_init(&path->list); 1428 list_del(&path->list);
1417 iucv_path_free(path); 1429 iucv_path_free(path);
1418 } 1430 }
1419} 1431}
@@ -1717,6 +1729,13 @@ static int __init iucv_init(void)
1717 rc = -ENOMEM; 1729 rc = -ENOMEM;
1718 goto out_free; 1730 goto out_free;
1719 } 1731 }
1732 iucv_param_irq[cpu] = kmalloc_node(sizeof(union iucv_param),
1733 GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
1734 if (!iucv_param_irq[cpu]) {
1735 rc = -ENOMEM;
1736 goto out_free;
1737 }
1738
1720 } 1739 }
1721 rc = register_hotcpu_notifier(&iucv_cpu_notifier); 1740 rc = register_hotcpu_notifier(&iucv_cpu_notifier);
1722 if (rc) 1741 if (rc)
@@ -1734,6 +1753,8 @@ out_cpu:
1734 unregister_hotcpu_notifier(&iucv_cpu_notifier); 1753 unregister_hotcpu_notifier(&iucv_cpu_notifier);
1735out_free: 1754out_free:
1736 for_each_possible_cpu(cpu) { 1755 for_each_possible_cpu(cpu) {
1756 kfree(iucv_param_irq[cpu]);
1757 iucv_param_irq[cpu] = NULL;
1737 kfree(iucv_param[cpu]); 1758 kfree(iucv_param[cpu]);
1738 iucv_param[cpu] = NULL; 1759 iucv_param[cpu] = NULL;
1739 kfree(iucv_irq_data[cpu]); 1760 kfree(iucv_irq_data[cpu]);
@@ -1764,6 +1785,8 @@ static void __exit iucv_exit(void)
1764 spin_unlock_irq(&iucv_queue_lock); 1785 spin_unlock_irq(&iucv_queue_lock);
1765 unregister_hotcpu_notifier(&iucv_cpu_notifier); 1786 unregister_hotcpu_notifier(&iucv_cpu_notifier);
1766 for_each_possible_cpu(cpu) { 1787 for_each_possible_cpu(cpu) {
1788 kfree(iucv_param_irq[cpu]);
1789 iucv_param_irq[cpu] = NULL;
1767 kfree(iucv_param[cpu]); 1790 kfree(iucv_param[cpu]);
1768 iucv_param[cpu] = NULL; 1791 iucv_param[cpu] = NULL;
1769 kfree(iucv_irq_data[cpu]); 1792 kfree(iucv_irq_data[cpu]);
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index ecc3faf9f11a..9cbf545e95a2 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -11,6 +11,22 @@ config MAC80211
11 This option enables the hardware independent IEEE 802.11 11 This option enables the hardware independent IEEE 802.11
12 networking stack. 12 networking stack.
13 13
14config MAC80211_DEFAULT_PS
15 bool "enable powersave by default"
16 depends on MAC80211
17 default y
18 help
19 This option enables powersave mode by default.
20
21 If this causes your applications to misbehave you should fix your
22 applications instead -- they need to register their network
23 latency requirement, see Documentation/power/pm_qos_interface.txt.
24
25config MAC80211_DEFAULT_PS_VALUE
26 int
27 default 1 if MAC80211_DEFAULT_PS
28 default 0
29
14menu "Rate control algorithm selection" 30menu "Rate control algorithm selection"
15 depends on MAC80211 != n 31 depends on MAC80211 != n
16 32
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index e677b751d468..5e1c230744b5 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1167,7 +1167,8 @@ static int ieee80211_scan(struct wiphy *wiphy,
1167 1167
1168 if (sdata->vif.type != NL80211_IFTYPE_STATION && 1168 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
1169 sdata->vif.type != NL80211_IFTYPE_ADHOC && 1169 sdata->vif.type != NL80211_IFTYPE_ADHOC &&
1170 sdata->vif.type != NL80211_IFTYPE_MESH_POINT) 1170 sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
1171 (sdata->vif.type != NL80211_IFTYPE_AP || sdata->u.ap.beacon))
1171 return -EOPNOTSUPP; 1172 return -EOPNOTSUPP;
1172 1173
1173 return ieee80211_request_scan(sdata, req); 1174 return ieee80211_request_scan(sdata, req);
@@ -1267,25 +1268,62 @@ static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
1267static int ieee80211_deauth(struct wiphy *wiphy, struct net_device *dev, 1268static int ieee80211_deauth(struct wiphy *wiphy, struct net_device *dev,
1268 struct cfg80211_deauth_request *req) 1269 struct cfg80211_deauth_request *req)
1269{ 1270{
1270 struct ieee80211_sub_if_data *sdata; 1271 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1271
1272 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1273 1272
1274 /* TODO: req->ie */ 1273 /* TODO: req->ie, req->peer_addr */
1275 return ieee80211_sta_deauthenticate(sdata, req->reason_code); 1274 return ieee80211_sta_deauthenticate(sdata, req->reason_code);
1276} 1275}
1277 1276
1278static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev, 1277static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev,
1279 struct cfg80211_disassoc_request *req) 1278 struct cfg80211_disassoc_request *req)
1280{ 1279{
1281 struct ieee80211_sub_if_data *sdata; 1280 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1282
1283 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1284 1281
1285 /* TODO: req->ie */ 1282 /* TODO: req->ie, req->peer_addr */
1286 return ieee80211_sta_disassociate(sdata, req->reason_code); 1283 return ieee80211_sta_disassociate(sdata, req->reason_code);
1287} 1284}
1288 1285
1286static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1287 struct cfg80211_ibss_params *params)
1288{
1289 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1290
1291 return ieee80211_ibss_join(sdata, params);
1292}
1293
1294static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1295{
1296 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1297
1298 return ieee80211_ibss_leave(sdata);
1299}
1300
1301static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1302{
1303 struct ieee80211_local *local = wiphy_priv(wiphy);
1304
1305 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1306 int err;
1307
1308 if (local->ops->set_rts_threshold) {
1309 err = local->ops->set_rts_threshold(
1310 local_to_hw(local), wiphy->rts_threshold);
1311 if (err)
1312 return err;
1313 }
1314 }
1315
1316 if (changed & WIPHY_PARAM_RETRY_SHORT)
1317 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
1318 if (changed & WIPHY_PARAM_RETRY_LONG)
1319 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
1320 if (changed &
1321 (WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG))
1322 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);
1323
1324 return 0;
1325}
1326
1289struct cfg80211_ops mac80211_config_ops = { 1327struct cfg80211_ops mac80211_config_ops = {
1290 .add_virtual_intf = ieee80211_add_iface, 1328 .add_virtual_intf = ieee80211_add_iface,
1291 .del_virtual_intf = ieee80211_del_iface, 1329 .del_virtual_intf = ieee80211_del_iface,
@@ -1322,4 +1360,7 @@ struct cfg80211_ops mac80211_config_ops = {
1322 .assoc = ieee80211_assoc, 1360 .assoc = ieee80211_assoc,
1323 .deauth = ieee80211_deauth, 1361 .deauth = ieee80211_deauth,
1324 .disassoc = ieee80211_disassoc, 1362 .disassoc = ieee80211_disassoc,
1363 .join_ibss = ieee80211_join_ibss,
1364 .leave_ibss = ieee80211_leave_ibss,
1365 .set_wiphy_params = ieee80211_set_wiphy_params,
1325}; 1366};
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 210b9b6fecd2..5001328be46b 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -52,13 +52,13 @@ static const struct file_operations name## _ops = { \
52DEBUGFS_READONLY_FILE(frequency, 20, "%d", 52DEBUGFS_READONLY_FILE(frequency, 20, "%d",
53 local->hw.conf.channel->center_freq); 53 local->hw.conf.channel->center_freq);
54DEBUGFS_READONLY_FILE(rts_threshold, 20, "%d", 54DEBUGFS_READONLY_FILE(rts_threshold, 20, "%d",
55 local->rts_threshold); 55 local->hw.wiphy->rts_threshold);
56DEBUGFS_READONLY_FILE(fragmentation_threshold, 20, "%d", 56DEBUGFS_READONLY_FILE(fragmentation_threshold, 20, "%d",
57 local->fragmentation_threshold); 57 local->hw.wiphy->frag_threshold);
58DEBUGFS_READONLY_FILE(short_retry_limit, 20, "%d", 58DEBUGFS_READONLY_FILE(short_retry_limit, 20, "%d",
59 local->hw.conf.short_frame_max_tx_count); 59 local->hw.wiphy->retry_short);
60DEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d", 60DEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d",
61 local->hw.conf.long_frame_max_tx_count); 61 local->hw.wiphy->retry_long);
62DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d", 62DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d",
63 local->total_ps_buffered); 63 local->total_ps_buffered);
64DEBUGFS_READONLY_FILE(wep_iv, 20, "%#08x", 64DEBUGFS_READONLY_FILE(wep_iv, 20, "%#08x",
diff --git a/net/mac80211/event.c b/net/mac80211/event.c
index 0d95561c0ee0..f288d01a6344 100644
--- a/net/mac80211/event.c
+++ b/net/mac80211/event.c
@@ -12,12 +12,12 @@
12#include "ieee80211_i.h" 12#include "ieee80211_i.h"
13 13
14/* 14/*
15 * indicate a failed Michael MIC to userspace; the passed packet 15 * Indicate a failed Michael MIC to userspace. If the caller knows the TSC of
16 * (in the variable hdr) must be long enough to extract the TKIP 16 * the frame that generated the MIC failure (i.e., if it was provided by the
17 * fields like TSC 17 * driver or is still in the frame), it should provide that information.
18 */ 18 */
19void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx, 19void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx,
20 struct ieee80211_hdr *hdr) 20 struct ieee80211_hdr *hdr, const u8 *tsc)
21{ 21{
22 union iwreq_data wrqu; 22 union iwreq_data wrqu;
23 char *buf = kmalloc(128, GFP_ATOMIC); 23 char *buf = kmalloc(128, GFP_ATOMIC);
@@ -34,8 +34,9 @@ void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int ke
34 kfree(buf); 34 kfree(buf);
35 } 35 }
36 36
37 /* 37 cfg80211_michael_mic_failure(sdata->dev, hdr->addr2,
38 * TODO: re-add support for sending MIC failure indication 38 (hdr->addr1[0] & 0x01) ?
39 * with all info via nl80211 39 NL80211_KEYTYPE_GROUP :
40 */ 40 NL80211_KEYTYPE_PAIRWISE,
41 keyidx, tsc);
41} 42}
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 4e3c72f20de7..0891bfb06996 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -14,7 +14,6 @@
14 */ 14 */
15 15
16#include <linux/ieee80211.h> 16#include <linux/ieee80211.h>
17#include <net/wireless.h>
18#include <net/mac80211.h> 17#include <net/mac80211.h>
19#include "ieee80211_i.h" 18#include "ieee80211_i.h"
20#include "rate.h" 19#include "rate.h"
@@ -83,89 +82,6 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
83 ht_cap->mcs.rx_mask[32/8] |= 1; 82 ht_cap->mcs.rx_mask[32/8] |= 1;
84} 83}
85 84
86/*
87 * ieee80211_enable_ht should be called only after the operating band
88 * has been determined as ht configuration depends on the hw's
89 * HT abilities for a specific band.
90 */
91u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
92 struct ieee80211_ht_info *hti,
93 u16 ap_ht_cap_flags)
94{
95 struct ieee80211_local *local = sdata->local;
96 struct ieee80211_supported_band *sband;
97 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
98 struct ieee80211_bss_ht_conf ht;
99 struct sta_info *sta;
100 u32 changed = 0;
101 bool enable_ht = true, ht_changed;
102 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
103
104 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
105
106 memset(&ht, 0, sizeof(ht));
107
108 /* HT is not supported */
109 if (!sband->ht_cap.ht_supported)
110 enable_ht = false;
111
112 /* check that channel matches the right operating channel */
113 if (local->hw.conf.channel->center_freq !=
114 ieee80211_channel_to_frequency(hti->control_chan))
115 enable_ht = false;
116
117 if (enable_ht) {
118 channel_type = NL80211_CHAN_HT20;
119
120 if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
121 (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
122 (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
123 switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
124 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
125 channel_type = NL80211_CHAN_HT40PLUS;
126 break;
127 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
128 channel_type = NL80211_CHAN_HT40MINUS;
129 break;
130 }
131 }
132 }
133
134 ht_changed = conf_is_ht(&local->hw.conf) != enable_ht ||
135 channel_type != local->hw.conf.channel_type;
136
137 local->oper_channel_type = channel_type;
138
139 if (ht_changed) {
140 /* channel_type change automatically detected */
141 ieee80211_hw_config(local, 0);
142
143 rcu_read_lock();
144
145 sta = sta_info_get(local, ifmgd->bssid);
146 if (sta)
147 rate_control_rate_update(local, sband, sta,
148 IEEE80211_RC_HT_CHANGED);
149
150 rcu_read_unlock();
151
152 }
153
154 /* disable HT */
155 if (!enable_ht)
156 return 0;
157
158 ht.operation_mode = le16_to_cpu(hti->operation_mode);
159
160 /* if bss configuration changed store the new one */
161 if (memcmp(&sdata->vif.bss_conf.ht, &ht, sizeof(ht))) {
162 changed |= BSS_CHANGED_HT;
163 sdata->vif.bss_conf.ht = ht;
164 }
165
166 return changed;
167}
168
169void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta) 85void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta)
170{ 86{
171 int i; 87 int i;
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 3201e1f96365..6030e003180c 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -59,74 +59,59 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
59 sdata->u.ibss.bssid, 0); 59 sdata->u.ibss.bssid, 0);
60} 60}
61 61
62static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, 62static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
63 const u8 *bssid, const int beacon_int, 63 const u8 *bssid, const int beacon_int,
64 const int freq, 64 struct ieee80211_channel *chan,
65 const size_t supp_rates_len, 65 const size_t supp_rates_len,
66 const u8 *supp_rates, 66 const u8 *supp_rates,
67 const u16 capability, u64 tsf) 67 const u16 capability, u64 tsf)
68{ 68{
69 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 69 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
70 struct ieee80211_local *local = sdata->local; 70 struct ieee80211_local *local = sdata->local;
71 int res = 0, rates, i, j; 71 int rates, i, j;
72 struct sk_buff *skb; 72 struct sk_buff *skb;
73 struct ieee80211_mgmt *mgmt; 73 struct ieee80211_mgmt *mgmt;
74 u8 *pos; 74 u8 *pos;
75 struct ieee80211_supported_band *sband; 75 struct ieee80211_supported_band *sband;
76 union iwreq_data wrqu;
77 76
78 if (local->ops->reset_tsf) { 77 if (local->ops->reset_tsf) {
79 /* Reset own TSF to allow time synchronization work. */ 78 /* Reset own TSF to allow time synchronization work. */
80 local->ops->reset_tsf(local_to_hw(local)); 79 local->ops->reset_tsf(local_to_hw(local));
81 } 80 }
82 81
83 if ((ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET) && 82 skb = ifibss->skb;
84 memcmp(ifibss->bssid, bssid, ETH_ALEN) == 0) 83 rcu_assign_pointer(ifibss->presp, NULL);
85 return res; 84 synchronize_rcu();
85 skb->data = skb->head;
86 skb->len = 0;
87 skb_reset_tail_pointer(skb);
88 skb_reserve(skb, sdata->local->hw.extra_tx_headroom);
86 89
87 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); 90 if (memcmp(ifibss->bssid, bssid, ETH_ALEN))
88 if (!skb) { 91 sta_info_flush(sdata->local, sdata);
89 printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
90 "response\n", sdata->dev->name);
91 return -ENOMEM;
92 }
93
94 if (!(ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET)) {
95 /* Remove possible STA entries from other IBSS networks. */
96 sta_info_flush_delayed(sdata);
97 }
98 92
99 memcpy(ifibss->bssid, bssid, ETH_ALEN); 93 memcpy(ifibss->bssid, bssid, ETH_ALEN);
100 res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
101 if (res)
102 return res;
103 94
104 local->hw.conf.beacon_int = beacon_int >= 10 ? beacon_int : 10; 95 local->hw.conf.beacon_int = beacon_int >= 10 ? beacon_int : 10;
105 96
106 sdata->drop_unencrypted = capability & 97 sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
107 WLAN_CAPABILITY_PRIVACY ? 1 : 0;
108
109 res = ieee80211_set_freq(sdata, freq);
110 98
111 if (res) 99 ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
112 return res;
113 100
114 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 101 local->oper_channel = chan;
102 local->oper_channel_type = NL80211_CHAN_NO_HT;
103 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
104 sband = local->hw.wiphy->bands[chan->band];
115 105
116 /* Build IBSS probe response */ 106 /* Build IBSS probe response */
117 107 mgmt = (void *) skb_put(skb, 24 + sizeof(mgmt->u.beacon));
118 skb_reserve(skb, local->hw.extra_tx_headroom);
119
120 mgmt = (struct ieee80211_mgmt *)
121 skb_put(skb, 24 + sizeof(mgmt->u.beacon));
122 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); 108 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
123 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 109 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
124 IEEE80211_STYPE_PROBE_RESP); 110 IEEE80211_STYPE_PROBE_RESP);
125 memset(mgmt->da, 0xff, ETH_ALEN); 111 memset(mgmt->da, 0xff, ETH_ALEN);
126 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 112 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
127 memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN); 113 memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN);
128 mgmt->u.beacon.beacon_int = 114 mgmt->u.beacon.beacon_int = cpu_to_le16(local->hw.conf.beacon_int);
129 cpu_to_le16(local->hw.conf.beacon_int);
130 mgmt->u.beacon.timestamp = cpu_to_le64(tsf); 115 mgmt->u.beacon.timestamp = cpu_to_le64(tsf);
131 mgmt->u.beacon.capab_info = cpu_to_le16(capability); 116 mgmt->u.beacon.capab_info = cpu_to_le16(capability);
132 117
@@ -147,7 +132,7 @@ static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
147 pos = skb_put(skb, 2 + 1); 132 pos = skb_put(skb, 2 + 1);
148 *pos++ = WLAN_EID_DS_PARAMS; 133 *pos++ = WLAN_EID_DS_PARAMS;
149 *pos++ = 1; 134 *pos++ = 1;
150 *pos++ = ieee80211_frequency_to_channel(freq); 135 *pos++ = ieee80211_frequency_to_channel(chan->center_freq);
151 } 136 }
152 137
153 pos = skb_put(skb, 2 + 2); 138 pos = skb_put(skb, 2 + 2);
@@ -165,12 +150,15 @@ static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
165 memcpy(pos, &supp_rates[8], rates); 150 memcpy(pos, &supp_rates[8], rates);
166 } 151 }
167 152
168 ifibss->probe_resp = skb; 153 if (ifibss->ie_len)
154 memcpy(skb_put(skb, ifibss->ie_len),
155 ifibss->ie, ifibss->ie_len);
156
157 rcu_assign_pointer(ifibss->presp, skb);
169 158
170 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON | 159 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON |
171 IEEE80211_IFCC_BEACON_ENABLED); 160 IEEE80211_IFCC_BEACON_ENABLED);
172 161
173
174 rates = 0; 162 rates = 0;
175 for (i = 0; i < supp_rates_len; i++) { 163 for (i = 0; i < supp_rates_len; i++) {
176 int bitrate = (supp_rates[i] & 0x7f) * 5; 164 int bitrate = (supp_rates[i] & 0x7f) * 5;
@@ -181,27 +169,24 @@ static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
181 169
182 ieee80211_sta_def_wmm_params(sdata, supp_rates_len, supp_rates); 170 ieee80211_sta_def_wmm_params(sdata, supp_rates_len, supp_rates);
183 171
184 ifibss->flags |= IEEE80211_IBSS_PREV_BSSID_SET;
185 ifibss->state = IEEE80211_IBSS_MLME_JOINED; 172 ifibss->state = IEEE80211_IBSS_MLME_JOINED;
186 mod_timer(&ifibss->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); 173 mod_timer(&ifibss->timer,
174 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
187 175
188 memset(&wrqu, 0, sizeof(wrqu)); 176 cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel,
189 memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN); 177 mgmt, skb->len, 0, GFP_KERNEL);
190 wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL); 178 cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);
191
192 return res;
193} 179}
194 180
195static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, 181static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
196 struct ieee80211_bss *bss) 182 struct ieee80211_bss *bss)
197{ 183{
198 return __ieee80211_sta_join_ibss(sdata, 184 __ieee80211_sta_join_ibss(sdata, bss->cbss.bssid,
199 bss->cbss.bssid, 185 bss->cbss.beacon_interval,
200 bss->cbss.beacon_interval, 186 bss->cbss.channel,
201 bss->cbss.channel->center_freq, 187 bss->supp_rates_len, bss->supp_rates,
202 bss->supp_rates_len, bss->supp_rates, 188 bss->cbss.capability,
203 bss->cbss.capability, 189 bss->cbss.tsf);
204 bss->cbss.tsf);
205} 190}
206 191
207static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, 192static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
@@ -277,7 +262,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
277 goto put_bss; 262 goto put_bss;
278 263
279 /* we use a fixed BSSID */ 264 /* we use a fixed BSSID */
280 if (sdata->u.ibss.flags & IEEE80211_IBSS_BSSID_SET) 265 if (sdata->u.ibss.bssid)
281 goto put_bss; 266 goto put_bss;
282 267
283 /* not an IBSS */ 268 /* not an IBSS */
@@ -369,13 +354,14 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
369 struct sta_info *sta; 354 struct sta_info *sta;
370 int band = local->hw.conf.channel->band; 355 int band = local->hw.conf.channel->band;
371 356
372 /* TODO: Could consider removing the least recently used entry and 357 /*
373 * allow new one to be added. */ 358 * XXX: Consider removing the least recently used entry and
359 * allow new one to be added.
360 */
374 if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { 361 if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) {
375 if (net_ratelimit()) { 362 if (net_ratelimit())
376 printk(KERN_DEBUG "%s: No room for a new IBSS STA " 363 printk(KERN_DEBUG "%s: No room for a new IBSS STA entry %pM\n",
377 "entry %pM\n", sdata->dev->name, addr); 364 sdata->dev->name, addr);
378 }
379 return NULL; 365 return NULL;
380 } 366 }
381 367
@@ -432,14 +418,15 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
432{ 418{
433 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 419 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
434 420
435 mod_timer(&ifibss->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); 421 mod_timer(&ifibss->timer,
422 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
436 423
437 ieee80211_sta_expire(sdata, IEEE80211_IBSS_INACTIVITY_LIMIT); 424 ieee80211_sta_expire(sdata, IEEE80211_IBSS_INACTIVITY_LIMIT);
425
438 if (ieee80211_sta_active_ibss(sdata)) 426 if (ieee80211_sta_active_ibss(sdata))
439 return; 427 return;
440 428
441 if ((ifibss->flags & IEEE80211_IBSS_BSSID_SET) && 429 if (ifibss->fixed_channel)
442 (!(ifibss->flags & IEEE80211_IBSS_AUTO_CHANNEL_SEL)))
443 return; 430 return;
444 431
445 printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other " 432 printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other "
@@ -455,7 +442,7 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
455 ieee80211_request_scan(sdata, &sdata->local->int_scan_req); 442 ieee80211_request_scan(sdata, &sdata->local->int_scan_req);
456} 443}
457 444
458static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) 445static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
459{ 446{
460 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 447 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
461 struct ieee80211_local *local = sdata->local; 448 struct ieee80211_local *local = sdata->local;
@@ -466,7 +453,7 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
466 u16 capability; 453 u16 capability;
467 int i; 454 int i;
468 455
469 if (ifibss->flags & IEEE80211_IBSS_BSSID_SET) { 456 if (ifibss->fixed_bssid) {
470 memcpy(bssid, ifibss->bssid, ETH_ALEN); 457 memcpy(bssid, ifibss->bssid, ETH_ALEN);
471 } else { 458 } else {
472 /* Generate random, not broadcast, locally administered BSSID. Mix in 459 /* Generate random, not broadcast, locally administered BSSID. Mix in
@@ -482,7 +469,7 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
482 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n", 469 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n",
483 sdata->dev->name, bssid); 470 sdata->dev->name, bssid);
484 471
485 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 472 sband = local->hw.wiphy->bands[ifibss->channel->band];
486 473
487 if (local->hw.conf.beacon_int == 0) 474 if (local->hw.conf.beacon_int == 0)
488 local->hw.conf.beacon_int = 100; 475 local->hw.conf.beacon_int = 100;
@@ -500,24 +487,20 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
500 *pos++ = (u8) (rate / 5); 487 *pos++ = (u8) (rate / 5);
501 } 488 }
502 489
503 return __ieee80211_sta_join_ibss(sdata, 490 __ieee80211_sta_join_ibss(sdata, bssid, local->hw.conf.beacon_int,
504 bssid, local->hw.conf.beacon_int, 491 ifibss->channel, sband->n_bitrates,
505 local->hw.conf.channel->center_freq, 492 supp_rates, capability, 0);
506 sband->n_bitrates, supp_rates,
507 capability, 0);
508} 493}
509 494
510static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) 495static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
511{ 496{
512 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 497 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
513 struct ieee80211_local *local = sdata->local; 498 struct ieee80211_local *local = sdata->local;
514 struct ieee80211_bss *bss; 499 struct ieee80211_bss *bss;
500 struct ieee80211_channel *chan = NULL;
515 const u8 *bssid = NULL; 501 const u8 *bssid = NULL;
516 int active_ibss; 502 int active_ibss;
517 503
518 if (ifibss->ssid_len == 0)
519 return -EINVAL;
520
521 active_ibss = ieee80211_sta_active_ibss(sdata); 504 active_ibss = ieee80211_sta_active_ibss(sdata);
522#ifdef CONFIG_MAC80211_IBSS_DEBUG 505#ifdef CONFIG_MAC80211_IBSS_DEBUG
523 printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n", 506 printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n",
@@ -525,11 +508,15 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
525#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 508#endif /* CONFIG_MAC80211_IBSS_DEBUG */
526 509
527 if (active_ibss) 510 if (active_ibss)
528 return 0; 511 return;
529 512
530 if (ifibss->flags & IEEE80211_IBSS_BSSID_SET) 513 if (ifibss->fixed_bssid)
514 bssid = ifibss->bssid;
515 if (ifibss->fixed_channel)
516 chan = ifibss->channel;
517 if (!is_zero_ether_addr(ifibss->bssid))
531 bssid = ifibss->bssid; 518 bssid = ifibss->bssid;
532 bss = (void *)cfg80211_get_bss(local->hw.wiphy, NULL, bssid, 519 bss = (void *)cfg80211_get_bss(local->hw.wiphy, chan, bssid,
533 ifibss->ssid, ifibss->ssid_len, 520 ifibss->ssid, ifibss->ssid_len,
534 WLAN_CAPABILITY_IBSS, 521 WLAN_CAPABILITY_IBSS,
535 WLAN_CAPABILITY_IBSS); 522 WLAN_CAPABILITY_IBSS);
@@ -540,18 +527,14 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
540 "%pM\n", bss->cbss.bssid, ifibss->bssid); 527 "%pM\n", bss->cbss.bssid, ifibss->bssid);
541#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 528#endif /* CONFIG_MAC80211_IBSS_DEBUG */
542 529
543 if (bss && 530 if (bss && memcmp(ifibss->bssid, bss->cbss.bssid, ETH_ALEN)) {
544 (!(ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET) ||
545 memcmp(ifibss->bssid, bss->cbss.bssid, ETH_ALEN))) {
546 int ret;
547
548 printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" 531 printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM"
549 " based on configured SSID\n", 532 " based on configured SSID\n",
550 sdata->dev->name, bss->cbss.bssid); 533 sdata->dev->name, bss->cbss.bssid);
551 534
552 ret = ieee80211_sta_join_ibss(sdata, bss); 535 ieee80211_sta_join_ibss(sdata, bss);
553 ieee80211_rx_bss_put(local, bss); 536 ieee80211_rx_bss_put(local, bss);
554 return ret; 537 return;
555 } else if (bss) 538 } else if (bss)
556 ieee80211_rx_bss_put(local, bss); 539 ieee80211_rx_bss_put(local, bss);
557 540
@@ -562,29 +545,31 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
562 /* Selected IBSS not found in current scan results - try to scan */ 545 /* Selected IBSS not found in current scan results - try to scan */
563 if (ifibss->state == IEEE80211_IBSS_MLME_JOINED && 546 if (ifibss->state == IEEE80211_IBSS_MLME_JOINED &&
564 !ieee80211_sta_active_ibss(sdata)) { 547 !ieee80211_sta_active_ibss(sdata)) {
565 mod_timer(&ifibss->timer, jiffies + 548 mod_timer(&ifibss->timer,
566 IEEE80211_IBSS_MERGE_INTERVAL); 549 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
567 } else if (time_after(jiffies, local->last_scan_completed + 550 } else if (time_after(jiffies, ifibss->last_scan_completed +
568 IEEE80211_SCAN_INTERVAL)) { 551 IEEE80211_SCAN_INTERVAL)) {
569 printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " 552 printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "
570 "join\n", sdata->dev->name); 553 "join\n", sdata->dev->name);
571 554
572 /* XXX maybe racy? */ 555 /* XXX maybe racy? */
573 if (local->scan_req) 556 if (local->scan_req)
574 return -EBUSY; 557 return;
575 558
576 memcpy(local->int_scan_req.ssids[0].ssid, 559 memcpy(local->int_scan_req.ssids[0].ssid,
577 ifibss->ssid, IEEE80211_MAX_SSID_LEN); 560 ifibss->ssid, IEEE80211_MAX_SSID_LEN);
578 local->int_scan_req.ssids[0].ssid_len = ifibss->ssid_len; 561 local->int_scan_req.ssids[0].ssid_len =
579 return ieee80211_request_scan(sdata, &local->int_scan_req); 562 ifibss->ssid_len;
563 ieee80211_request_scan(sdata, &local->int_scan_req);
580 } else if (ifibss->state != IEEE80211_IBSS_MLME_JOINED) { 564 } else if (ifibss->state != IEEE80211_IBSS_MLME_JOINED) {
581 int interval = IEEE80211_SCAN_INTERVAL; 565 int interval = IEEE80211_SCAN_INTERVAL;
582 566
583 if (time_after(jiffies, ifibss->ibss_join_req + 567 if (time_after(jiffies, ifibss->ibss_join_req +
584 IEEE80211_IBSS_JOIN_TIMEOUT)) { 568 IEEE80211_IBSS_JOIN_TIMEOUT)) {
585 if (!(local->oper_channel->flags & 569 if (!(local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS)) {
586 IEEE80211_CHAN_NO_IBSS)) 570 ieee80211_sta_create_ibss(sdata);
587 return ieee80211_sta_create_ibss(sdata); 571 return;
572 }
588 printk(KERN_DEBUG "%s: IBSS not allowed on" 573 printk(KERN_DEBUG "%s: IBSS not allowed on"
589 " %d MHz\n", sdata->dev->name, 574 " %d MHz\n", sdata->dev->name,
590 local->hw.conf.channel->center_freq); 575 local->hw.conf.channel->center_freq);
@@ -595,11 +580,9 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
595 } 580 }
596 581
597 ifibss->state = IEEE80211_IBSS_MLME_SEARCH; 582 ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
598 mod_timer(&ifibss->timer, jiffies + interval); 583 mod_timer(&ifibss->timer,
599 return 0; 584 round_jiffies(jiffies + interval));
600 } 585 }
601
602 return 0;
603} 586}
604 587
605static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, 588static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
@@ -614,7 +597,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
614 u8 *pos, *end; 597 u8 *pos, *end;
615 598
616 if (ifibss->state != IEEE80211_IBSS_MLME_JOINED || 599 if (ifibss->state != IEEE80211_IBSS_MLME_JOINED ||
617 len < 24 + 2 || !ifibss->probe_resp) 600 len < 24 + 2 || !ifibss->presp)
618 return; 601 return;
619 602
620 if (local->ops->tx_last_beacon) 603 if (local->ops->tx_last_beacon)
@@ -649,13 +632,13 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
649 } 632 }
650 if (pos[1] != 0 && 633 if (pos[1] != 0 &&
651 (pos[1] != ifibss->ssid_len || 634 (pos[1] != ifibss->ssid_len ||
652 memcmp(pos + 2, ifibss->ssid, ifibss->ssid_len) != 0)) { 635 !memcmp(pos + 2, ifibss->ssid, ifibss->ssid_len))) {
653 /* Ignore ProbeReq for foreign SSID */ 636 /* Ignore ProbeReq for foreign SSID */
654 return; 637 return;
655 } 638 }
656 639
657 /* Reply with ProbeResp */ 640 /* Reply with ProbeResp */
658 skb = skb_copy(ifibss->probe_resp, GFP_KERNEL); 641 skb = skb_copy(ifibss->presp, GFP_KERNEL);
659 if (!skb) 642 if (!skb)
660 return; 643 return;
661 644
@@ -794,89 +777,21 @@ void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata)
794 setup_timer(&ifibss->timer, ieee80211_ibss_timer, 777 setup_timer(&ifibss->timer, ieee80211_ibss_timer,
795 (unsigned long) sdata); 778 (unsigned long) sdata);
796 skb_queue_head_init(&ifibss->skb_queue); 779 skb_queue_head_init(&ifibss->skb_queue);
797
798 ifibss->flags |= IEEE80211_IBSS_AUTO_BSSID_SEL |
799 IEEE80211_IBSS_AUTO_CHANNEL_SEL;
800}
801
802int ieee80211_ibss_commit(struct ieee80211_sub_if_data *sdata)
803{
804 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
805
806 ifibss->flags &= ~IEEE80211_IBSS_PREV_BSSID_SET;
807
808 if (ifibss->ssid_len)
809 ifibss->flags |= IEEE80211_IBSS_SSID_SET;
810 else
811 ifibss->flags &= ~IEEE80211_IBSS_SSID_SET;
812
813 ifibss->ibss_join_req = jiffies;
814 ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
815 set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request);
816
817 return 0;
818}
819
820int ieee80211_ibss_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len)
821{
822 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
823
824 if (len > IEEE80211_MAX_SSID_LEN)
825 return -EINVAL;
826
827 if (ifibss->ssid_len != len || memcmp(ifibss->ssid, ssid, len) != 0) {
828 memset(ifibss->ssid, 0, sizeof(ifibss->ssid));
829 memcpy(ifibss->ssid, ssid, len);
830 ifibss->ssid_len = len;
831 }
832
833 return ieee80211_ibss_commit(sdata);
834}
835
836int ieee80211_ibss_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len)
837{
838 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
839
840 memcpy(ssid, ifibss->ssid, ifibss->ssid_len);
841 *len = ifibss->ssid_len;
842
843 return 0;
844}
845
846int ieee80211_ibss_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
847{
848 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
849
850 if (is_valid_ether_addr(bssid)) {
851 memcpy(ifibss->bssid, bssid, ETH_ALEN);
852 ifibss->flags |= IEEE80211_IBSS_BSSID_SET;
853 } else {
854 memset(ifibss->bssid, 0, ETH_ALEN);
855 ifibss->flags &= ~IEEE80211_IBSS_BSSID_SET;
856 }
857
858 if (netif_running(sdata->dev)) {
859 if (ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID)) {
860 printk(KERN_DEBUG "%s: Failed to config new BSSID to "
861 "the low-level driver\n", sdata->dev->name);
862 }
863 }
864
865 return ieee80211_ibss_commit(sdata);
866} 780}
867 781
868/* scan finished notification */ 782/* scan finished notification */
869void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local) 783void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
870{ 784{
871 struct ieee80211_sub_if_data *sdata = local->scan_sdata; 785 struct ieee80211_sub_if_data *sdata;
872 struct ieee80211_if_ibss *ifibss;
873 786
874 if (sdata && sdata->vif.type == NL80211_IFTYPE_ADHOC) { 787 mutex_lock(&local->iflist_mtx);
875 ifibss = &sdata->u.ibss; 788 list_for_each_entry(sdata, &local->interfaces, list) {
876 if ((!(ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET)) || 789 if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
877 !ieee80211_sta_active_ibss(sdata)) 790 continue;
878 ieee80211_sta_find_ibss(sdata); 791 sdata->u.ibss.last_scan_completed = jiffies;
792 ieee80211_sta_find_ibss(sdata);
879 } 793 }
794 mutex_unlock(&local->iflist_mtx);
880} 795}
881 796
882ieee80211_rx_result 797ieee80211_rx_result
@@ -906,3 +821,71 @@ ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
906 821
907 return RX_DROP_MONITOR; 822 return RX_DROP_MONITOR;
908} 823}
824
825int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
826 struct cfg80211_ibss_params *params)
827{
828 struct sk_buff *skb;
829
830 memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN);
831 sdata->u.ibss.ssid_len = params->ssid_len;
832
833 if (params->bssid) {
834 memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN);
835 sdata->u.ibss.fixed_bssid = true;
836 } else
837 sdata->u.ibss.fixed_bssid = false;
838
839 sdata->u.ibss.channel = params->channel;
840 sdata->u.ibss.fixed_channel = params->channel_fixed;
841
842 if (params->ie) {
843 sdata->u.ibss.ie = kmemdup(params->ie, params->ie_len,
844 GFP_KERNEL);
845 if (sdata->u.ibss.ie)
846 sdata->u.ibss.ie_len = params->ie_len;
847 }
848
849 skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom +
850 36 /* bitrates */ +
851 34 /* SSID */ +
852 3 /* DS params */ +
853 4 /* IBSS params */ +
854 params->ie_len);
855 if (!skb)
856 return -ENOMEM;
857
858 sdata->u.ibss.skb = skb;
859 sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH;
860 sdata->u.ibss.ibss_join_req = jiffies;
861
862 set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
863 queue_work(sdata->local->hw.workqueue, &sdata->u.ibss.work);
864
865 return 0;
866}
867
868int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
869{
870 struct sk_buff *skb;
871
872 del_timer_sync(&sdata->u.ibss.timer);
873 clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
874 cancel_work_sync(&sdata->u.ibss.work);
875 clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
876
877 sta_info_flush(sdata->local, sdata);
878
879 /* remove beacon */
880 kfree(sdata->u.ibss.ie);
881 skb = sdata->u.ibss.presp;
882 rcu_assign_pointer(sdata->u.ibss.presp, NULL);
883 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON_ENABLED);
884 synchronize_rcu();
885 kfree_skb(skb);
886
887 skb_queue_purge(&sdata->u.ibss.skb_queue);
888 memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
889
890 return 0;
891}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e6ed78cb16b3..1579bc92c88d 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -24,7 +24,6 @@
24#include <linux/spinlock.h> 24#include <linux/spinlock.h>
25#include <linux/etherdevice.h> 25#include <linux/etherdevice.h>
26#include <net/cfg80211.h> 26#include <net/cfg80211.h>
27#include <net/wireless.h>
28#include <net/iw_handler.h> 27#include <net/iw_handler.h>
29#include <net/mac80211.h> 28#include <net/mac80211.h>
30#include "key.h" 29#include "key.h"
@@ -295,6 +294,8 @@ struct ieee80211_if_managed {
295 int auth_tries; /* retries for auth req */ 294 int auth_tries; /* retries for auth req */
296 int assoc_tries; /* retries for assoc req */ 295 int assoc_tries; /* retries for assoc req */
297 296
297 bool powersave; /* powersave requested for this iface */
298
298 unsigned long request; 299 unsigned long request;
299 300
300 unsigned long last_probe; 301 unsigned long last_probe;
@@ -306,6 +307,8 @@ struct ieee80211_if_managed {
306 int auth_alg; /* currently used IEEE 802.11 authentication algorithm */ 307 int auth_alg; /* currently used IEEE 802.11 authentication algorithm */
307 int auth_transaction; 308 int auth_transaction;
308 309
310 u32 beacon_crc;
311
309 enum { 312 enum {
310 IEEE80211_MFP_DISABLED, 313 IEEE80211_MFP_DISABLED,
311 IEEE80211_MFP_OPTIONAL, 314 IEEE80211_MFP_OPTIONAL,
@@ -319,14 +322,6 @@ struct ieee80211_if_managed {
319 size_t sme_auth_ie_len; 322 size_t sme_auth_ie_len;
320}; 323};
321 324
322enum ieee80211_ibss_flags {
323 IEEE80211_IBSS_AUTO_CHANNEL_SEL = BIT(0),
324 IEEE80211_IBSS_AUTO_BSSID_SEL = BIT(1),
325 IEEE80211_IBSS_BSSID_SET = BIT(2),
326 IEEE80211_IBSS_PREV_BSSID_SET = BIT(3),
327 IEEE80211_IBSS_SSID_SET = BIT(4),
328};
329
330enum ieee80211_ibss_request { 325enum ieee80211_ibss_request {
331 IEEE80211_IBSS_REQ_RUN = 0, 326 IEEE80211_IBSS_REQ_RUN = 0,
332}; 327};
@@ -337,17 +332,20 @@ struct ieee80211_if_ibss {
337 332
338 struct sk_buff_head skb_queue; 333 struct sk_buff_head skb_queue;
339 334
340 u8 ssid[IEEE80211_MAX_SSID_LEN]; 335 unsigned long request;
341 u8 ssid_len; 336 unsigned long last_scan_completed;
342 337 bool fixed_bssid;
343 u32 flags; 338 bool fixed_channel;
344 339
345 u8 bssid[ETH_ALEN]; 340 u8 bssid[ETH_ALEN];
346 341 u8 ssid[IEEE80211_MAX_SSID_LEN];
347 unsigned long request; 342 u8 ssid_len, ie_len;
343 u8 *ie;
344 struct ieee80211_channel *channel;
348 345
349 unsigned long ibss_join_req; 346 unsigned long ibss_join_req;
350 struct sk_buff *probe_resp; /* ProbeResp template for IBSS */ 347 /* probe response/beacon for IBSS */
348 struct sk_buff *presp, *skb;
351 349
352 enum { 350 enum {
353 IEEE80211_IBSS_MLME_SEARCH, 351 IEEE80211_IBSS_MLME_SEARCH,
@@ -626,8 +624,6 @@ struct ieee80211_local {
626 spinlock_t sta_lock; 624 spinlock_t sta_lock;
627 unsigned long num_sta; 625 unsigned long num_sta;
628 struct list_head sta_list; 626 struct list_head sta_list;
629 struct list_head sta_flush_list;
630 struct work_struct sta_flush_work;
631 struct sta_info *sta_hash[STA_HASH_SIZE]; 627 struct sta_info *sta_hash[STA_HASH_SIZE];
632 struct timer_list sta_cleanup; 628 struct timer_list sta_cleanup;
633 629
@@ -647,9 +643,6 @@ struct ieee80211_local {
647 643
648 struct rate_control_ref *rate_ctrl; 644 struct rate_control_ref *rate_ctrl;
649 645
650 int rts_threshold;
651 int fragmentation_threshold;
652
653 struct crypto_blkcipher *wep_tx_tfm; 646 struct crypto_blkcipher *wep_tx_tfm;
654 struct crypto_blkcipher *wep_rx_tfm; 647 struct crypto_blkcipher *wep_rx_tfm;
655 u32 wep_iv; 648 u32 wep_iv;
@@ -671,10 +664,12 @@ struct ieee80211_local {
671 struct cfg80211_scan_request int_scan_req; 664 struct cfg80211_scan_request int_scan_req;
672 struct cfg80211_scan_request *scan_req; 665 struct cfg80211_scan_request *scan_req;
673 struct ieee80211_channel *scan_channel; 666 struct ieee80211_channel *scan_channel;
667 const u8 *orig_ies;
668 int orig_ies_len;
674 int scan_channel_idx; 669 int scan_channel_idx;
670 int scan_ies_len;
675 671
676 enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state; 672 enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state;
677 unsigned long last_scan_completed;
678 struct delayed_work scan_work; 673 struct delayed_work scan_work;
679 struct ieee80211_sub_if_data *scan_sdata; 674 struct ieee80211_sub_if_data *scan_sdata;
680 enum nl80211_channel_type oper_channel_type; 675 enum nl80211_channel_type oper_channel_type;
@@ -736,15 +731,22 @@ struct ieee80211_local {
736 int wifi_wme_noack_test; 731 int wifi_wme_noack_test;
737 unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ 732 unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */
738 733
739 bool powersave;
740 bool pspolling; 734 bool pspolling;
735 /*
736 * PS can only be enabled when we have exactly one managed
737 * interface (and monitors) in PS, this then points there.
738 */
739 struct ieee80211_sub_if_data *ps_sdata;
741 struct work_struct dynamic_ps_enable_work; 740 struct work_struct dynamic_ps_enable_work;
742 struct work_struct dynamic_ps_disable_work; 741 struct work_struct dynamic_ps_disable_work;
743 struct timer_list dynamic_ps_timer; 742 struct timer_list dynamic_ps_timer;
743 struct notifier_block network_latency_notifier;
744 744
745 int user_power_level; /* in dBm */ 745 int user_power_level; /* in dBm */
746 int power_constr_level; /* in dBm */ 746 int power_constr_level; /* in dBm */
747 747
748 struct work_struct restart_work;
749
748#ifdef CONFIG_MAC80211_DEBUGFS 750#ifdef CONFIG_MAC80211_DEBUGFS
749 struct local_debugfsdentries { 751 struct local_debugfsdentries {
750 struct dentry *rcdir; 752 struct dentry *rcdir;
@@ -830,7 +832,7 @@ struct ieee802_11_elems {
830 u8 *fh_params; 832 u8 *fh_params;
831 u8 *ds_params; 833 u8 *ds_params;
832 u8 *cf_params; 834 u8 *cf_params;
833 u8 *tim; 835 struct ieee80211_tim_ie *tim;
834 u8 *ibss_params; 836 u8 *ibss_params;
835 u8 *challenge; 837 u8 *challenge;
836 u8 *wpa; 838 u8 *wpa;
@@ -927,12 +929,11 @@ int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason
927int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason); 929int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason);
928void ieee80211_send_pspoll(struct ieee80211_local *local, 930void ieee80211_send_pspoll(struct ieee80211_local *local,
929 struct ieee80211_sub_if_data *sdata); 931 struct ieee80211_sub_if_data *sdata);
932void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency);
933int ieee80211_max_network_latency(struct notifier_block *nb,
934 unsigned long data, void *dummy);
930 935
931/* IBSS code */ 936/* IBSS code */
932int ieee80211_ibss_commit(struct ieee80211_sub_if_data *sdata);
933int ieee80211_ibss_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len);
934int ieee80211_ibss_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len);
935int ieee80211_ibss_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid);
936void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); 937void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);
937void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata); 938void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata);
938ieee80211_rx_result 939ieee80211_rx_result
@@ -940,6 +941,9 @@ ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
940 struct ieee80211_rx_status *rx_status); 941 struct ieee80211_rx_status *rx_status);
941struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, 942struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
942 u8 *bssid, u8 *addr, u32 supp_rates); 943 u8 *bssid, u8 *addr, u32 supp_rates);
944int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
945 struct cfg80211_ibss_params *params);
946int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata);
943 947
944/* scan/BSS handling */ 948/* scan/BSS handling */
945void ieee80211_scan_work(struct work_struct *work); 949void ieee80211_scan_work(struct work_struct *work);
@@ -995,9 +999,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
995void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, 999void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
996 struct ieee80211_ht_cap *ht_cap_ie, 1000 struct ieee80211_ht_cap *ht_cap_ie,
997 struct ieee80211_sta_ht_cap *ht_cap); 1001 struct ieee80211_sta_ht_cap *ht_cap);
998u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
999 struct ieee80211_ht_info *hti,
1000 u16 ap_ht_cap_flags);
1001void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn); 1002void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn);
1002void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, 1003void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
1003 const u8 *da, u16 tid, 1004 const u8 *da, u16 tid,
@@ -1036,15 +1037,22 @@ void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
1036 u16 capab_info, u8 *pwr_constr_elem, 1037 u16 capab_info, u8 *pwr_constr_elem,
1037 u8 pwr_constr_elem_len); 1038 u8 pwr_constr_elem_len);
1038 1039
1039/* Suspend/resume */ 1040/* Suspend/resume and hw reconfiguration */
1041int ieee80211_reconfig(struct ieee80211_local *local);
1042
1040#ifdef CONFIG_PM 1043#ifdef CONFIG_PM
1041int __ieee80211_suspend(struct ieee80211_hw *hw); 1044int __ieee80211_suspend(struct ieee80211_hw *hw);
1042int __ieee80211_resume(struct ieee80211_hw *hw); 1045
1046static inline int __ieee80211_resume(struct ieee80211_hw *hw)
1047{
1048 return ieee80211_reconfig(hw_to_local(hw));
1049}
1043#else 1050#else
1044static inline int __ieee80211_suspend(struct ieee80211_hw *hw) 1051static inline int __ieee80211_suspend(struct ieee80211_hw *hw)
1045{ 1052{
1046 return 0; 1053 return 0;
1047} 1054}
1055
1048static inline int __ieee80211_resume(struct ieee80211_hw *hw) 1056static inline int __ieee80211_resume(struct ieee80211_hw *hw)
1049{ 1057{
1050 return 0; 1058 return 0;
@@ -1060,12 +1068,15 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
1060int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, 1068int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
1061 int rate, int erp, int short_preamble); 1069 int rate, int erp, int short_preamble);
1062void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx, 1070void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx,
1063 struct ieee80211_hdr *hdr); 1071 struct ieee80211_hdr *hdr, const u8 *tsc);
1064void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata); 1072void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata);
1065void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, 1073void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
1066 int encrypt); 1074 int encrypt);
1067void ieee802_11_parse_elems(u8 *start, size_t len, 1075void ieee802_11_parse_elems(u8 *start, size_t len,
1068 struct ieee802_11_elems *elems); 1076 struct ieee802_11_elems *elems);
1077u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
1078 struct ieee802_11_elems *elems,
1079 u64 filter, u32 crc);
1069int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freq); 1080int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freq);
1070u32 ieee80211_mandatory_rates(struct ieee80211_local *local, 1081u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
1071 enum ieee80211_band band); 1082 enum ieee80211_band band);
@@ -1093,9 +1104,11 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
1093 u16 transaction, u16 auth_alg, 1104 u16 transaction, u16 auth_alg,
1094 u8 *extra, size_t extra_len, 1105 u8 *extra, size_t extra_len,
1095 const u8 *bssid, int encrypt); 1106 const u8 *bssid, int encrypt);
1107int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1108 const u8 *ie, size_t ie_len);
1096void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, 1109void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
1097 u8 *ssid, size_t ssid_len, 1110 const u8 *ssid, size_t ssid_len,
1098 u8 *ie, size_t ie_len); 1111 const u8 *ie, size_t ie_len);
1099 1112
1100void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, 1113void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
1101 const size_t supp_rates_len, 1114 const size_t supp_rates_len,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 91e8e1bacaaa..52425975bbbe 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -235,11 +235,7 @@ static int ieee80211_open(struct net_device *dev)
235 netif_addr_unlock_bh(local->mdev); 235 netif_addr_unlock_bh(local->mdev);
236 break; 236 break;
237 case NL80211_IFTYPE_STATION: 237 case NL80211_IFTYPE_STATION:
238 case NL80211_IFTYPE_ADHOC: 238 sdata->u.mgd.flags &= ~IEEE80211_STA_PREV_BSSID_SET;
239 if (sdata->vif.type == NL80211_IFTYPE_STATION)
240 sdata->u.mgd.flags &= ~IEEE80211_STA_PREV_BSSID_SET;
241 else
242 sdata->u.ibss.flags &= ~IEEE80211_IBSS_PREV_BSSID_SET;
243 /* fall through */ 239 /* fall through */
244 default: 240 default:
245 conf.vif = &sdata->vif; 241 conf.vif = &sdata->vif;
@@ -317,6 +313,8 @@ static int ieee80211_open(struct net_device *dev)
317 ieee80211_set_wmm_default(sdata); 313 ieee80211_set_wmm_default(sdata);
318 } 314 }
319 315
316 ieee80211_recalc_ps(local, -1);
317
320 /* 318 /*
321 * ieee80211_sta_work is disabled while network interface 319 * ieee80211_sta_work is disabled while network interface
322 * is down. Therefore, some configuration changes may not 320 * is down. Therefore, some configuration changes may not
@@ -325,8 +323,6 @@ static int ieee80211_open(struct net_device *dev)
325 */ 323 */
326 if (sdata->vif.type == NL80211_IFTYPE_STATION) 324 if (sdata->vif.type == NL80211_IFTYPE_STATION)
327 queue_work(local->hw.workqueue, &sdata->u.mgd.work); 325 queue_work(local->hw.workqueue, &sdata->u.mgd.work);
328 else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
329 queue_work(local->hw.workqueue, &sdata->u.ibss.work);
330 326
331 netif_tx_start_all_queues(dev); 327 netif_tx_start_all_queues(dev);
332 328
@@ -497,7 +493,6 @@ static int ieee80211_stop(struct net_device *dev)
497 /* fall through */ 493 /* fall through */
498 case NL80211_IFTYPE_ADHOC: 494 case NL80211_IFTYPE_ADHOC:
499 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { 495 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
500 memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
501 del_timer_sync(&sdata->u.ibss.timer); 496 del_timer_sync(&sdata->u.ibss.timer);
502 cancel_work_sync(&sdata->u.ibss.work); 497 cancel_work_sync(&sdata->u.ibss.work);
503 synchronize_rcu(); 498 synchronize_rcu();
@@ -572,6 +567,8 @@ static int ieee80211_stop(struct net_device *dev)
572 hw_reconf_flags = 0; 567 hw_reconf_flags = 0;
573 } 568 }
574 569
570 ieee80211_recalc_ps(local, -1);
571
575 /* do after stop to avoid reconfiguring when we stop anyway */ 572 /* do after stop to avoid reconfiguring when we stop anyway */
576 if (hw_reconf_flags) 573 if (hw_reconf_flags)
577 ieee80211_hw_config(local, hw_reconf_flags); 574 ieee80211_hw_config(local, hw_reconf_flags);
@@ -649,7 +646,8 @@ static void ieee80211_teardown_sdata(struct net_device *dev)
649 mesh_rmc_free(sdata); 646 mesh_rmc_free(sdata);
650 break; 647 break;
651 case NL80211_IFTYPE_ADHOC: 648 case NL80211_IFTYPE_ADHOC:
652 kfree_skb(sdata->u.ibss.probe_resp); 649 if (WARN_ON(sdata->u.ibss.presp))
650 kfree_skb(sdata->u.ibss.presp);
653 break; 651 break;
654 case NL80211_IFTYPE_STATION: 652 case NL80211_IFTYPE_STATION:
655 kfree(sdata->u.mgd.extra_ie); 653 kfree(sdata->u.mgd.extra_ie);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 14134193cd17..5ca62ea15079 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -21,6 +21,7 @@
21#include <linux/wireless.h> 21#include <linux/wireless.h>
22#include <linux/rtnetlink.h> 22#include <linux/rtnetlink.h>
23#include <linux/bitmap.h> 23#include <linux/bitmap.h>
24#include <linux/pm_qos_params.h>
24#include <net/net_namespace.h> 25#include <net/net_namespace.h>
25#include <net/cfg80211.h> 26#include <net/cfg80211.h>
26 27
@@ -208,7 +209,7 @@ int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
208 !!rcu_dereference(sdata->u.ap.beacon); 209 !!rcu_dereference(sdata->u.ap.beacon);
209 break; 210 break;
210 case NL80211_IFTYPE_ADHOC: 211 case NL80211_IFTYPE_ADHOC:
211 conf.enable_beacon = !!sdata->u.ibss.probe_resp; 212 conf.enable_beacon = !!sdata->u.ibss.presp;
212 break; 213 break;
213 case NL80211_IFTYPE_MESH_POINT: 214 case NL80211_IFTYPE_MESH_POINT:
214 conf.enable_beacon = true; 215 conf.enable_beacon = true;
@@ -696,6 +697,28 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
696} 697}
697EXPORT_SYMBOL(ieee80211_tx_status); 698EXPORT_SYMBOL(ieee80211_tx_status);
698 699
700static void ieee80211_restart_work(struct work_struct *work)
701{
702 struct ieee80211_local *local =
703 container_of(work, struct ieee80211_local, restart_work);
704
705 rtnl_lock();
706 ieee80211_reconfig(local);
707 rtnl_unlock();
708}
709
710void ieee80211_restart_hw(struct ieee80211_hw *hw)
711{
712 struct ieee80211_local *local = hw_to_local(hw);
713
714 /* use this reason, __ieee80211_resume will unblock it */
715 ieee80211_stop_queues_by_reason(hw,
716 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
717
718 schedule_work(&local->restart_work);
719}
720EXPORT_SYMBOL(ieee80211_restart_hw);
721
699struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, 722struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
700 const struct ieee80211_ops *ops) 723 const struct ieee80211_ops *ops)
701{ 724{
@@ -728,12 +751,13 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
728 return NULL; 751 return NULL;
729 752
730 wiphy->privid = mac80211_wiphy_privid; 753 wiphy->privid = mac80211_wiphy_privid;
731 wiphy->max_scan_ssids = 4; 754
732 /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */ 755 /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */
733 wiphy->bss_priv_size = sizeof(struct ieee80211_bss) - 756 wiphy->bss_priv_size = sizeof(struct ieee80211_bss) -
734 sizeof(struct cfg80211_bss); 757 sizeof(struct cfg80211_bss);
735 758
736 local = wiphy_priv(wiphy); 759 local = wiphy_priv(wiphy);
760
737 local->hw.wiphy = wiphy; 761 local->hw.wiphy = wiphy;
738 762
739 local->hw.priv = (char *)local + 763 local->hw.priv = (char *)local +
@@ -752,10 +776,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
752 /* set up some defaults */ 776 /* set up some defaults */
753 local->hw.queues = 1; 777 local->hw.queues = 1;
754 local->hw.max_rates = 1; 778 local->hw.max_rates = 1;
755 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; 779 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
756 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; 780 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
757 local->hw.conf.long_frame_max_tx_count = 4;
758 local->hw.conf.short_frame_max_tx_count = 7;
759 local->hw.conf.radio_enabled = true; 781 local->hw.conf.radio_enabled = true;
760 local->user_power_level = -1; 782 local->user_power_level = -1;
761 783
@@ -768,6 +790,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
768 790
769 INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); 791 INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
770 792
793 INIT_WORK(&local->restart_work, ieee80211_restart_work);
794
771 INIT_WORK(&local->dynamic_ps_enable_work, 795 INIT_WORK(&local->dynamic_ps_enable_work,
772 ieee80211_dynamic_ps_enable_work); 796 ieee80211_dynamic_ps_enable_work);
773 INIT_WORK(&local->dynamic_ps_disable_work, 797 INIT_WORK(&local->dynamic_ps_disable_work,
@@ -821,7 +845,17 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
821 enum ieee80211_band band; 845 enum ieee80211_band band;
822 struct net_device *mdev; 846 struct net_device *mdev;
823 struct ieee80211_master_priv *mpriv; 847 struct ieee80211_master_priv *mpriv;
824 int channels, i, j; 848 int channels, i, j, max_bitrates;
849 bool supp_ht;
850 static const u32 cipher_suites[] = {
851 WLAN_CIPHER_SUITE_WEP40,
852 WLAN_CIPHER_SUITE_WEP104,
853 WLAN_CIPHER_SUITE_TKIP,
854 WLAN_CIPHER_SUITE_CCMP,
855
856 /* keep last -- depends on hw flags! */
857 WLAN_CIPHER_SUITE_AES_CMAC
858 };
825 859
826 /* 860 /*
827 * generic code guarantees at least one band, 861 * generic code guarantees at least one band,
@@ -829,18 +863,25 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
829 * that hw.conf.channel is assigned 863 * that hw.conf.channel is assigned
830 */ 864 */
831 channels = 0; 865 channels = 0;
866 max_bitrates = 0;
867 supp_ht = false;
832 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 868 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
833 struct ieee80211_supported_band *sband; 869 struct ieee80211_supported_band *sband;
834 870
835 sband = local->hw.wiphy->bands[band]; 871 sband = local->hw.wiphy->bands[band];
836 if (sband && !local->oper_channel) { 872 if (!sband)
873 continue;
874 if (!local->oper_channel) {
837 /* init channel we're on */ 875 /* init channel we're on */
838 local->hw.conf.channel = 876 local->hw.conf.channel =
839 local->oper_channel = 877 local->oper_channel =
840 local->scan_channel = &sband->channels[0]; 878 local->scan_channel = &sband->channels[0];
841 } 879 }
842 if (sband) 880 channels += sband->n_channels;
843 channels += sband->n_channels; 881
882 if (max_bitrates < sband->n_bitrates)
883 max_bitrates = sband->n_bitrates;
884 supp_ht = supp_ht || sband->ht_cap.ht_supported;
844 } 885 }
845 886
846 local->int_scan_req.n_channels = channels; 887 local->int_scan_req.n_channels = channels;
@@ -860,6 +901,37 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
860 else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) 901 else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
861 local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC; 902 local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
862 903
904 /*
905 * Calculate scan IE length -- we need this to alloc
906 * memory and to subtract from the driver limit. It
907 * includes the (extended) supported rates and HT
908 * information -- SSID is the driver's responsibility.
909 */
910 local->scan_ies_len = 4 + max_bitrates; /* (ext) supp rates */
911 if (supp_ht)
912 local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap);
913
914 if (!local->ops->hw_scan) {
915 /* For hw_scan, driver needs to set these up. */
916 local->hw.wiphy->max_scan_ssids = 4;
917 local->hw.wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
918 }
919
920 /*
921 * If the driver supports any scan IEs, then assume the
922 * limit includes the IEs mac80211 will add, otherwise
923 * leave it at zero and let the driver sort it out; we
924 * still pass our IEs to the driver but userspace will
925 * not be allowed to in that case.
926 */
927 if (local->hw.wiphy->max_scan_ie_len)
928 local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len;
929
930 local->hw.wiphy->cipher_suites = cipher_suites;
931 local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
932 if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE))
933 local->hw.wiphy->n_cipher_suites--;
934
863 result = wiphy_register(local->hw.wiphy); 935 result = wiphy_register(local->hw.wiphy);
864 if (result < 0) 936 if (result < 0)
865 goto fail_wiphy_register; 937 goto fail_wiphy_register;
@@ -965,25 +1037,38 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
965 } 1037 }
966 } 1038 }
967 1039
1040 local->network_latency_notifier.notifier_call =
1041 ieee80211_max_network_latency;
1042 result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY,
1043 &local->network_latency_notifier);
1044
1045 if (result) {
1046 rtnl_lock();
1047 goto fail_pm_qos;
1048 }
1049
968 return 0; 1050 return 0;
969 1051
970fail_rate: 1052 fail_pm_qos:
1053 ieee80211_led_exit(local);
1054 ieee80211_remove_interfaces(local);
1055 fail_rate:
971 unregister_netdevice(local->mdev); 1056 unregister_netdevice(local->mdev);
972 local->mdev = NULL; 1057 local->mdev = NULL;
973fail_dev: 1058 fail_dev:
974 rtnl_unlock(); 1059 rtnl_unlock();
975 ieee80211_wep_free(local); 1060 ieee80211_wep_free(local);
976fail_wep: 1061 fail_wep:
977 sta_info_stop(local); 1062 sta_info_stop(local);
978fail_sta_info: 1063 fail_sta_info:
979 debugfs_hw_del(local); 1064 debugfs_hw_del(local);
980 destroy_workqueue(local->hw.workqueue); 1065 destroy_workqueue(local->hw.workqueue);
981fail_workqueue: 1066 fail_workqueue:
982 if (local->mdev) 1067 if (local->mdev)
983 free_netdev(local->mdev); 1068 free_netdev(local->mdev);
984fail_mdev_alloc: 1069 fail_mdev_alloc:
985 wiphy_unregister(local->hw.wiphy); 1070 wiphy_unregister(local->hw.wiphy);
986fail_wiphy_register: 1071 fail_wiphy_register:
987 kfree(local->int_scan_req.channels); 1072 kfree(local->int_scan_req.channels);
988 return result; 1073 return result;
989} 1074}
@@ -996,6 +1081,9 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
996 tasklet_kill(&local->tx_pending_tasklet); 1081 tasklet_kill(&local->tx_pending_tasklet);
997 tasklet_kill(&local->tasklet); 1082 tasklet_kill(&local->tasklet);
998 1083
1084 pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
1085 &local->network_latency_notifier);
1086
999 rtnl_lock(); 1087 rtnl_lock();
1000 1088
1001 /* 1089 /*
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 132938b073dc..3610c11286bc 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -17,6 +17,8 @@
17#include <linux/if_arp.h> 17#include <linux/if_arp.h>
18#include <linux/etherdevice.h> 18#include <linux/etherdevice.h>
19#include <linux/rtnetlink.h> 19#include <linux/rtnetlink.h>
20#include <linux/pm_qos_params.h>
21#include <linux/crc32.h>
20#include <net/mac80211.h> 22#include <net/mac80211.h>
21#include <asm/unaligned.h> 23#include <asm/unaligned.h>
22 24
@@ -80,6 +82,89 @@ static int ieee80211_compatible_rates(struct ieee80211_bss *bss,
80 return count; 82 return count;
81} 83}
82 84
85/*
86 * ieee80211_enable_ht should be called only after the operating band
87 * has been determined as ht configuration depends on the hw's
88 * HT abilities for a specific band.
89 */
90static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
91 struct ieee80211_ht_info *hti,
92 u16 ap_ht_cap_flags)
93{
94 struct ieee80211_local *local = sdata->local;
95 struct ieee80211_supported_band *sband;
96 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
97 struct ieee80211_bss_ht_conf ht;
98 struct sta_info *sta;
99 u32 changed = 0;
100 bool enable_ht = true, ht_changed;
101 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
102
103 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
104
105 memset(&ht, 0, sizeof(ht));
106
107 /* HT is not supported */
108 if (!sband->ht_cap.ht_supported)
109 enable_ht = false;
110
111 /* check that channel matches the right operating channel */
112 if (local->hw.conf.channel->center_freq !=
113 ieee80211_channel_to_frequency(hti->control_chan))
114 enable_ht = false;
115
116 if (enable_ht) {
117 channel_type = NL80211_CHAN_HT20;
118
119 if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
120 (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
121 (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
122 switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
123 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
124 channel_type = NL80211_CHAN_HT40PLUS;
125 break;
126 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
127 channel_type = NL80211_CHAN_HT40MINUS;
128 break;
129 }
130 }
131 }
132
133 ht_changed = conf_is_ht(&local->hw.conf) != enable_ht ||
134 channel_type != local->hw.conf.channel_type;
135
136 local->oper_channel_type = channel_type;
137
138 if (ht_changed) {
139 /* channel_type change automatically detected */
140 ieee80211_hw_config(local, 0);
141
142 rcu_read_lock();
143
144 sta = sta_info_get(local, ifmgd->bssid);
145 if (sta)
146 rate_control_rate_update(local, sband, sta,
147 IEEE80211_RC_HT_CHANGED);
148
149 rcu_read_unlock();
150
151 }
152
153 /* disable HT */
154 if (!enable_ht)
155 return 0;
156
157 ht.operation_mode = le16_to_cpu(hti->operation_mode);
158
159 /* if bss configuration changed store the new one */
160 if (memcmp(&sdata->vif.bss_conf.ht, &ht, sizeof(ht))) {
161 changed |= BSS_CHANGED_HT;
162 sdata->vif.bss_conf.ht = ht;
163 }
164
165 return changed;
166}
167
83/* frame sending functions */ 168/* frame sending functions */
84 169
85static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) 170static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
@@ -325,6 +410,10 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
325 /* u.deauth.reason_code == u.disassoc.reason_code */ 410 /* u.deauth.reason_code == u.disassoc.reason_code */
326 mgmt->u.deauth.reason_code = cpu_to_le16(reason); 411 mgmt->u.deauth.reason_code = cpu_to_le16(reason);
327 412
413 if (stype == IEEE80211_STYPE_DEAUTH)
414 cfg80211_send_deauth(sdata->dev, (u8 *) mgmt, skb->len);
415 else
416 cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt, skb->len);
328 ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED); 417 ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED);
329} 418}
330 419
@@ -359,6 +448,166 @@ void ieee80211_send_pspoll(struct ieee80211_local *local,
359 ieee80211_tx_skb(sdata, skb, 0); 448 ieee80211_tx_skb(sdata, skb, 0);
360} 449}
361 450
451void ieee80211_send_nullfunc(struct ieee80211_local *local,
452 struct ieee80211_sub_if_data *sdata,
453 int powersave)
454{
455 struct sk_buff *skb;
456 struct ieee80211_hdr *nullfunc;
457 __le16 fc;
458
459 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
460 return;
461
462 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24);
463 if (!skb) {
464 printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc "
465 "frame\n", sdata->dev->name);
466 return;
467 }
468 skb_reserve(skb, local->hw.extra_tx_headroom);
469
470 nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
471 memset(nullfunc, 0, 24);
472 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
473 IEEE80211_FCTL_TODS);
474 if (powersave)
475 fc |= cpu_to_le16(IEEE80211_FCTL_PM);
476 nullfunc->frame_control = fc;
477 memcpy(nullfunc->addr1, sdata->u.mgd.bssid, ETH_ALEN);
478 memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN);
479 memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN);
480
481 ieee80211_tx_skb(sdata, skb, 0);
482}
483
484/* powersave */
485static void ieee80211_enable_ps(struct ieee80211_local *local,
486 struct ieee80211_sub_if_data *sdata)
487{
488 struct ieee80211_conf *conf = &local->hw.conf;
489
490 if (conf->dynamic_ps_timeout > 0 &&
491 !(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)) {
492 mod_timer(&local->dynamic_ps_timer, jiffies +
493 msecs_to_jiffies(conf->dynamic_ps_timeout));
494 } else {
495 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
496 ieee80211_send_nullfunc(local, sdata, 1);
497 conf->flags |= IEEE80211_CONF_PS;
498 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
499 }
500}
501
502static void ieee80211_change_ps(struct ieee80211_local *local)
503{
504 struct ieee80211_conf *conf = &local->hw.conf;
505
506 if (local->ps_sdata) {
507 if (!(local->ps_sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED))
508 return;
509
510 ieee80211_enable_ps(local, local->ps_sdata);
511 } else if (conf->flags & IEEE80211_CONF_PS) {
512 conf->flags &= ~IEEE80211_CONF_PS;
513 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
514 del_timer_sync(&local->dynamic_ps_timer);
515 cancel_work_sync(&local->dynamic_ps_enable_work);
516 }
517}
518
519/* need to hold RTNL or interface lock */
520void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
521{
522 struct ieee80211_sub_if_data *sdata, *found = NULL;
523 int count = 0;
524
525 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) {
526 local->ps_sdata = NULL;
527 return;
528 }
529
530 list_for_each_entry(sdata, &local->interfaces, list) {
531 if (!netif_running(sdata->dev))
532 continue;
533 if (sdata->vif.type != NL80211_IFTYPE_STATION)
534 continue;
535 found = sdata;
536 count++;
537 }
538
539 if (count == 1 && found->u.mgd.powersave) {
540 s32 beaconint_us;
541
542 if (latency < 0)
543 latency = pm_qos_requirement(PM_QOS_NETWORK_LATENCY);
544
545 beaconint_us = ieee80211_tu_to_usec(
546 found->vif.bss_conf.beacon_int);
547
548 if (beaconint_us > latency) {
549 local->ps_sdata = NULL;
550 } else {
551 u8 dtimper = found->vif.bss_conf.dtim_period;
552 int maxslp = 1;
553
554 if (dtimper > 1)
555 maxslp = min_t(int, dtimper,
556 latency / beaconint_us);
557
558 local->hw.conf.max_sleep_interval = maxslp;
559 local->ps_sdata = found;
560 }
561 } else {
562 local->ps_sdata = NULL;
563 }
564
565 ieee80211_change_ps(local);
566}
567
568void ieee80211_dynamic_ps_disable_work(struct work_struct *work)
569{
570 struct ieee80211_local *local =
571 container_of(work, struct ieee80211_local,
572 dynamic_ps_disable_work);
573
574 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
575 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
576 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
577 }
578
579 ieee80211_wake_queues_by_reason(&local->hw,
580 IEEE80211_QUEUE_STOP_REASON_PS);
581}
582
583void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
584{
585 struct ieee80211_local *local =
586 container_of(work, struct ieee80211_local,
587 dynamic_ps_enable_work);
588 struct ieee80211_sub_if_data *sdata = local->ps_sdata;
589
590 /* can only happen when PS was just disabled anyway */
591 if (!sdata)
592 return;
593
594 if (local->hw.conf.flags & IEEE80211_CONF_PS)
595 return;
596
597 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
598 ieee80211_send_nullfunc(local, sdata, 1);
599
600 local->hw.conf.flags |= IEEE80211_CONF_PS;
601 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
602}
603
604void ieee80211_dynamic_ps_timer(unsigned long data)
605{
606 struct ieee80211_local *local = (void *) data;
607
608 queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work);
609}
610
362/* MLME */ 611/* MLME */
363static void ieee80211_sta_wmm_params(struct ieee80211_local *local, 612static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
364 struct ieee80211_if_managed *ifmgd, 613 struct ieee80211_if_managed *ifmgd,
@@ -435,30 +684,6 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
435 } 684 }
436} 685}
437 686
438static bool ieee80211_check_tim(struct ieee802_11_elems *elems, u16 aid)
439{
440 u8 mask;
441 u8 index, indexn1, indexn2;
442 struct ieee80211_tim_ie *tim = (struct ieee80211_tim_ie *) elems->tim;
443
444 if (unlikely(!tim || elems->tim_len < 4))
445 return false;
446
447 aid &= 0x3fff;
448 index = aid / 8;
449 mask = 1 << (aid & 7);
450
451 indexn1 = tim->bitmap_ctrl & 0xfe;
452 indexn2 = elems->tim_len + indexn1 - 4;
453
454 if (index < indexn1 || index > indexn2)
455 return false;
456
457 index -= indexn1;
458
459 return !!(tim->virtual_map[index] & mask);
460}
461
462static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, 687static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
463 u16 capab, bool erp_valid, u8 erp) 688 u16 capab, bool erp_valid, u8 erp)
464{ 689{
@@ -634,18 +859,11 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
634 bss_info_changed |= BSS_CHANGED_BASIC_RATES; 859 bss_info_changed |= BSS_CHANGED_BASIC_RATES;
635 ieee80211_bss_info_change_notify(sdata, bss_info_changed); 860 ieee80211_bss_info_change_notify(sdata, bss_info_changed);
636 861
637 if (local->powersave) { 862 /* will be same as sdata */
638 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) && 863 if (local->ps_sdata) {
639 local->hw.conf.dynamic_ps_timeout > 0) { 864 mutex_lock(&local->iflist_mtx);
640 mod_timer(&local->dynamic_ps_timer, jiffies + 865 ieee80211_recalc_ps(local, -1);
641 msecs_to_jiffies( 866 mutex_unlock(&local->iflist_mtx);
642 local->hw.conf.dynamic_ps_timeout));
643 } else {
644 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
645 ieee80211_send_nullfunc(local, sdata, 1);
646 conf->flags |= IEEE80211_CONF_PS;
647 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
648 }
649 } 867 }
650 868
651 netif_tx_start_all_queues(sdata->dev); 869 netif_tx_start_all_queues(sdata->dev);
@@ -714,7 +932,7 @@ static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata)
714 " timed out\n", 932 " timed out\n",
715 sdata->dev->name, ifmgd->bssid); 933 sdata->dev->name, ifmgd->bssid);
716 ifmgd->state = IEEE80211_STA_MLME_DISABLED; 934 ifmgd->state = IEEE80211_STA_MLME_DISABLED;
717 ieee80211_sta_send_apinfo(sdata); 935 cfg80211_send_auth_timeout(sdata->dev, ifmgd->bssid);
718 ieee80211_rx_bss_remove(sdata, ifmgd->bssid, 936 ieee80211_rx_bss_remove(sdata, ifmgd->bssid,
719 sdata->local->hw.conf.channel->center_freq, 937 sdata->local->hw.conf.channel->center_freq,
720 ifmgd->ssid, ifmgd->ssid_len); 938 ifmgd->ssid, ifmgd->ssid_len);
@@ -897,7 +1115,7 @@ static void ieee80211_associate(struct ieee80211_sub_if_data *sdata)
897 " timed out\n", 1115 " timed out\n",
898 sdata->dev->name, ifmgd->bssid); 1116 sdata->dev->name, ifmgd->bssid);
899 ifmgd->state = IEEE80211_STA_MLME_DISABLED; 1117 ifmgd->state = IEEE80211_STA_MLME_DISABLED;
900 ieee80211_sta_send_apinfo(sdata); 1118 cfg80211_send_assoc_timeout(sdata->dev, ifmgd->bssid);
901 ieee80211_rx_bss_remove(sdata, ifmgd->bssid, 1119 ieee80211_rx_bss_remove(sdata, ifmgd->bssid,
902 sdata->local->hw.conf.channel->center_freq, 1120 sdata->local->hw.conf.channel->center_freq,
903 ifmgd->ssid, ifmgd->ssid_len); 1121 ifmgd->ssid, ifmgd->ssid_len);
@@ -1187,7 +1405,7 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1187 1405
1188 ieee80211_set_disassoc(sdata, true, false, 0); 1406 ieee80211_set_disassoc(sdata, true, false, 0);
1189 ifmgd->flags &= ~IEEE80211_STA_AUTHENTICATED; 1407 ifmgd->flags &= ~IEEE80211_STA_AUTHENTICATED;
1190 cfg80211_send_rx_deauth(sdata->dev, (u8 *) mgmt, len); 1408 cfg80211_send_deauth(sdata->dev, (u8 *) mgmt, len);
1191} 1409}
1192 1410
1193 1411
@@ -1218,7 +1436,7 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1218 } 1436 }
1219 1437
1220 ieee80211_set_disassoc(sdata, false, false, reason_code); 1438 ieee80211_set_disassoc(sdata, false, false, reason_code);
1221 cfg80211_send_rx_disassoc(sdata->dev, (u8 *) mgmt, len); 1439 cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt, len);
1222} 1440}
1223 1441
1224 1442
@@ -1287,6 +1505,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1287 * association next time. This works around some broken APs 1505 * association next time. This works around some broken APs
1288 * which do not correctly reject reassociation requests. */ 1506 * which do not correctly reject reassociation requests. */
1289 ifmgd->flags &= ~IEEE80211_STA_PREV_BSSID_SET; 1507 ifmgd->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
1508 cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, len);
1509 if (ifmgd->flags & IEEE80211_STA_EXT_SME) {
1510 /* Wait for SME to decide what to do next */
1511 ifmgd->state = IEEE80211_STA_MLME_DISABLED;
1512 }
1290 return; 1513 return;
1291 } 1514 }
1292 1515
@@ -1518,46 +1741,74 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1518 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; 1741 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
1519} 1742}
1520 1743
1744/*
1745 * This is the canonical list of information elements we care about,
1746 * the filter code also gives us all changes to the Microsoft OUI
1747 * (00:50:F2) vendor IE which is used for WMM which we need to track.
1748 *
1749 * We implement beacon filtering in software since that means we can
1750 * avoid processing the frame here and in cfg80211, and userspace
1751 * will not be able to tell whether the hardware supports it or not.
1752 *
1753 * XXX: This list needs to be dynamic -- userspace needs to be able to
1754 * add items it requires. It also needs to be able to tell us to
1755 * look out for other vendor IEs.
1756 */
1757static const u64 care_about_ies =
1758 (1ULL << WLAN_EID_COUNTRY) |
1759 (1ULL << WLAN_EID_ERP_INFO) |
1760 (1ULL << WLAN_EID_CHANNEL_SWITCH) |
1761 (1ULL << WLAN_EID_PWR_CONSTRAINT) |
1762 (1ULL << WLAN_EID_HT_CAPABILITY) |
1763 (1ULL << WLAN_EID_HT_INFORMATION);
1764
1521static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, 1765static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1522 struct ieee80211_mgmt *mgmt, 1766 struct ieee80211_mgmt *mgmt,
1523 size_t len, 1767 size_t len,
1524 struct ieee80211_rx_status *rx_status) 1768 struct ieee80211_rx_status *rx_status)
1525{ 1769{
1526 struct ieee80211_if_managed *ifmgd; 1770 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1527 size_t baselen; 1771 size_t baselen;
1528 struct ieee802_11_elems elems; 1772 struct ieee802_11_elems elems;
1529 struct ieee80211_local *local = sdata->local; 1773 struct ieee80211_local *local = sdata->local;
1530 u32 changed = 0; 1774 u32 changed = 0;
1531 bool erp_valid, directed_tim; 1775 bool erp_valid, directed_tim = false;
1532 u8 erp_value = 0; 1776 u8 erp_value = 0;
1777 u32 ncrc;
1533 1778
1534 /* Process beacon from the current BSS */ 1779 /* Process beacon from the current BSS */
1535 baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; 1780 baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
1536 if (baselen > len) 1781 if (baselen > len)
1537 return; 1782 return;
1538 1783
1539 ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); 1784 if (rx_status->freq != local->hw.conf.channel->center_freq)
1540
1541 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, true);
1542
1543 if (sdata->vif.type != NL80211_IFTYPE_STATION)
1544 return; 1785 return;
1545 1786
1546 ifmgd = &sdata->u.mgd;
1547
1548 if (!(ifmgd->flags & IEEE80211_STA_ASSOCIATED) || 1787 if (!(ifmgd->flags & IEEE80211_STA_ASSOCIATED) ||
1549 memcmp(ifmgd->bssid, mgmt->bssid, ETH_ALEN) != 0) 1788 memcmp(ifmgd->bssid, mgmt->bssid, ETH_ALEN) != 0)
1550 return; 1789 return;
1551 1790
1552 if (rx_status->freq != local->hw.conf.channel->center_freq) 1791 ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);
1792 ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable,
1793 len - baselen, &elems,
1794 care_about_ies, ncrc);
1795
1796 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
1797 directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len,
1798 ifmgd->aid);
1799
1800 ncrc = crc32_be(ncrc, (void *)&directed_tim, sizeof(directed_tim));
1801
1802 if (ncrc == ifmgd->beacon_crc)
1553 return; 1803 return;
1804 ifmgd->beacon_crc = ncrc;
1805
1806 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, true);
1554 1807
1555 ieee80211_sta_wmm_params(local, ifmgd, elems.wmm_param, 1808 ieee80211_sta_wmm_params(local, ifmgd, elems.wmm_param,
1556 elems.wmm_param_len); 1809 elems.wmm_param_len);
1557 1810
1558 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) { 1811 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) {
1559 directed_tim = ieee80211_check_tim(&elems, ifmgd->aid);
1560
1561 if (directed_tim) { 1812 if (directed_tim) {
1562 if (local->hw.conf.dynamic_ps_timeout > 0) { 1813 if (local->hw.conf.dynamic_ps_timeout > 0) {
1563 local->hw.conf.flags &= ~IEEE80211_CONF_PS; 1814 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
@@ -1930,6 +2181,7 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
1930void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) 2181void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
1931{ 2182{
1932 struct ieee80211_if_managed *ifmgd; 2183 struct ieee80211_if_managed *ifmgd;
2184 u32 hw_flags;
1933 2185
1934 ifmgd = &sdata->u.mgd; 2186 ifmgd = &sdata->u.mgd;
1935 INIT_WORK(&ifmgd->work, ieee80211_sta_work); 2187 INIT_WORK(&ifmgd->work, ieee80211_sta_work);
@@ -1949,6 +2201,13 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
1949 IEEE80211_STA_AUTO_CHANNEL_SEL; 2201 IEEE80211_STA_AUTO_CHANNEL_SEL;
1950 if (sdata->local->hw.queues >= 4) 2202 if (sdata->local->hw.queues >= 4)
1951 ifmgd->flags |= IEEE80211_STA_WMM_ENABLED; 2203 ifmgd->flags |= IEEE80211_STA_WMM_ENABLED;
2204
2205 hw_flags = sdata->local->hw.flags;
2206
2207 if (hw_flags & IEEE80211_HW_SUPPORTS_PS) {
2208 ifmgd->powersave = CONFIG_MAC80211_DEFAULT_PS_VALUE;
2209 sdata->local->hw.conf.dynamic_ps_timeout = 500;
2210 }
1952} 2211}
1953 2212
1954/* configuration hooks */ 2213/* configuration hooks */
@@ -2068,9 +2327,6 @@ int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason
2068 printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n", 2327 printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n",
2069 sdata->dev->name, reason); 2328 sdata->dev->name, reason);
2070 2329
2071 if (sdata->vif.type != NL80211_IFTYPE_STATION)
2072 return -EINVAL;
2073
2074 ieee80211_set_disassoc(sdata, true, true, reason); 2330 ieee80211_set_disassoc(sdata, true, true, reason);
2075 return 0; 2331 return 0;
2076} 2332}
@@ -2082,9 +2338,6 @@ int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason)
2082 printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n", 2338 printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n",
2083 sdata->dev->name, reason); 2339 sdata->dev->name, reason);
2084 2340
2085 if (sdata->vif.type != NL80211_IFTYPE_STATION)
2086 return -EINVAL;
2087
2088 if (!(ifmgd->flags & IEEE80211_STA_ASSOCIATED)) 2341 if (!(ifmgd->flags & IEEE80211_STA_ASSOCIATED))
2089 return -ENOLINK; 2342 return -ENOLINK;
2090 2343
@@ -2104,75 +2357,17 @@ void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local)
2104 rcu_read_unlock(); 2357 rcu_read_unlock();
2105} 2358}
2106 2359
2107void ieee80211_dynamic_ps_disable_work(struct work_struct *work) 2360int ieee80211_max_network_latency(struct notifier_block *nb,
2361 unsigned long data, void *dummy)
2108{ 2362{
2363 s32 latency_usec = (s32) data;
2109 struct ieee80211_local *local = 2364 struct ieee80211_local *local =
2110 container_of(work, struct ieee80211_local, 2365 container_of(nb, struct ieee80211_local,
2111 dynamic_ps_disable_work); 2366 network_latency_notifier);
2112 2367
2113 if (local->hw.conf.flags & IEEE80211_CONF_PS) { 2368 mutex_lock(&local->iflist_mtx);
2114 local->hw.conf.flags &= ~IEEE80211_CONF_PS; 2369 ieee80211_recalc_ps(local, latency_usec);
2115 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 2370 mutex_unlock(&local->iflist_mtx);
2116 }
2117
2118 ieee80211_wake_queues_by_reason(&local->hw,
2119 IEEE80211_QUEUE_STOP_REASON_PS);
2120}
2121
2122void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
2123{
2124 struct ieee80211_local *local =
2125 container_of(work, struct ieee80211_local,
2126 dynamic_ps_enable_work);
2127 /* XXX: using scan_sdata is completely broken! */
2128 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
2129
2130 if (local->hw.conf.flags & IEEE80211_CONF_PS)
2131 return;
2132
2133 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK && sdata)
2134 ieee80211_send_nullfunc(local, sdata, 1);
2135
2136 local->hw.conf.flags |= IEEE80211_CONF_PS;
2137 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
2138}
2139 2371
2140void ieee80211_dynamic_ps_timer(unsigned long data) 2372 return 0;
2141{
2142 struct ieee80211_local *local = (void *) data;
2143
2144 queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work);
2145}
2146
2147void ieee80211_send_nullfunc(struct ieee80211_local *local,
2148 struct ieee80211_sub_if_data *sdata,
2149 int powersave)
2150{
2151 struct sk_buff *skb;
2152 struct ieee80211_hdr *nullfunc;
2153 __le16 fc;
2154
2155 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
2156 return;
2157
2158 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24);
2159 if (!skb) {
2160 printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc "
2161 "frame\n", sdata->dev->name);
2162 return;
2163 }
2164 skb_reserve(skb, local->hw.extra_tx_headroom);
2165
2166 nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
2167 memset(nullfunc, 0, 24);
2168 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
2169 IEEE80211_FCTL_TODS);
2170 if (powersave)
2171 fc |= cpu_to_le16(IEEE80211_FCTL_PM);
2172 nullfunc->frame_control = fc;
2173 memcpy(nullfunc->addr1, sdata->u.mgd.bssid, ETH_ALEN);
2174 memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN);
2175 memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN);
2176
2177 ieee80211_tx_skb(sdata, skb, 0);
2178} 2373}
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 81985d27cbda..b38986c9deef 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -72,119 +72,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
72 return 0; 72 return 0;
73} 73}
74 74
75int __ieee80211_resume(struct ieee80211_hw *hw) 75/*
76{ 76 * __ieee80211_resume() is a static inline which just calls
77 struct ieee80211_local *local = hw_to_local(hw); 77 * ieee80211_reconfig(), which is also needed for hardware
78 struct ieee80211_sub_if_data *sdata; 78 * hang/firmware failure/etc. recovery.
79 struct ieee80211_if_init_conf conf; 79 */
80 struct sta_info *sta;
81 unsigned long flags;
82 int res;
83
84 /* restart hardware */
85 if (local->open_count) {
86 res = local->ops->start(hw);
87
88 ieee80211_led_radio(local, hw->conf.radio_enabled);
89 }
90
91 /* add interfaces */
92 list_for_each_entry(sdata, &local->interfaces, list) {
93 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
94 sdata->vif.type != NL80211_IFTYPE_MONITOR &&
95 netif_running(sdata->dev)) {
96 conf.vif = &sdata->vif;
97 conf.type = sdata->vif.type;
98 conf.mac_addr = sdata->dev->dev_addr;
99 res = local->ops->add_interface(hw, &conf);
100 }
101 }
102
103 /* add STAs back */
104 if (local->ops->sta_notify) {
105 spin_lock_irqsave(&local->sta_lock, flags);
106 list_for_each_entry(sta, &local->sta_list, list) {
107 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
108 sdata = container_of(sdata->bss,
109 struct ieee80211_sub_if_data,
110 u.ap);
111
112 local->ops->sta_notify(hw, &sdata->vif,
113 STA_NOTIFY_ADD, &sta->sta);
114 }
115 spin_unlock_irqrestore(&local->sta_lock, flags);
116 }
117
118 /* Clear Suspend state so that ADDBA requests can be processed */
119
120 rcu_read_lock();
121
122 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
123 list_for_each_entry_rcu(sta, &local->sta_list, list) {
124 clear_sta_flags(sta, WLAN_STA_SUSPEND);
125 }
126 }
127
128 rcu_read_unlock();
129
130 /* add back keys */
131 list_for_each_entry(sdata, &local->interfaces, list)
132 if (netif_running(sdata->dev))
133 ieee80211_enable_keys(sdata);
134
135 /* setup RTS threshold */
136 if (local->ops->set_rts_threshold)
137 local->ops->set_rts_threshold(hw, local->rts_threshold);
138
139 /* reconfigure hardware */
140 ieee80211_hw_config(local, ~0);
141
142 netif_addr_lock_bh(local->mdev);
143 ieee80211_configure_filter(local);
144 netif_addr_unlock_bh(local->mdev);
145
146 /* Finally also reconfigure all the BSS information */
147 list_for_each_entry(sdata, &local->interfaces, list) {
148 u32 changed = ~0;
149 if (!netif_running(sdata->dev))
150 continue;
151 switch (sdata->vif.type) {
152 case NL80211_IFTYPE_STATION:
153 /* disable beacon change bits */
154 changed &= ~IEEE80211_IFCC_BEACON;
155 /* fall through */
156 case NL80211_IFTYPE_ADHOC:
157 case NL80211_IFTYPE_AP:
158 case NL80211_IFTYPE_MESH_POINT:
159 /*
160 * Driver's config_interface can fail if rfkill is
161 * enabled. Accommodate this return code.
162 * FIXME: When mac80211 has knowledge of rfkill
163 * state the code below can change back to:
164 * WARN(ieee80211_if_config(sdata, changed));
165 * ieee80211_bss_info_change_notify(sdata, ~0);
166 */
167 if (ieee80211_if_config(sdata, changed))
168 printk(KERN_DEBUG "%s: failed to configure interface during resume\n",
169 sdata->dev->name);
170 else
171 ieee80211_bss_info_change_notify(sdata, ~0);
172 break;
173 case NL80211_IFTYPE_WDS:
174 break;
175 case NL80211_IFTYPE_AP_VLAN:
176 case NL80211_IFTYPE_MONITOR:
177 /* ignore virtual */
178 break;
179 case NL80211_IFTYPE_UNSPECIFIED:
180 case __NL80211_IFTYPE_AFTER_LAST:
181 WARN_ON(1);
182 break;
183 }
184 }
185
186 ieee80211_wake_queues_by_reason(hw,
187 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
188
189 return 0;
190}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 9776f73c51ad..a5afb79dab6e 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1932,7 +1932,7 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev,
1932 !ieee80211_is_auth(hdr->frame_control)) 1932 !ieee80211_is_auth(hdr->frame_control))
1933 goto ignore; 1933 goto ignore;
1934 1934
1935 mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr); 1935 mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr, NULL);
1936 ignore: 1936 ignore:
1937 dev_kfree_skb(rx->skb); 1937 dev_kfree_skb(rx->skb);
1938 rx->skb = NULL; 1938 rx->skb = NULL;
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 3bf9839f5916..f25b07feabf9 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -253,7 +253,7 @@ static void ieee80211_scan_ps_disable(struct ieee80211_sub_if_data *sdata)
253{ 253{
254 struct ieee80211_local *local = sdata->local; 254 struct ieee80211_local *local = sdata->local;
255 255
256 if (!local->powersave) 256 if (!local->ps_sdata)
257 ieee80211_send_nullfunc(local, sdata, 0); 257 ieee80211_send_nullfunc(local, sdata, 0);
258 else { 258 else {
259 /* 259 /*
@@ -285,12 +285,16 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
285 if (WARN_ON(!local->scan_req)) 285 if (WARN_ON(!local->scan_req))
286 return; 286 return;
287 287
288 if (local->hw_scanning) {
289 kfree(local->scan_req->ie);
290 local->scan_req->ie = local->orig_ies;
291 local->scan_req->ie_len = local->orig_ies_len;
292 }
293
288 if (local->scan_req != &local->int_scan_req) 294 if (local->scan_req != &local->int_scan_req)
289 cfg80211_scan_done(local->scan_req, aborted); 295 cfg80211_scan_done(local->scan_req, aborted);
290 local->scan_req = NULL; 296 local->scan_req = NULL;
291 297
292 local->last_scan_completed = jiffies;
293
294 if (local->hw_scanning) { 298 if (local->hw_scanning) {
295 local->hw_scanning = false; 299 local->hw_scanning = false;
296 /* 300 /*
@@ -457,12 +461,28 @@ int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
457 } 461 }
458 462
459 if (local->ops->hw_scan) { 463 if (local->ops->hw_scan) {
460 int rc; 464 u8 *ies;
465 int rc, ielen;
466
467 ies = kmalloc(2 + IEEE80211_MAX_SSID_LEN +
468 local->scan_ies_len + req->ie_len, GFP_KERNEL);
469 if (!ies)
470 return -ENOMEM;
471
472 ielen = ieee80211_build_preq_ies(local, ies,
473 req->ie, req->ie_len);
474 local->orig_ies = req->ie;
475 local->orig_ies_len = req->ie_len;
476 req->ie = ies;
477 req->ie_len = ielen;
461 478
462 local->hw_scanning = true; 479 local->hw_scanning = true;
463 rc = local->ops->hw_scan(local_to_hw(local), req); 480 rc = local->ops->hw_scan(local_to_hw(local), req);
464 if (rc) { 481 if (rc) {
465 local->hw_scanning = false; 482 local->hw_scanning = false;
483 kfree(ies);
484 req->ie_len = local->orig_ies_len;
485 req->ie = local->orig_ies;
466 return rc; 486 return rc;
467 } 487 }
468 local->scan_sdata = scan_sdata; 488 local->scan_sdata = scan_sdata;
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
index 5f7a2624ed74..48bf78e7fa7a 100644
--- a/net/mac80211/spectmgmt.c
+++ b/net/mac80211/spectmgmt.c
@@ -15,7 +15,7 @@
15 */ 15 */
16 16
17#include <linux/ieee80211.h> 17#include <linux/ieee80211.h>
18#include <net/wireless.h> 18#include <net/cfg80211.h>
19#include <net/mac80211.h> 19#include <net/mac80211.h>
20#include "ieee80211_i.h" 20#include "ieee80211_i.h"
21#include "sta_info.h" 21#include "sta_info.h"
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index c5f14e6bbde2..654a8e963ccb 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -686,41 +686,10 @@ static void sta_info_debugfs_add_work(struct work_struct *work)
686} 686}
687#endif 687#endif
688 688
689static void __ieee80211_run_pending_flush(struct ieee80211_local *local)
690{
691 struct sta_info *sta;
692 unsigned long flags;
693
694 ASSERT_RTNL();
695
696 spin_lock_irqsave(&local->sta_lock, flags);
697 while (!list_empty(&local->sta_flush_list)) {
698 sta = list_first_entry(&local->sta_flush_list,
699 struct sta_info, list);
700 list_del(&sta->list);
701 spin_unlock_irqrestore(&local->sta_lock, flags);
702 sta_info_destroy(sta);
703 spin_lock_irqsave(&local->sta_lock, flags);
704 }
705 spin_unlock_irqrestore(&local->sta_lock, flags);
706}
707
708static void ieee80211_sta_flush_work(struct work_struct *work)
709{
710 struct ieee80211_local *local =
711 container_of(work, struct ieee80211_local, sta_flush_work);
712
713 rtnl_lock();
714 __ieee80211_run_pending_flush(local);
715 rtnl_unlock();
716}
717
718void sta_info_init(struct ieee80211_local *local) 689void sta_info_init(struct ieee80211_local *local)
719{ 690{
720 spin_lock_init(&local->sta_lock); 691 spin_lock_init(&local->sta_lock);
721 INIT_LIST_HEAD(&local->sta_list); 692 INIT_LIST_HEAD(&local->sta_list);
722 INIT_LIST_HEAD(&local->sta_flush_list);
723 INIT_WORK(&local->sta_flush_work, ieee80211_sta_flush_work);
724 693
725 setup_timer(&local->sta_cleanup, sta_info_cleanup, 694 setup_timer(&local->sta_cleanup, sta_info_cleanup,
726 (unsigned long)local); 695 (unsigned long)local);
@@ -741,7 +710,6 @@ int sta_info_start(struct ieee80211_local *local)
741void sta_info_stop(struct ieee80211_local *local) 710void sta_info_stop(struct ieee80211_local *local)
742{ 711{
743 del_timer(&local->sta_cleanup); 712 del_timer(&local->sta_cleanup);
744 cancel_work_sync(&local->sta_flush_work);
745#ifdef CONFIG_MAC80211_DEBUGFS 713#ifdef CONFIG_MAC80211_DEBUGFS
746 /* 714 /*
747 * Make sure the debugfs adding work isn't pending after this 715 * Make sure the debugfs adding work isn't pending after this
@@ -752,10 +720,7 @@ void sta_info_stop(struct ieee80211_local *local)
752 cancel_work_sync(&local->sta_debugfs_add); 720 cancel_work_sync(&local->sta_debugfs_add);
753#endif 721#endif
754 722
755 rtnl_lock();
756 sta_info_flush(local, NULL); 723 sta_info_flush(local, NULL);
757 __ieee80211_run_pending_flush(local);
758 rtnl_unlock();
759} 724}
760 725
761/** 726/**
@@ -767,7 +732,7 @@ void sta_info_stop(struct ieee80211_local *local)
767 * @sdata: matching rule for the net device (sta->dev) or %NULL to match all STAs 732 * @sdata: matching rule for the net device (sta->dev) or %NULL to match all STAs
768 */ 733 */
769int sta_info_flush(struct ieee80211_local *local, 734int sta_info_flush(struct ieee80211_local *local,
770 struct ieee80211_sub_if_data *sdata) 735 struct ieee80211_sub_if_data *sdata)
771{ 736{
772 struct sta_info *sta, *tmp; 737 struct sta_info *sta, *tmp;
773 LIST_HEAD(tmp_list); 738 LIST_HEAD(tmp_list);
@@ -775,7 +740,6 @@ int sta_info_flush(struct ieee80211_local *local,
775 unsigned long flags; 740 unsigned long flags;
776 741
777 might_sleep(); 742 might_sleep();
778 ASSERT_RTNL();
779 743
780 spin_lock_irqsave(&local->sta_lock, flags); 744 spin_lock_irqsave(&local->sta_lock, flags);
781 list_for_each_entry_safe(sta, tmp, &local->sta_list, list) { 745 list_for_each_entry_safe(sta, tmp, &local->sta_list, list) {
@@ -795,39 +759,6 @@ int sta_info_flush(struct ieee80211_local *local,
795 return ret; 759 return ret;
796} 760}
797 761
798/**
799 * sta_info_flush_delayed - flush matching STA entries from the STA table
800 *
801 * This function unlinks all stations for a given interface and queues
802 * them for freeing. Note that the workqueue function scheduled here has
803 * to run before any new keys can be added to the system to avoid set_key()
804 * callback ordering issues.
805 *
806 * @sdata: the interface
807 */
808void sta_info_flush_delayed(struct ieee80211_sub_if_data *sdata)
809{
810 struct ieee80211_local *local = sdata->local;
811 struct sta_info *sta, *tmp;
812 unsigned long flags;
813 bool work = false;
814
815 spin_lock_irqsave(&local->sta_lock, flags);
816 list_for_each_entry_safe(sta, tmp, &local->sta_list, list) {
817 if (sdata == sta->sdata) {
818 __sta_info_unlink(&sta);
819 if (sta) {
820 list_add_tail(&sta->list,
821 &local->sta_flush_list);
822 work = true;
823 }
824 }
825 }
826 if (work)
827 schedule_work(&local->sta_flush_work);
828 spin_unlock_irqrestore(&local->sta_lock, flags);
829}
830
831void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, 762void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
832 unsigned long exp_time) 763 unsigned long exp_time)
833{ 764{
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 5534d489f506..31a8990ce401 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -442,8 +442,7 @@ void sta_info_init(struct ieee80211_local *local);
442int sta_info_start(struct ieee80211_local *local); 442int sta_info_start(struct ieee80211_local *local);
443void sta_info_stop(struct ieee80211_local *local); 443void sta_info_stop(struct ieee80211_local *local);
444int sta_info_flush(struct ieee80211_local *local, 444int sta_info_flush(struct ieee80211_local *local,
445 struct ieee80211_sub_if_data *sdata); 445 struct ieee80211_sub_if_data *sdata);
446void sta_info_flush_delayed(struct ieee80211_sub_if_data *sdata);
447void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, 446void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
448 unsigned long exp_time); 447 unsigned long exp_time);
449 448
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 3fb04a86444d..1865622003c9 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -409,8 +409,24 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
409 sta->sta.addr); 409 sta->sta.addr);
410 } 410 }
411#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 411#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
412 clear_sta_flags(sta, WLAN_STA_PSPOLL); 412 if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL)) {
413 /*
414 * The sleeping station with pending data is now snoozing.
415 * It queried us for its buffered frames and will go back
416 * to deep sleep once it got everything.
417 *
418 * inform the driver, in case the hardware does powersave
419 * frame filtering and keeps a station blacklist on its own
420 * (e.g: p54), so that frames can be delivered unimpeded.
421 *
422 * Note: It should be save to disable the filter now.
423 * As, it is really unlikely that we still have any pending
424 * frame for this station in the hw's buffers/fifos left,
425 * that is not rejected with a unsuccessful tx_status yet.
426 */
413 427
428 info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
429 }
414 return TX_CONTINUE; 430 return TX_CONTINUE;
415} 431}
416 432
@@ -429,7 +445,7 @@ ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx)
429static ieee80211_tx_result debug_noinline 445static ieee80211_tx_result debug_noinline
430ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) 446ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
431{ 447{
432 struct ieee80211_key *key; 448 struct ieee80211_key *key = NULL;
433 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); 449 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
434 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; 450 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
435 451
@@ -500,7 +516,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
500 sband = tx->local->hw.wiphy->bands[tx->channel->band]; 516 sband = tx->local->hw.wiphy->bands[tx->channel->band];
501 517
502 len = min_t(int, tx->skb->len + FCS_LEN, 518 len = min_t(int, tx->skb->len + FCS_LEN,
503 tx->local->fragmentation_threshold); 519 tx->local->hw.wiphy->frag_threshold);
504 520
505 /* set up the tx rate control struct we give the RC algo */ 521 /* set up the tx rate control struct we give the RC algo */
506 txrc.hw = local_to_hw(tx->local); 522 txrc.hw = local_to_hw(tx->local);
@@ -511,8 +527,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
511 txrc.max_rate_idx = tx->sdata->max_ratectrl_rateidx; 527 txrc.max_rate_idx = tx->sdata->max_ratectrl_rateidx;
512 528
513 /* set up RTS protection if desired */ 529 /* set up RTS protection if desired */
514 if (tx->local->rts_threshold < IEEE80211_MAX_RTS_THRESHOLD && 530 if (len > tx->local->hw.wiphy->rts_threshold) {
515 len > tx->local->rts_threshold) {
516 txrc.rts = rts = true; 531 txrc.rts = rts = true;
517 } 532 }
518 533
@@ -754,7 +769,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
754 struct sk_buff *skb = tx->skb; 769 struct sk_buff *skb = tx->skb;
755 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 770 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
756 struct ieee80211_hdr *hdr = (void *)skb->data; 771 struct ieee80211_hdr *hdr = (void *)skb->data;
757 int frag_threshold = tx->local->fragmentation_threshold; 772 int frag_threshold = tx->local->hw.wiphy->frag_threshold;
758 int hdrlen; 773 int hdrlen;
759 int fragnum; 774 int fragnum;
760 775
@@ -1072,7 +1087,7 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
1072 1087
1073 if (tx->flags & IEEE80211_TX_FRAGMENTED) { 1088 if (tx->flags & IEEE80211_TX_FRAGMENTED) {
1074 if ((tx->flags & IEEE80211_TX_UNICAST) && 1089 if ((tx->flags & IEEE80211_TX_UNICAST) &&
1075 skb->len + FCS_LEN > local->fragmentation_threshold && 1090 skb->len + FCS_LEN > local->hw.wiphy->frag_threshold &&
1076 !(info->flags & IEEE80211_TX_CTL_AMPDU)) 1091 !(info->flags & IEEE80211_TX_CTL_AMPDU))
1077 tx->flags |= IEEE80211_TX_FRAGMENTED; 1092 tx->flags |= IEEE80211_TX_FRAGMENTED;
1078 else 1093 else
@@ -2086,18 +2101,18 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
2086 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { 2101 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
2087 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 2102 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
2088 struct ieee80211_hdr *hdr; 2103 struct ieee80211_hdr *hdr;
2104 struct sk_buff *presp = rcu_dereference(ifibss->presp);
2089 2105
2090 if (!ifibss->probe_resp) 2106 if (!presp)
2091 goto out; 2107 goto out;
2092 2108
2093 skb = skb_copy(ifibss->probe_resp, GFP_ATOMIC); 2109 skb = skb_copy(presp, GFP_ATOMIC);
2094 if (!skb) 2110 if (!skb)
2095 goto out; 2111 goto out;
2096 2112
2097 hdr = (struct ieee80211_hdr *) skb->data; 2113 hdr = (struct ieee80211_hdr *) skb->data;
2098 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 2114 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2099 IEEE80211_STYPE_BEACON); 2115 IEEE80211_STYPE_BEACON);
2100
2101 } else if (ieee80211_vif_is_mesh(&sdata->vif)) { 2116 } else if (ieee80211_vif_is_mesh(&sdata->vif)) {
2102 struct ieee80211_mgmt *mgmt; 2117 struct ieee80211_mgmt *mgmt;
2103 u8 *pos; 2118 u8 *pos;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index fdf432f14554..61876eb50b49 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -20,6 +20,7 @@
20#include <linux/if_arp.h> 20#include <linux/if_arp.h>
21#include <linux/wireless.h> 21#include <linux/wireless.h>
22#include <linux/bitmap.h> 22#include <linux/bitmap.h>
23#include <linux/crc32.h>
23#include <net/net_namespace.h> 24#include <net/net_namespace.h>
24#include <net/cfg80211.h> 25#include <net/cfg80211.h>
25#include <net/rtnetlink.h> 26#include <net/rtnetlink.h>
@@ -28,6 +29,7 @@
28#include "rate.h" 29#include "rate.h"
29#include "mesh.h" 30#include "mesh.h"
30#include "wme.h" 31#include "wme.h"
32#include "led.h"
31 33
32/* privid for wiphys to determine whether they belong to us or not */ 34/* privid for wiphys to determine whether they belong to us or not */
33void *mac80211_wiphy_privid = &mac80211_wiphy_privid; 35void *mac80211_wiphy_privid = &mac80211_wiphy_privid;
@@ -536,8 +538,16 @@ EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
536void ieee802_11_parse_elems(u8 *start, size_t len, 538void ieee802_11_parse_elems(u8 *start, size_t len,
537 struct ieee802_11_elems *elems) 539 struct ieee802_11_elems *elems)
538{ 540{
541 ieee802_11_parse_elems_crc(start, len, elems, 0, 0);
542}
543
544u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
545 struct ieee802_11_elems *elems,
546 u64 filter, u32 crc)
547{
539 size_t left = len; 548 size_t left = len;
540 u8 *pos = start; 549 u8 *pos = start;
550 bool calc_crc = filter != 0;
541 551
542 memset(elems, 0, sizeof(*elems)); 552 memset(elems, 0, sizeof(*elems));
543 elems->ie_start = start; 553 elems->ie_start = start;
@@ -551,7 +561,10 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
551 left -= 2; 561 left -= 2;
552 562
553 if (elen > left) 563 if (elen > left)
554 return; 564 break;
565
566 if (calc_crc && id < 64 && (filter & BIT(id)))
567 crc = crc32_be(crc, pos - 2, elen + 2);
555 568
556 switch (id) { 569 switch (id) {
557 case WLAN_EID_SSID: 570 case WLAN_EID_SSID:
@@ -575,8 +588,10 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
575 elems->cf_params_len = elen; 588 elems->cf_params_len = elen;
576 break; 589 break;
577 case WLAN_EID_TIM: 590 case WLAN_EID_TIM:
578 elems->tim = pos; 591 if (elen >= sizeof(struct ieee80211_tim_ie)) {
579 elems->tim_len = elen; 592 elems->tim = (void *)pos;
593 elems->tim_len = elen;
594 }
580 break; 595 break;
581 case WLAN_EID_IBSS_PARAMS: 596 case WLAN_EID_IBSS_PARAMS:
582 elems->ibss_params = pos; 597 elems->ibss_params = pos;
@@ -586,15 +601,20 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
586 elems->challenge = pos; 601 elems->challenge = pos;
587 elems->challenge_len = elen; 602 elems->challenge_len = elen;
588 break; 603 break;
589 case WLAN_EID_WPA: 604 case WLAN_EID_VENDOR_SPECIFIC:
590 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 && 605 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
591 pos[2] == 0xf2) { 606 pos[2] == 0xf2) {
592 /* Microsoft OUI (00:50:F2) */ 607 /* Microsoft OUI (00:50:F2) */
608
609 if (calc_crc)
610 crc = crc32_be(crc, pos - 2, elen + 2);
611
593 if (pos[3] == 1) { 612 if (pos[3] == 1) {
594 /* OUI Type 1 - WPA IE */ 613 /* OUI Type 1 - WPA IE */
595 elems->wpa = pos; 614 elems->wpa = pos;
596 elems->wpa_len = elen; 615 elems->wpa_len = elen;
597 } else if (elen >= 5 && pos[3] == 2) { 616 } else if (elen >= 5 && pos[3] == 2) {
617 /* OUI Type 2 - WMM IE */
598 if (pos[4] == 0) { 618 if (pos[4] == 0) {
599 elems->wmm_info = pos; 619 elems->wmm_info = pos;
600 elems->wmm_info_len = elen; 620 elems->wmm_info_len = elen;
@@ -679,6 +699,8 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
679 left -= elen; 699 left -= elen;
680 pos += elen; 700 pos += elen;
681 } 701 }
702
703 return crc;
682} 704}
683 705
684void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata) 706void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
@@ -831,16 +853,73 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
831 ieee80211_tx_skb(sdata, skb, encrypt); 853 ieee80211_tx_skb(sdata, skb, encrypt);
832} 854}
833 855
856int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
857 const u8 *ie, size_t ie_len)
858{
859 struct ieee80211_supported_band *sband;
860 u8 *pos, *supp_rates_len, *esupp_rates_len = NULL;
861 int i;
862
863 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
864
865 pos = buffer;
866
867 *pos++ = WLAN_EID_SUPP_RATES;
868 supp_rates_len = pos;
869 *pos++ = 0;
870
871 for (i = 0; i < sband->n_bitrates; i++) {
872 struct ieee80211_rate *rate = &sband->bitrates[i];
873
874 if (esupp_rates_len) {
875 *esupp_rates_len += 1;
876 } else if (*supp_rates_len == 8) {
877 *pos++ = WLAN_EID_EXT_SUPP_RATES;
878 esupp_rates_len = pos;
879 *pos++ = 1;
880 } else
881 *supp_rates_len += 1;
882
883 *pos++ = rate->bitrate / 5;
884 }
885
886 if (sband->ht_cap.ht_supported) {
887 __le16 tmp = cpu_to_le16(sband->ht_cap.cap);
888
889 *pos++ = WLAN_EID_HT_CAPABILITY;
890 *pos++ = sizeof(struct ieee80211_ht_cap);
891 memset(pos, 0, sizeof(struct ieee80211_ht_cap));
892 memcpy(pos, &tmp, sizeof(u16));
893 pos += sizeof(u16);
894 /* TODO: needs a define here for << 2 */
895 *pos++ = sband->ht_cap.ampdu_factor |
896 (sband->ht_cap.ampdu_density << 2);
897 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
898 pos += sizeof(sband->ht_cap.mcs);
899 pos += 2 + 4 + 1; /* ext info, BF cap, antsel */
900 }
901
902 /*
903 * If adding more here, adjust code in main.c
904 * that calculates local->scan_ies_len.
905 */
906
907 if (ie) {
908 memcpy(pos, ie, ie_len);
909 pos += ie_len;
910 }
911
912 return pos - buffer;
913}
914
834void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, 915void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
835 u8 *ssid, size_t ssid_len, 916 const u8 *ssid, size_t ssid_len,
836 u8 *ie, size_t ie_len) 917 const u8 *ie, size_t ie_len)
837{ 918{
838 struct ieee80211_local *local = sdata->local; 919 struct ieee80211_local *local = sdata->local;
839 struct ieee80211_supported_band *sband;
840 struct sk_buff *skb; 920 struct sk_buff *skb;
841 struct ieee80211_mgmt *mgmt; 921 struct ieee80211_mgmt *mgmt;
842 u8 *pos, *supp_rates, *esupp_rates = NULL; 922 u8 *pos;
843 int i;
844 923
845 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 + 924 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 +
846 ie_len); 925 ie_len);
@@ -867,31 +946,9 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
867 *pos++ = WLAN_EID_SSID; 946 *pos++ = WLAN_EID_SSID;
868 *pos++ = ssid_len; 947 *pos++ = ssid_len;
869 memcpy(pos, ssid, ssid_len); 948 memcpy(pos, ssid, ssid_len);
949 pos += ssid_len;
870 950
871 supp_rates = skb_put(skb, 2); 951 skb_put(skb, ieee80211_build_preq_ies(local, pos, ie, ie_len));
872 supp_rates[0] = WLAN_EID_SUPP_RATES;
873 supp_rates[1] = 0;
874 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
875
876 for (i = 0; i < sband->n_bitrates; i++) {
877 struct ieee80211_rate *rate = &sband->bitrates[i];
878 if (esupp_rates) {
879 pos = skb_put(skb, 1);
880 esupp_rates[1]++;
881 } else if (supp_rates[1] == 8) {
882 esupp_rates = skb_put(skb, 3);
883 esupp_rates[0] = WLAN_EID_EXT_SUPP_RATES;
884 esupp_rates[1] = 1;
885 pos = &esupp_rates[2];
886 } else {
887 pos = skb_put(skb, 1);
888 supp_rates[1]++;
889 }
890 *pos = rate->bitrate / 5;
891 }
892
893 if (ie)
894 memcpy(skb_put(skb, ie_len), ie, ie_len);
895 952
896 ieee80211_tx_skb(sdata, skb, 0); 953 ieee80211_tx_skb(sdata, skb, 0);
897} 954}
@@ -931,3 +988,120 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
931 } 988 }
932 return supp_rates; 989 return supp_rates;
933} 990}
991
992int ieee80211_reconfig(struct ieee80211_local *local)
993{
994 struct ieee80211_hw *hw = &local->hw;
995 struct ieee80211_sub_if_data *sdata;
996 struct ieee80211_if_init_conf conf;
997 struct sta_info *sta;
998 unsigned long flags;
999 int res;
1000
1001 /* restart hardware */
1002 if (local->open_count) {
1003 res = local->ops->start(hw);
1004
1005 ieee80211_led_radio(local, hw->conf.radio_enabled);
1006 }
1007
1008 /* add interfaces */
1009 list_for_each_entry(sdata, &local->interfaces, list) {
1010 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
1011 sdata->vif.type != NL80211_IFTYPE_MONITOR &&
1012 netif_running(sdata->dev)) {
1013 conf.vif = &sdata->vif;
1014 conf.type = sdata->vif.type;
1015 conf.mac_addr = sdata->dev->dev_addr;
1016 res = local->ops->add_interface(hw, &conf);
1017 }
1018 }
1019
1020 /* add STAs back */
1021 if (local->ops->sta_notify) {
1022 spin_lock_irqsave(&local->sta_lock, flags);
1023 list_for_each_entry(sta, &local->sta_list, list) {
1024 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1025 sdata = container_of(sdata->bss,
1026 struct ieee80211_sub_if_data,
1027 u.ap);
1028
1029 local->ops->sta_notify(hw, &sdata->vif,
1030 STA_NOTIFY_ADD, &sta->sta);
1031 }
1032 spin_unlock_irqrestore(&local->sta_lock, flags);
1033 }
1034
1035 /* Clear Suspend state so that ADDBA requests can be processed */
1036
1037 rcu_read_lock();
1038
1039 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
1040 list_for_each_entry_rcu(sta, &local->sta_list, list) {
1041 clear_sta_flags(sta, WLAN_STA_SUSPEND);
1042 }
1043 }
1044
1045 rcu_read_unlock();
1046
1047 /* setup RTS threshold */
1048 if (local->ops->set_rts_threshold)
1049 local->ops->set_rts_threshold(hw, hw->wiphy->rts_threshold);
1050
1051 /* reconfigure hardware */
1052 ieee80211_hw_config(local, ~0);
1053
1054 netif_addr_lock_bh(local->mdev);
1055 ieee80211_configure_filter(local);
1056 netif_addr_unlock_bh(local->mdev);
1057
1058 /* Finally also reconfigure all the BSS information */
1059 list_for_each_entry(sdata, &local->interfaces, list) {
1060 u32 changed = ~0;
1061 if (!netif_running(sdata->dev))
1062 continue;
1063 switch (sdata->vif.type) {
1064 case NL80211_IFTYPE_STATION:
1065 /* disable beacon change bits */
1066 changed &= ~IEEE80211_IFCC_BEACON;
1067 /* fall through */
1068 case NL80211_IFTYPE_ADHOC:
1069 case NL80211_IFTYPE_AP:
1070 case NL80211_IFTYPE_MESH_POINT:
1071 /*
1072 * Driver's config_interface can fail if rfkill is
1073 * enabled. Accommodate this return code.
1074 * FIXME: When mac80211 has knowledge of rfkill
1075 * state the code below can change back to:
1076 * WARN(ieee80211_if_config(sdata, changed));
1077 * ieee80211_bss_info_change_notify(sdata, ~0);
1078 */
1079 if (ieee80211_if_config(sdata, changed))
1080 printk(KERN_DEBUG "%s: failed to configure interface during resume\n",
1081 sdata->dev->name);
1082 else
1083 ieee80211_bss_info_change_notify(sdata, ~0);
1084 break;
1085 case NL80211_IFTYPE_WDS:
1086 break;
1087 case NL80211_IFTYPE_AP_VLAN:
1088 case NL80211_IFTYPE_MONITOR:
1089 /* ignore virtual */
1090 break;
1091 case NL80211_IFTYPE_UNSPECIFIED:
1092 case __NL80211_IFTYPE_AFTER_LAST:
1093 WARN_ON(1);
1094 break;
1095 }
1096 }
1097
1098 /* add back keys */
1099 list_for_each_entry(sdata, &local->interfaces, list)
1100 if (netif_running(sdata->dev))
1101 ieee80211_enable_keys(sdata);
1102
1103 ieee80211_wake_queues_by_reason(hw,
1104 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
1105
1106 return 0;
1107}
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 959aa8379ccf..1a649da42c41 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -149,17 +149,14 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev,
149 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 149 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
150 150
151 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 151 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
152 sdata->u.ibss.flags &= ~IEEE80211_IBSS_AUTO_CHANNEL_SEL; 152 return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
153 else if (sdata->vif.type == NL80211_IFTYPE_STATION) 153 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
154 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL; 154 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL;
155 155
156 /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */ 156 /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
157 if (freq->e == 0) { 157 if (freq->e == 0) {
158 if (freq->m < 0) { 158 if (freq->m < 0) {
159 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 159 if (sdata->vif.type == NL80211_IFTYPE_STATION)
160 sdata->u.ibss.flags |=
161 IEEE80211_IBSS_AUTO_CHANNEL_SEL;
162 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
163 sdata->u.mgd.flags |= 160 sdata->u.mgd.flags |=
164 IEEE80211_STA_AUTO_CHANNEL_SEL; 161 IEEE80211_STA_AUTO_CHANNEL_SEL;
165 return 0; 162 return 0;
@@ -183,6 +180,10 @@ static int ieee80211_ioctl_giwfreq(struct net_device *dev,
183 struct iw_freq *freq, char *extra) 180 struct iw_freq *freq, char *extra)
184{ 181{
185 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 182 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
183 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
184
185 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
186 return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
186 187
187 freq->m = local->hw.conf.channel->center_freq; 188 freq->m = local->hw.conf.channel->center_freq;
188 freq->e = 6; 189 freq->e = 6;
@@ -195,15 +196,17 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
195 struct iw_request_info *info, 196 struct iw_request_info *info,
196 struct iw_point *data, char *ssid) 197 struct iw_point *data, char *ssid)
197{ 198{
198 struct ieee80211_sub_if_data *sdata; 199 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
199 size_t len = data->length; 200 size_t len = data->length;
200 int ret; 201 int ret;
201 202
203 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
204 return cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
205
202 /* iwconfig uses nul termination in SSID.. */ 206 /* iwconfig uses nul termination in SSID.. */
203 if (len > 0 && ssid[len - 1] == '\0') 207 if (len > 0 && ssid[len - 1] == '\0')
204 len--; 208 len--;
205 209
206 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
207 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 210 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
208 if (data->flags) 211 if (data->flags)
209 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL; 212 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
@@ -217,8 +220,7 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
217 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME; 220 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
218 ieee80211_sta_req_auth(sdata); 221 ieee80211_sta_req_auth(sdata);
219 return 0; 222 return 0;
220 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 223 }
221 return ieee80211_ibss_set_ssid(sdata, ssid, len);
222 224
223 return -EOPNOTSUPP; 225 return -EOPNOTSUPP;
224} 226}
@@ -229,9 +231,13 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev,
229 struct iw_point *data, char *ssid) 231 struct iw_point *data, char *ssid)
230{ 232{
231 size_t len; 233 size_t len;
232
233 struct ieee80211_sub_if_data *sdata; 234 struct ieee80211_sub_if_data *sdata;
235
234 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 236 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
237
238 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
239 return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
240
235 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 241 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
236 int res = ieee80211_sta_get_ssid(sdata, ssid, &len); 242 int res = ieee80211_sta_get_ssid(sdata, ssid, &len);
237 if (res == 0) { 243 if (res == 0) {
@@ -240,14 +246,6 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev,
240 } else 246 } else
241 data->flags = 0; 247 data->flags = 0;
242 return res; 248 return res;
243 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
244 int res = ieee80211_ibss_get_ssid(sdata, ssid, &len);
245 if (res == 0) {
246 data->length = len;
247 data->flags = 1;
248 } else
249 data->flags = 0;
250 return res;
251 } 249 }
252 250
253 return -EOPNOTSUPP; 251 return -EOPNOTSUPP;
@@ -258,9 +256,11 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
258 struct iw_request_info *info, 256 struct iw_request_info *info,
259 struct sockaddr *ap_addr, char *extra) 257 struct sockaddr *ap_addr, char *extra)
260{ 258{
261 struct ieee80211_sub_if_data *sdata; 259 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
260
261 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
262 return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
262 263
263 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
264 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 264 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
265 int ret; 265 int ret;
266 266
@@ -277,16 +277,6 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
277 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME; 277 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
278 ieee80211_sta_req_auth(sdata); 278 ieee80211_sta_req_auth(sdata);
279 return 0; 279 return 0;
280 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
281 if (is_zero_ether_addr((u8 *) &ap_addr->sa_data))
282 sdata->u.ibss.flags |= IEEE80211_IBSS_AUTO_BSSID_SEL |
283 IEEE80211_IBSS_AUTO_CHANNEL_SEL;
284 else if (is_broadcast_ether_addr((u8 *) &ap_addr->sa_data))
285 sdata->u.ibss.flags |= IEEE80211_IBSS_AUTO_BSSID_SEL;
286 else
287 sdata->u.ibss.flags &= ~IEEE80211_IBSS_AUTO_BSSID_SEL;
288
289 return ieee80211_ibss_set_bssid(sdata, (u8 *) &ap_addr->sa_data);
290 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) { 280 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
291 /* 281 /*
292 * If it is necessary to update the WDS peer address 282 * If it is necessary to update the WDS peer address
@@ -312,9 +302,11 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
312 struct iw_request_info *info, 302 struct iw_request_info *info,
313 struct sockaddr *ap_addr, char *extra) 303 struct sockaddr *ap_addr, char *extra)
314{ 304{
315 struct ieee80211_sub_if_data *sdata; 305 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
306
307 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
308 return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
316 309
317 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
318 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 310 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
319 if (sdata->u.mgd.state == IEEE80211_STA_MLME_ASSOCIATED) { 311 if (sdata->u.mgd.state == IEEE80211_STA_MLME_ASSOCIATED) {
320 ap_addr->sa_family = ARPHRD_ETHER; 312 ap_addr->sa_family = ARPHRD_ETHER;
@@ -322,13 +314,6 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
322 } else 314 } else
323 memset(&ap_addr->sa_data, 0, ETH_ALEN); 315 memset(&ap_addr->sa_data, 0, ETH_ALEN);
324 return 0; 316 return 0;
325 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
326 if (sdata->u.ibss.state == IEEE80211_IBSS_MLME_JOINED) {
327 ap_addr->sa_family = ARPHRD_ETHER;
328 memcpy(&ap_addr->sa_data, sdata->u.ibss.bssid, ETH_ALEN);
329 } else
330 memset(&ap_addr->sa_data, 0, ETH_ALEN);
331 return 0;
332 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) { 317 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
333 ap_addr->sa_family = ARPHRD_ETHER; 318 ap_addr->sa_family = ARPHRD_ETHER;
334 memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN); 319 memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN);
@@ -487,155 +472,6 @@ static int ieee80211_ioctl_giwtxpower(struct net_device *dev,
487 return 0; 472 return 0;
488} 473}
489 474
490static int ieee80211_ioctl_siwrts(struct net_device *dev,
491 struct iw_request_info *info,
492 struct iw_param *rts, char *extra)
493{
494 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
495
496 if (rts->disabled)
497 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
498 else if (!rts->fixed)
499 /* if the rts value is not fixed, then take default */
500 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
501 else if (rts->value < 0 || rts->value > IEEE80211_MAX_RTS_THRESHOLD)
502 return -EINVAL;
503 else
504 local->rts_threshold = rts->value;
505
506 /* If the wlan card performs RTS/CTS in hardware/firmware,
507 * configure it here */
508
509 if (local->ops->set_rts_threshold)
510 local->ops->set_rts_threshold(local_to_hw(local),
511 local->rts_threshold);
512
513 return 0;
514}
515
516static int ieee80211_ioctl_giwrts(struct net_device *dev,
517 struct iw_request_info *info,
518 struct iw_param *rts, char *extra)
519{
520 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
521
522 rts->value = local->rts_threshold;
523 rts->disabled = (rts->value >= IEEE80211_MAX_RTS_THRESHOLD);
524 rts->fixed = 1;
525
526 return 0;
527}
528
529
530static int ieee80211_ioctl_siwfrag(struct net_device *dev,
531 struct iw_request_info *info,
532 struct iw_param *frag, char *extra)
533{
534 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
535
536 if (frag->disabled)
537 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
538 else if (!frag->fixed)
539 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
540 else if (frag->value < 256 ||
541 frag->value > IEEE80211_MAX_FRAG_THRESHOLD)
542 return -EINVAL;
543 else {
544 /* Fragment length must be even, so strip LSB. */
545 local->fragmentation_threshold = frag->value & ~0x1;
546 }
547
548 return 0;
549}
550
551static int ieee80211_ioctl_giwfrag(struct net_device *dev,
552 struct iw_request_info *info,
553 struct iw_param *frag, char *extra)
554{
555 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
556
557 frag->value = local->fragmentation_threshold;
558 frag->disabled = (frag->value >= IEEE80211_MAX_FRAG_THRESHOLD);
559 frag->fixed = 1;
560
561 return 0;
562}
563
564
565static int ieee80211_ioctl_siwretry(struct net_device *dev,
566 struct iw_request_info *info,
567 struct iw_param *retry, char *extra)
568{
569 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
570
571 if (retry->disabled ||
572 (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
573 return -EINVAL;
574
575 if (retry->flags & IW_RETRY_MAX) {
576 local->hw.conf.long_frame_max_tx_count = retry->value;
577 } else if (retry->flags & IW_RETRY_MIN) {
578 local->hw.conf.short_frame_max_tx_count = retry->value;
579 } else {
580 local->hw.conf.long_frame_max_tx_count = retry->value;
581 local->hw.conf.short_frame_max_tx_count = retry->value;
582 }
583
584 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);
585
586 return 0;
587}
588
589
590static int ieee80211_ioctl_giwretry(struct net_device *dev,
591 struct iw_request_info *info,
592 struct iw_param *retry, char *extra)
593{
594 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
595
596 retry->disabled = 0;
597 if (retry->flags == 0 || retry->flags & IW_RETRY_MIN) {
598 /* first return min value, iwconfig will ask max value
599 * later if needed */
600 retry->flags |= IW_RETRY_LIMIT;
601 retry->value = local->hw.conf.short_frame_max_tx_count;
602 if (local->hw.conf.long_frame_max_tx_count !=
603 local->hw.conf.short_frame_max_tx_count)
604 retry->flags |= IW_RETRY_MIN;
605 return 0;
606 }
607 if (retry->flags & IW_RETRY_MAX) {
608 retry->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
609 retry->value = local->hw.conf.long_frame_max_tx_count;
610 }
611
612 return 0;
613}
614
615static int ieee80211_ioctl_siwmlme(struct net_device *dev,
616 struct iw_request_info *info,
617 struct iw_point *data, char *extra)
618{
619 struct ieee80211_sub_if_data *sdata;
620 struct iw_mlme *mlme = (struct iw_mlme *) extra;
621
622 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
623 if (!(sdata->vif.type == NL80211_IFTYPE_STATION))
624 return -EINVAL;
625
626 switch (mlme->cmd) {
627 case IW_MLME_DEAUTH:
628 /* TODO: mlme->addr.sa_data */
629 return ieee80211_sta_deauthenticate(sdata, mlme->reason_code);
630 case IW_MLME_DISASSOC:
631 /* TODO: mlme->addr.sa_data */
632 return ieee80211_sta_disassociate(sdata, mlme->reason_code);
633 default:
634 return -EOPNOTSUPP;
635 }
636}
637
638
639static int ieee80211_ioctl_siwencode(struct net_device *dev, 475static int ieee80211_ioctl_siwencode(struct net_device *dev,
640 struct iw_request_info *info, 476 struct iw_request_info *info,
641 struct iw_point *erq, char *keybuf) 477 struct iw_point *erq, char *keybuf)
@@ -675,7 +511,7 @@ static int ieee80211_ioctl_siwencode(struct net_device *dev,
675 !sdata->default_key, 511 !sdata->default_key,
676 keybuf, erq->length); 512 keybuf, erq->length);
677 513
678 if (!ret) { 514 if (!ret && sdata->vif.type == NL80211_IFTYPE_STATION) {
679 if (remove) 515 if (remove)
680 sdata->u.mgd.flags &= ~IEEE80211_STA_TKIP_WEP_USED; 516 sdata->u.mgd.flags &= ~IEEE80211_STA_TKIP_WEP_USED;
681 else 517 else
@@ -747,7 +583,7 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev,
747 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 583 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
748 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 584 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
749 struct ieee80211_conf *conf = &local->hw.conf; 585 struct ieee80211_conf *conf = &local->hw.conf;
750 int ret = 0, timeout = 0; 586 int timeout = 0;
751 bool ps; 587 bool ps;
752 588
753 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) 589 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
@@ -779,42 +615,18 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev,
779 timeout = wrq->value / 1000; 615 timeout = wrq->value / 1000;
780 616
781 set: 617 set:
782 if (ps == local->powersave && timeout == conf->dynamic_ps_timeout) 618 if (ps == sdata->u.mgd.powersave && timeout == conf->dynamic_ps_timeout)
783 return ret; 619 return 0;
784 620
785 local->powersave = ps; 621 sdata->u.mgd.powersave = ps;
786 conf->dynamic_ps_timeout = timeout; 622 conf->dynamic_ps_timeout = timeout;
787 623
788 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) 624 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
789 ret = ieee80211_hw_config(local, 625 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
790 IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT);
791 626
792 if (!(sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED)) 627 ieee80211_recalc_ps(local, -1);
793 return ret;
794 628
795 if (conf->dynamic_ps_timeout > 0 && 629 return 0;
796 !(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)) {
797 mod_timer(&local->dynamic_ps_timer, jiffies +
798 msecs_to_jiffies(conf->dynamic_ps_timeout));
799 } else {
800 if (local->powersave) {
801 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
802 ieee80211_send_nullfunc(local, sdata, 1);
803 conf->flags |= IEEE80211_CONF_PS;
804 ret = ieee80211_hw_config(local,
805 IEEE80211_CONF_CHANGE_PS);
806 } else {
807 conf->flags &= ~IEEE80211_CONF_PS;
808 ret = ieee80211_hw_config(local,
809 IEEE80211_CONF_CHANGE_PS);
810 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
811 ieee80211_send_nullfunc(local, sdata, 0);
812 del_timer_sync(&local->dynamic_ps_timer);
813 cancel_work_sync(&local->dynamic_ps_enable_work);
814 }
815 }
816
817 return ret;
818} 630}
819 631
820static int ieee80211_ioctl_giwpower(struct net_device *dev, 632static int ieee80211_ioctl_giwpower(struct net_device *dev,
@@ -822,9 +634,9 @@ static int ieee80211_ioctl_giwpower(struct net_device *dev,
822 union iwreq_data *wrqu, 634 union iwreq_data *wrqu,
823 char *extra) 635 char *extra)
824{ 636{
825 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 637 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
826 638
827 wrqu->power.disabled = !local->powersave; 639 wrqu->power.disabled = !sdata->u.mgd.powersave;
828 640
829 return 0; 641 return 0;
830} 642}
@@ -1099,7 +911,7 @@ static const iw_handler ieee80211_handler[] =
1099 (iw_handler) NULL, /* SIOCGIWTHRSPY */ 911 (iw_handler) NULL, /* SIOCGIWTHRSPY */
1100 (iw_handler) ieee80211_ioctl_siwap, /* SIOCSIWAP */ 912 (iw_handler) ieee80211_ioctl_siwap, /* SIOCSIWAP */
1101 (iw_handler) ieee80211_ioctl_giwap, /* SIOCGIWAP */ 913 (iw_handler) ieee80211_ioctl_giwap, /* SIOCGIWAP */
1102 (iw_handler) ieee80211_ioctl_siwmlme, /* SIOCSIWMLME */ 914 (iw_handler) cfg80211_wext_siwmlme, /* SIOCSIWMLME */
1103 (iw_handler) NULL, /* SIOCGIWAPLIST */ 915 (iw_handler) NULL, /* SIOCGIWAPLIST */
1104 (iw_handler) cfg80211_wext_siwscan, /* SIOCSIWSCAN */ 916 (iw_handler) cfg80211_wext_siwscan, /* SIOCSIWSCAN */
1105 (iw_handler) cfg80211_wext_giwscan, /* SIOCGIWSCAN */ 917 (iw_handler) cfg80211_wext_giwscan, /* SIOCGIWSCAN */
@@ -1111,14 +923,14 @@ static const iw_handler ieee80211_handler[] =
1111 (iw_handler) NULL, /* -- hole -- */ 923 (iw_handler) NULL, /* -- hole -- */
1112 (iw_handler) ieee80211_ioctl_siwrate, /* SIOCSIWRATE */ 924 (iw_handler) ieee80211_ioctl_siwrate, /* SIOCSIWRATE */
1113 (iw_handler) ieee80211_ioctl_giwrate, /* SIOCGIWRATE */ 925 (iw_handler) ieee80211_ioctl_giwrate, /* SIOCGIWRATE */
1114 (iw_handler) ieee80211_ioctl_siwrts, /* SIOCSIWRTS */ 926 (iw_handler) cfg80211_wext_siwrts, /* SIOCSIWRTS */
1115 (iw_handler) ieee80211_ioctl_giwrts, /* SIOCGIWRTS */ 927 (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */
1116 (iw_handler) ieee80211_ioctl_siwfrag, /* SIOCSIWFRAG */ 928 (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */
1117 (iw_handler) ieee80211_ioctl_giwfrag, /* SIOCGIWFRAG */ 929 (iw_handler) cfg80211_wext_giwfrag, /* SIOCGIWFRAG */
1118 (iw_handler) ieee80211_ioctl_siwtxpower, /* SIOCSIWTXPOW */ 930 (iw_handler) ieee80211_ioctl_siwtxpower, /* SIOCSIWTXPOW */
1119 (iw_handler) ieee80211_ioctl_giwtxpower, /* SIOCGIWTXPOW */ 931 (iw_handler) ieee80211_ioctl_giwtxpower, /* SIOCGIWTXPOW */
1120 (iw_handler) ieee80211_ioctl_siwretry, /* SIOCSIWRETRY */ 932 (iw_handler) cfg80211_wext_siwretry, /* SIOCSIWRETRY */
1121 (iw_handler) ieee80211_ioctl_giwretry, /* SIOCGIWRETRY */ 933 (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */
1122 (iw_handler) ieee80211_ioctl_siwencode, /* SIOCSIWENCODE */ 934 (iw_handler) ieee80211_ioctl_siwencode, /* SIOCSIWENCODE */
1123 (iw_handler) ieee80211_ioctl_giwencode, /* SIOCGIWENCODE */ 935 (iw_handler) ieee80211_ioctl_giwencode, /* SIOCGIWENCODE */
1124 (iw_handler) ieee80211_ioctl_siwpower, /* SIOCSIWPOWER */ 936 (iw_handler) ieee80211_ioctl_siwpower, /* SIOCSIWPOWER */
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 4f8bfea278f2..dcfae8884b86 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -122,7 +122,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
122 return RX_DROP_UNUSABLE; 122 return RX_DROP_UNUSABLE;
123 123
124 mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx, 124 mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx,
125 (void *) skb->data); 125 (void *) skb->data, NULL);
126 return RX_DROP_UNUSABLE; 126 return RX_DROP_UNUSABLE;
127 } 127 }
128 128
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index 20cf16fc572f..b11e7e527864 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -35,7 +35,6 @@
35#include <linux/kernel.h> 35#include <linux/kernel.h>
36#include <linux/in.h> 36#include <linux/in.h>
37#include <linux/poll.h> 37#include <linux/poll.h>
38#include <linux/version.h>
39#include <net/sock.h> 38#include <net/sock.h>
40 39
41#include "rds.h" 40#include "rds.h"
diff --git a/net/rds/connection.c b/net/rds/connection.c
index 273f064930a8..d14445c48304 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -148,14 +148,12 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr,
148 if (conn) 148 if (conn)
149 goto out; 149 goto out;
150 150
151 conn = kmem_cache_alloc(rds_conn_slab, gfp); 151 conn = kmem_cache_zalloc(rds_conn_slab, gfp);
152 if (conn == NULL) { 152 if (conn == NULL) {
153 conn = ERR_PTR(-ENOMEM); 153 conn = ERR_PTR(-ENOMEM);
154 goto out; 154 goto out;
155 } 155 }
156 156
157 memset(conn, 0, sizeof(*conn));
158
159 INIT_HLIST_NODE(&conn->c_hash_node); 157 INIT_HLIST_NODE(&conn->c_hash_node);
160 conn->c_version = RDS_PROTOCOL_3_0; 158 conn->c_version = RDS_PROTOCOL_3_0;
161 conn->c_laddr = laddr; 159 conn->c_laddr = laddr;
diff --git a/net/rds/ib.c b/net/rds/ib.c
index 4933b380985e..b9bcd32431e1 100644
--- a/net/rds/ib.c
+++ b/net/rds/ib.c
@@ -224,8 +224,8 @@ static int rds_ib_laddr_check(__be32 addr)
224 * IB and iWARP capable NICs. 224 * IB and iWARP capable NICs.
225 */ 225 */
226 cm_id = rdma_create_id(NULL, NULL, RDMA_PS_TCP); 226 cm_id = rdma_create_id(NULL, NULL, RDMA_PS_TCP);
227 if (!cm_id) 227 if (IS_ERR(cm_id))
228 return -EADDRNOTAVAIL; 228 return PTR_ERR(cm_id);
229 229
230 memset(&sin, 0, sizeof(sin)); 230 memset(&sin, 0, sizeof(sin));
231 sin.sin_family = AF_INET; 231 sin.sin_family = AF_INET;
diff --git a/net/rds/ib.h b/net/rds/ib.h
index 069206cae733..455ae73047fe 100644
--- a/net/rds/ib.h
+++ b/net/rds/ib.h
@@ -333,7 +333,7 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op);
333void rds_ib_send_add_credits(struct rds_connection *conn, unsigned int credits); 333void rds_ib_send_add_credits(struct rds_connection *conn, unsigned int credits);
334void rds_ib_advertise_credits(struct rds_connection *conn, unsigned int posted); 334void rds_ib_advertise_credits(struct rds_connection *conn, unsigned int posted);
335int rds_ib_send_grab_credits(struct rds_ib_connection *ic, u32 wanted, 335int rds_ib_send_grab_credits(struct rds_ib_connection *ic, u32 wanted,
336 u32 *adv_credits, int need_posted); 336 u32 *adv_credits, int need_posted, int max_posted);
337 337
338/* ib_stats.c */ 338/* ib_stats.c */
339DECLARE_PER_CPU(struct rds_ib_statistics, rds_ib_stats); 339DECLARE_PER_CPU(struct rds_ib_statistics, rds_ib_stats);
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c
index 36d931573ff4..5709bad28329 100644
--- a/net/rds/ib_recv.c
+++ b/net/rds/ib_recv.c
@@ -524,7 +524,7 @@ void rds_ib_attempt_ack(struct rds_ib_connection *ic)
524 } 524 }
525 525
526 /* Can we get a send credit? */ 526 /* Can we get a send credit? */
527 if (!rds_ib_send_grab_credits(ic, 1, &adv_credits, 0)) { 527 if (!rds_ib_send_grab_credits(ic, 1, &adv_credits, 0, RDS_MAX_ADV_CREDIT)) {
528 rds_ib_stats_inc(s_ib_tx_throttle); 528 rds_ib_stats_inc(s_ib_tx_throttle);
529 clear_bit(IB_ACK_IN_FLIGHT, &ic->i_ack_flags); 529 clear_bit(IB_ACK_IN_FLIGHT, &ic->i_ack_flags);
530 return; 530 return;
diff --git a/net/rds/ib_ring.c b/net/rds/ib_ring.c
index 99a6ccae964c..ff97e8eda858 100644
--- a/net/rds/ib_ring.c
+++ b/net/rds/ib_ring.c
@@ -137,7 +137,7 @@ int rds_ib_ring_empty(struct rds_ib_work_ring *ring)
137 137
138int rds_ib_ring_low(struct rds_ib_work_ring *ring) 138int rds_ib_ring_low(struct rds_ib_work_ring *ring)
139{ 139{
140 return __rds_ib_ring_used(ring) <= (ring->w_nr >> 2); 140 return __rds_ib_ring_used(ring) <= (ring->w_nr >> 1);
141} 141}
142 142
143/* 143/*
diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c
index cb6c52cb1c4c..23bf830db2d5 100644
--- a/net/rds/ib_send.c
+++ b/net/rds/ib_send.c
@@ -311,7 +311,7 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context)
311 * and using atomic_cmpxchg when updating the two counters. 311 * and using atomic_cmpxchg when updating the two counters.
312 */ 312 */
313int rds_ib_send_grab_credits(struct rds_ib_connection *ic, 313int rds_ib_send_grab_credits(struct rds_ib_connection *ic,
314 u32 wanted, u32 *adv_credits, int need_posted) 314 u32 wanted, u32 *adv_credits, int need_posted, int max_posted)
315{ 315{
316 unsigned int avail, posted, got = 0, advertise; 316 unsigned int avail, posted, got = 0, advertise;
317 long oldval, newval; 317 long oldval, newval;
@@ -351,7 +351,7 @@ try_again:
351 * available. 351 * available.
352 */ 352 */
353 if (posted && (got || need_posted)) { 353 if (posted && (got || need_posted)) {
354 advertise = min_t(unsigned int, posted, RDS_MAX_ADV_CREDIT); 354 advertise = min_t(unsigned int, posted, max_posted);
355 newval -= IB_SET_POST_CREDITS(advertise); 355 newval -= IB_SET_POST_CREDITS(advertise);
356 } 356 }
357 357
@@ -498,7 +498,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm,
498 498
499 credit_alloc = work_alloc; 499 credit_alloc = work_alloc;
500 if (ic->i_flowctl) { 500 if (ic->i_flowctl) {
501 credit_alloc = rds_ib_send_grab_credits(ic, work_alloc, &posted, 0); 501 credit_alloc = rds_ib_send_grab_credits(ic, work_alloc, &posted, 0, RDS_MAX_ADV_CREDIT);
502 adv_credits += posted; 502 adv_credits += posted;
503 if (credit_alloc < work_alloc) { 503 if (credit_alloc < work_alloc) {
504 rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc - credit_alloc); 504 rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc - credit_alloc);
@@ -506,7 +506,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm,
506 flow_controlled++; 506 flow_controlled++;
507 } 507 }
508 if (work_alloc == 0) { 508 if (work_alloc == 0) {
509 rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc); 509 set_bit(RDS_LL_SEND_FULL, &conn->c_flags);
510 rds_ib_stats_inc(s_ib_tx_throttle); 510 rds_ib_stats_inc(s_ib_tx_throttle);
511 ret = -ENOMEM; 511 ret = -ENOMEM;
512 goto out; 512 goto out;
@@ -571,7 +571,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm,
571 /* 571 /*
572 * Update adv_credits since we reset the ACK_REQUIRED bit. 572 * Update adv_credits since we reset the ACK_REQUIRED bit.
573 */ 573 */
574 rds_ib_send_grab_credits(ic, 0, &posted, 1); 574 rds_ib_send_grab_credits(ic, 0, &posted, 1, RDS_MAX_ADV_CREDIT - adv_credits);
575 adv_credits += posted; 575 adv_credits += posted;
576 BUG_ON(adv_credits > 255); 576 BUG_ON(adv_credits > 255);
577 } else if (ic->i_rm != rm) 577 } else if (ic->i_rm != rm)
diff --git a/net/rds/info.c b/net/rds/info.c
index 1d885535214d..62aeef37aefe 100644
--- a/net/rds/info.c
+++ b/net/rds/info.c
@@ -188,10 +188,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval,
188 ret = -ENOMEM; 188 ret = -ENOMEM;
189 goto out; 189 goto out;
190 } 190 }
191 down_read(&current->mm->mmap_sem); 191 ret = get_user_pages_fast(start, nr_pages, 1, pages);
192 ret = get_user_pages(current, current->mm, start, nr_pages, 1, 0,
193 pages, NULL);
194 up_read(&current->mm->mmap_sem);
195 if (ret != nr_pages) { 192 if (ret != nr_pages) {
196 if (ret > 0) 193 if (ret > 0)
197 nr_pages = ret; 194 nr_pages = ret;
diff --git a/net/rds/iw.c b/net/rds/iw.c
index b732efb5b634..d16e1cbc8e83 100644
--- a/net/rds/iw.c
+++ b/net/rds/iw.c
@@ -233,8 +233,8 @@ static int rds_iw_laddr_check(__be32 addr)
233 * IB and iWARP capable NICs. 233 * IB and iWARP capable NICs.
234 */ 234 */
235 cm_id = rdma_create_id(NULL, NULL, RDMA_PS_TCP); 235 cm_id = rdma_create_id(NULL, NULL, RDMA_PS_TCP);
236 if (!cm_id) 236 if (IS_ERR(cm_id))
237 return -EADDRNOTAVAIL; 237 return PTR_ERR(cm_id);
238 238
239 memset(&sin, 0, sizeof(sin)); 239 memset(&sin, 0, sizeof(sin));
240 sin.sin_family = AF_INET; 240 sin.sin_family = AF_INET;
diff --git a/net/rds/iw.h b/net/rds/iw.h
index b4fb27252895..0715dde323e7 100644
--- a/net/rds/iw.h
+++ b/net/rds/iw.h
@@ -361,7 +361,7 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op);
361void rds_iw_send_add_credits(struct rds_connection *conn, unsigned int credits); 361void rds_iw_send_add_credits(struct rds_connection *conn, unsigned int credits);
362void rds_iw_advertise_credits(struct rds_connection *conn, unsigned int posted); 362void rds_iw_advertise_credits(struct rds_connection *conn, unsigned int posted);
363int rds_iw_send_grab_credits(struct rds_iw_connection *ic, u32 wanted, 363int rds_iw_send_grab_credits(struct rds_iw_connection *ic, u32 wanted,
364 u32 *adv_credits, int need_posted); 364 u32 *adv_credits, int need_posted, int max_posted);
365 365
366/* ib_stats.c */ 366/* ib_stats.c */
367DECLARE_PER_CPU(struct rds_iw_statistics, rds_iw_stats); 367DECLARE_PER_CPU(struct rds_iw_statistics, rds_iw_stats);
diff --git a/net/rds/iw_recv.c b/net/rds/iw_recv.c
index fde470fa50d5..8683f5f66c4b 100644
--- a/net/rds/iw_recv.c
+++ b/net/rds/iw_recv.c
@@ -524,7 +524,7 @@ void rds_iw_attempt_ack(struct rds_iw_connection *ic)
524 } 524 }
525 525
526 /* Can we get a send credit? */ 526 /* Can we get a send credit? */
527 if (!rds_iw_send_grab_credits(ic, 1, &adv_credits, 0)) { 527 if (!rds_iw_send_grab_credits(ic, 1, &adv_credits, 0, RDS_MAX_ADV_CREDIT)) {
528 rds_iw_stats_inc(s_iw_tx_throttle); 528 rds_iw_stats_inc(s_iw_tx_throttle);
529 clear_bit(IB_ACK_IN_FLIGHT, &ic->i_ack_flags); 529 clear_bit(IB_ACK_IN_FLIGHT, &ic->i_ack_flags);
530 return; 530 return;
diff --git a/net/rds/iw_ring.c b/net/rds/iw_ring.c
index d422d4b5deef..da8e3b63f663 100644
--- a/net/rds/iw_ring.c
+++ b/net/rds/iw_ring.c
@@ -137,7 +137,7 @@ int rds_iw_ring_empty(struct rds_iw_work_ring *ring)
137 137
138int rds_iw_ring_low(struct rds_iw_work_ring *ring) 138int rds_iw_ring_low(struct rds_iw_work_ring *ring)
139{ 139{
140 return __rds_iw_ring_used(ring) <= (ring->w_nr >> 2); 140 return __rds_iw_ring_used(ring) <= (ring->w_nr >> 1);
141} 141}
142 142
143 143
diff --git a/net/rds/iw_send.c b/net/rds/iw_send.c
index 22dd38ffd608..44a6a0551f28 100644
--- a/net/rds/iw_send.c
+++ b/net/rds/iw_send.c
@@ -347,7 +347,7 @@ void rds_iw_send_cq_comp_handler(struct ib_cq *cq, void *context)
347 * and using atomic_cmpxchg when updating the two counters. 347 * and using atomic_cmpxchg when updating the two counters.
348 */ 348 */
349int rds_iw_send_grab_credits(struct rds_iw_connection *ic, 349int rds_iw_send_grab_credits(struct rds_iw_connection *ic,
350 u32 wanted, u32 *adv_credits, int need_posted) 350 u32 wanted, u32 *adv_credits, int need_posted, int max_posted)
351{ 351{
352 unsigned int avail, posted, got = 0, advertise; 352 unsigned int avail, posted, got = 0, advertise;
353 long oldval, newval; 353 long oldval, newval;
@@ -387,7 +387,7 @@ try_again:
387 * available. 387 * available.
388 */ 388 */
389 if (posted && (got || need_posted)) { 389 if (posted && (got || need_posted)) {
390 advertise = min_t(unsigned int, posted, RDS_MAX_ADV_CREDIT); 390 advertise = min_t(unsigned int, posted, max_posted);
391 newval -= IB_SET_POST_CREDITS(advertise); 391 newval -= IB_SET_POST_CREDITS(advertise);
392 } 392 }
393 393
@@ -541,7 +541,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm,
541 541
542 credit_alloc = work_alloc; 542 credit_alloc = work_alloc;
543 if (ic->i_flowctl) { 543 if (ic->i_flowctl) {
544 credit_alloc = rds_iw_send_grab_credits(ic, work_alloc, &posted, 0); 544 credit_alloc = rds_iw_send_grab_credits(ic, work_alloc, &posted, 0, RDS_MAX_ADV_CREDIT);
545 adv_credits += posted; 545 adv_credits += posted;
546 if (credit_alloc < work_alloc) { 546 if (credit_alloc < work_alloc) {
547 rds_iw_ring_unalloc(&ic->i_send_ring, work_alloc - credit_alloc); 547 rds_iw_ring_unalloc(&ic->i_send_ring, work_alloc - credit_alloc);
@@ -549,7 +549,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm,
549 flow_controlled++; 549 flow_controlled++;
550 } 550 }
551 if (work_alloc == 0) { 551 if (work_alloc == 0) {
552 rds_iw_ring_unalloc(&ic->i_send_ring, work_alloc); 552 set_bit(RDS_LL_SEND_FULL, &conn->c_flags);
553 rds_iw_stats_inc(s_iw_tx_throttle); 553 rds_iw_stats_inc(s_iw_tx_throttle);
554 ret = -ENOMEM; 554 ret = -ENOMEM;
555 goto out; 555 goto out;
@@ -614,7 +614,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm,
614 /* 614 /*
615 * Update adv_credits since we reset the ACK_REQUIRED bit. 615 * Update adv_credits since we reset the ACK_REQUIRED bit.
616 */ 616 */
617 rds_iw_send_grab_credits(ic, 0, &posted, 1); 617 rds_iw_send_grab_credits(ic, 0, &posted, 1, RDS_MAX_ADV_CREDIT - adv_credits);
618 adv_credits += posted; 618 adv_credits += posted;
619 BUG_ON(adv_credits > 255); 619 BUG_ON(adv_credits > 255);
620 } else if (ic->i_rm != rm) 620 } else if (ic->i_rm != rm)
diff --git a/net/rds/rdma.c b/net/rds/rdma.c
index eaeeb91e1119..8dc83d2caa58 100644
--- a/net/rds/rdma.c
+++ b/net/rds/rdma.c
@@ -150,12 +150,9 @@ static int rds_pin_pages(unsigned long user_addr, unsigned int nr_pages,
150{ 150{
151 int ret; 151 int ret;
152 152
153 down_read(&current->mm->mmap_sem); 153 ret = get_user_pages_fast(user_addr, nr_pages, write, pages);
154 ret = get_user_pages(current, current->mm, user_addr,
155 nr_pages, write, 0, pages, NULL);
156 up_read(&current->mm->mmap_sem);
157 154
158 if (0 <= ret && (unsigned) ret < nr_pages) { 155 if (ret >= 0 && ret < nr_pages) {
159 while (ret--) 156 while (ret--)
160 put_page(pages[ret]); 157 put_page(pages[ret]);
161 ret = -EFAULT; 158 ret = -EFAULT;
diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c
index 7b19024f9706..7d0f901c93d5 100644
--- a/net/rds/rdma_transport.c
+++ b/net/rds/rdma_transport.c
@@ -34,7 +34,7 @@
34 34
35#include "rdma_transport.h" 35#include "rdma_transport.h"
36 36
37static struct rdma_cm_id *rds_iw_listen_id; 37static struct rdma_cm_id *rds_rdma_listen_id;
38 38
39int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id, 39int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id,
40 struct rdma_cm_event *event) 40 struct rdma_cm_event *event)
@@ -161,7 +161,7 @@ static int __init rds_rdma_listen_init(void)
161 161
162 rdsdebug("cm %p listening on port %u\n", cm_id, RDS_PORT); 162 rdsdebug("cm %p listening on port %u\n", cm_id, RDS_PORT);
163 163
164 rds_iw_listen_id = cm_id; 164 rds_rdma_listen_id = cm_id;
165 cm_id = NULL; 165 cm_id = NULL;
166out: 166out:
167 if (cm_id) 167 if (cm_id)
@@ -171,10 +171,10 @@ out:
171 171
172static void rds_rdma_listen_stop(void) 172static void rds_rdma_listen_stop(void)
173{ 173{
174 if (rds_iw_listen_id) { 174 if (rds_rdma_listen_id) {
175 rdsdebug("cm %p\n", rds_iw_listen_id); 175 rdsdebug("cm %p\n", rds_rdma_listen_id);
176 rdma_destroy_id(rds_iw_listen_id); 176 rdma_destroy_id(rds_rdma_listen_id);
177 rds_iw_listen_id = NULL; 177 rds_rdma_listen_id = NULL;
178 } 178 }
179} 179}
180 180
diff --git a/net/rds/rds.h b/net/rds/rds.h
index 619f0a30a4e5..1f82ec0d2066 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -132,7 +132,7 @@ struct rds_connection {
132#define RDS_FLAG_CONG_BITMAP 0x01 132#define RDS_FLAG_CONG_BITMAP 0x01
133#define RDS_FLAG_ACK_REQUIRED 0x02 133#define RDS_FLAG_ACK_REQUIRED 0x02
134#define RDS_FLAG_RETRANSMITTED 0x04 134#define RDS_FLAG_RETRANSMITTED 0x04
135#define RDS_MAX_ADV_CREDIT 127 135#define RDS_MAX_ADV_CREDIT 255
136 136
137/* 137/*
138 * Maximum space available for extension headers. 138 * Maximum space available for extension headers.
diff --git a/net/rds/send.c b/net/rds/send.c
index 104fe033203d..a4a7f428cd76 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -854,11 +854,6 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
854 854
855 rm->m_daddr = daddr; 855 rm->m_daddr = daddr;
856 856
857 /* Parse any control messages the user may have included. */
858 ret = rds_cmsg_send(rs, rm, msg, &allocated_mr);
859 if (ret)
860 goto out;
861
862 /* rds_conn_create has a spinlock that runs with IRQ off. 857 /* rds_conn_create has a spinlock that runs with IRQ off.
863 * Caching the conn in the socket helps a lot. */ 858 * Caching the conn in the socket helps a lot. */
864 if (rs->rs_conn && rs->rs_conn->c_faddr == daddr) 859 if (rs->rs_conn && rs->rs_conn->c_faddr == daddr)
@@ -874,6 +869,11 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
874 rs->rs_conn = conn; 869 rs->rs_conn = conn;
875 } 870 }
876 871
872 /* Parse any control messages the user may have included. */
873 ret = rds_cmsg_send(rs, rm, msg, &allocated_mr);
874 if (ret)
875 goto out;
876
877 if ((rm->m_rdma_cookie || rm->m_rdma_op) 877 if ((rm->m_rdma_cookie || rm->m_rdma_op)
878 && conn->c_trans->xmit_rdma == NULL) { 878 && conn->c_trans->xmit_rdma == NULL) {
879 if (printk_ratelimit()) 879 if (printk_ratelimit())
diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c
index 84efde97c5a7..60a34f3b5f65 100644
--- a/net/rfkill/rfkill-input.c
+++ b/net/rfkill/rfkill-input.c
@@ -47,12 +47,6 @@ enum rfkill_global_sched_op {
47 RFKILL_GLOBAL_OP_UNBLOCK, 47 RFKILL_GLOBAL_OP_UNBLOCK,
48}; 48};
49 49
50/*
51 * Currently, the code marked with RFKILL_NEED_SWSET is inactive.
52 * If handling of EV_SW SW_WLAN/WWAN/BLUETOOTH/etc is needed in the
53 * future, when such events are added, that code will be necessary.
54 */
55
56struct rfkill_task { 50struct rfkill_task {
57 struct delayed_work dwork; 51 struct delayed_work dwork;
58 52
@@ -65,14 +59,6 @@ struct rfkill_task {
65 /* pending regular switch operations (1=pending) */ 59 /* pending regular switch operations (1=pending) */
66 unsigned long sw_pending[BITS_TO_LONGS(RFKILL_TYPE_MAX)]; 60 unsigned long sw_pending[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
67 61
68#ifdef RFKILL_NEED_SWSET
69 /* set operation pending (1=pending) */
70 unsigned long sw_setpending[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
71
72 /* desired state for pending set operation (1=unblock) */
73 unsigned long sw_newstate[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
74#endif
75
76 /* should the state be complemented (1=yes) */ 62 /* should the state be complemented (1=yes) */
77 unsigned long sw_togglestate[BITS_TO_LONGS(RFKILL_TYPE_MAX)]; 63 unsigned long sw_togglestate[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
78 64
@@ -111,24 +97,6 @@ static void __rfkill_handle_global_op(enum rfkill_global_sched_op op)
111 } 97 }
112} 98}
113 99
114#ifdef RFKILL_NEED_SWSET
115static void __rfkill_handle_normal_op(const enum rfkill_type type,
116 const bool sp, const bool s, const bool c)
117{
118 enum rfkill_state state;
119
120 if (sp)
121 state = (s) ? RFKILL_STATE_UNBLOCKED :
122 RFKILL_STATE_SOFT_BLOCKED;
123 else
124 state = rfkill_get_global_state(type);
125
126 if (c)
127 state = rfkill_state_complement(state);
128
129 rfkill_switch_all(type, state);
130}
131#else
132static void __rfkill_handle_normal_op(const enum rfkill_type type, 100static void __rfkill_handle_normal_op(const enum rfkill_type type,
133 const bool c) 101 const bool c)
134{ 102{
@@ -140,7 +108,6 @@ static void __rfkill_handle_normal_op(const enum rfkill_type type,
140 108
141 rfkill_switch_all(type, state); 109 rfkill_switch_all(type, state);
142} 110}
143#endif
144 111
145static void rfkill_task_handler(struct work_struct *work) 112static void rfkill_task_handler(struct work_struct *work)
146{ 113{
@@ -171,21 +138,11 @@ static void rfkill_task_handler(struct work_struct *work)
171 i < RFKILL_TYPE_MAX) { 138 i < RFKILL_TYPE_MAX) {
172 if (test_and_clear_bit(i, task->sw_pending)) { 139 if (test_and_clear_bit(i, task->sw_pending)) {
173 bool c; 140 bool c;
174#ifdef RFKILL_NEED_SWSET
175 bool sp, s;
176 sp = test_and_clear_bit(i,
177 task->sw_setpending);
178 s = test_bit(i, task->sw_newstate);
179#endif
180 c = test_and_clear_bit(i, 141 c = test_and_clear_bit(i,
181 task->sw_togglestate); 142 task->sw_togglestate);
182 spin_unlock_irq(&task->lock); 143 spin_unlock_irq(&task->lock);
183 144
184#ifdef RFKILL_NEED_SWSET
185 __rfkill_handle_normal_op(i, sp, s, c);
186#else
187 __rfkill_handle_normal_op(i, c); 145 __rfkill_handle_normal_op(i, c);
188#endif
189 146
190 spin_lock_irq(&task->lock); 147 spin_lock_irq(&task->lock);
191 } 148 }
@@ -238,32 +195,6 @@ static void rfkill_schedule_global_op(enum rfkill_global_sched_op op)
238 spin_unlock_irqrestore(&rfkill_task.lock, flags); 195 spin_unlock_irqrestore(&rfkill_task.lock, flags);
239} 196}
240 197
241#ifdef RFKILL_NEED_SWSET
242/* Use this if you need to add EV_SW SW_WLAN/WWAN/BLUETOOTH/etc handling */
243
244static void rfkill_schedule_set(enum rfkill_type type,
245 enum rfkill_state desired_state)
246{
247 unsigned long flags;
248
249 if (rfkill_is_epo_lock_active())
250 return;
251
252 spin_lock_irqsave(&rfkill_task.lock, flags);
253 if (!rfkill_task.global_op_pending) {
254 set_bit(type, rfkill_task.sw_pending);
255 set_bit(type, rfkill_task.sw_setpending);
256 clear_bit(type, rfkill_task.sw_togglestate);
257 if (desired_state)
258 set_bit(type, rfkill_task.sw_newstate);
259 else
260 clear_bit(type, rfkill_task.sw_newstate);
261 rfkill_schedule_ratelimited();
262 }
263 spin_unlock_irqrestore(&rfkill_task.lock, flags);
264}
265#endif
266
267static void rfkill_schedule_toggle(enum rfkill_type type) 198static void rfkill_schedule_toggle(enum rfkill_type type)
268{ 199{
269 unsigned long flags; 200 unsigned long flags;
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index 3eaa39403c13..e2d4510623f2 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -96,6 +96,7 @@ static void update_rfkill_state(struct rfkill *rfkill)
96 } 96 }
97 mutex_unlock(&rfkill->mutex); 97 mutex_unlock(&rfkill->mutex);
98 } 98 }
99 rfkill_led_trigger(rfkill, rfkill->state);
99} 100}
100 101
101/** 102/**
@@ -136,8 +137,9 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
136 oldstate = rfkill->state; 137 oldstate = rfkill->state;
137 138
138 if (rfkill->get_state && !force && 139 if (rfkill->get_state && !force &&
139 !rfkill->get_state(rfkill->data, &newstate)) 140 !rfkill->get_state(rfkill->data, &newstate)) {
140 rfkill->state = newstate; 141 rfkill->state = newstate;
142 }
141 143
142 switch (state) { 144 switch (state) {
143 case RFKILL_STATE_HARD_BLOCKED: 145 case RFKILL_STATE_HARD_BLOCKED:
@@ -172,6 +174,7 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
172 if (force || rfkill->state != oldstate) 174 if (force || rfkill->state != oldstate)
173 rfkill_uevent(rfkill); 175 rfkill_uevent(rfkill);
174 176
177 rfkill_led_trigger(rfkill, rfkill->state);
175 return retval; 178 return retval;
176} 179}
177 180
@@ -200,10 +203,11 @@ static void __rfkill_switch_all(const enum rfkill_type type,
200 203
201 rfkill_global_states[type].current_state = state; 204 rfkill_global_states[type].current_state = state;
202 list_for_each_entry(rfkill, &rfkill_list, node) { 205 list_for_each_entry(rfkill, &rfkill_list, node) {
203 if ((!rfkill->user_claim) && (rfkill->type == type)) { 206 if (rfkill->type == type) {
204 mutex_lock(&rfkill->mutex); 207 mutex_lock(&rfkill->mutex);
205 rfkill_toggle_radio(rfkill, state, 0); 208 rfkill_toggle_radio(rfkill, state, 0);
206 mutex_unlock(&rfkill->mutex); 209 mutex_unlock(&rfkill->mutex);
210 rfkill_led_trigger(rfkill, rfkill->state);
207 } 211 }
208 } 212 }
209} 213}
@@ -256,6 +260,7 @@ void rfkill_epo(void)
256 RFKILL_STATE_SOFT_BLOCKED; 260 RFKILL_STATE_SOFT_BLOCKED;
257 } 261 }
258 mutex_unlock(&rfkill_global_mutex); 262 mutex_unlock(&rfkill_global_mutex);
263 rfkill_led_trigger(rfkill, rfkill->state);
259} 264}
260EXPORT_SYMBOL_GPL(rfkill_epo); 265EXPORT_SYMBOL_GPL(rfkill_epo);
261 266
@@ -358,6 +363,7 @@ int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state)
358 rfkill_uevent(rfkill); 363 rfkill_uevent(rfkill);
359 364
360 mutex_unlock(&rfkill->mutex); 365 mutex_unlock(&rfkill->mutex);
366 rfkill_led_trigger(rfkill, rfkill->state);
361 367
362 return 0; 368 return 0;
363} 369}
@@ -447,53 +453,14 @@ static ssize_t rfkill_claim_show(struct device *dev,
447 struct device_attribute *attr, 453 struct device_attribute *attr,
448 char *buf) 454 char *buf)
449{ 455{
450 struct rfkill *rfkill = to_rfkill(dev); 456 return sprintf(buf, "%d\n", 0);
451
452 return sprintf(buf, "%d\n", rfkill->user_claim);
453} 457}
454 458
455static ssize_t rfkill_claim_store(struct device *dev, 459static ssize_t rfkill_claim_store(struct device *dev,
456 struct device_attribute *attr, 460 struct device_attribute *attr,
457 const char *buf, size_t count) 461 const char *buf, size_t count)
458{ 462{
459 struct rfkill *rfkill = to_rfkill(dev); 463 return -EOPNOTSUPP;
460 unsigned long claim_tmp;
461 bool claim;
462 int error;
463
464 if (!capable(CAP_NET_ADMIN))
465 return -EPERM;
466
467 if (rfkill->user_claim_unsupported)
468 return -EOPNOTSUPP;
469
470 error = strict_strtoul(buf, 0, &claim_tmp);
471 if (error)
472 return error;
473 claim = !!claim_tmp;
474
475 /*
476 * Take the global lock to make sure the kernel is not in
477 * the middle of rfkill_switch_all
478 */
479 error = mutex_lock_killable(&rfkill_global_mutex);
480 if (error)
481 return error;
482
483 if (rfkill->user_claim != claim) {
484 if (!claim && !rfkill_epo_lock_active) {
485 mutex_lock(&rfkill->mutex);
486 rfkill_toggle_radio(rfkill,
487 rfkill_global_states[rfkill->type].current_state,
488 0);
489 mutex_unlock(&rfkill->mutex);
490 }
491 rfkill->user_claim = claim;
492 }
493
494 mutex_unlock(&rfkill_global_mutex);
495
496 return error ? error : count;
497} 464}
498 465
499static struct device_attribute rfkill_dev_attrs[] = { 466static struct device_attribute rfkill_dev_attrs[] = {
@@ -559,6 +526,7 @@ static int rfkill_resume(struct device *dev)
559 1); 526 1);
560 527
561 mutex_unlock(&rfkill->mutex); 528 mutex_unlock(&rfkill->mutex);
529 rfkill_led_trigger(rfkill, rfkill->state);
562 } 530 }
563 531
564 return 0; 532 return 0;
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 7d08f522ec84..f0c91df59d4e 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -412,6 +412,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
412 412
413 /* Build the SCTP header. */ 413 /* Build the SCTP header. */
414 sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr)); 414 sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr));
415 skb_reset_transport_header(nskb);
415 sh->source = htons(packet->source_port); 416 sh->source = htons(packet->source_port);
416 sh->dest = htons(packet->destination_port); 417 sh->dest = htons(packet->destination_port);
417 418
@@ -527,15 +528,25 @@ int sctp_packet_transmit(struct sctp_packet *packet)
527 * Note: Adler-32 is no longer applicable, as has been replaced 528 * Note: Adler-32 is no longer applicable, as has been replaced
528 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. 529 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
529 */ 530 */
530 if (!sctp_checksum_disable && !(dst->dev->features & NETIF_F_NO_CSUM)) { 531 if (!sctp_checksum_disable &&
532 !(dst->dev->features & (NETIF_F_NO_CSUM | NETIF_F_SCTP_CSUM))) {
531 __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len); 533 __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len);
532 534
533 /* 3) Put the resultant value into the checksum field in the 535 /* 3) Put the resultant value into the checksum field in the
534 * common header, and leave the rest of the bits unchanged. 536 * common header, and leave the rest of the bits unchanged.
535 */ 537 */
536 sh->checksum = sctp_end_cksum(crc32); 538 sh->checksum = sctp_end_cksum(crc32);
537 } else 539 } else {
538 nskb->ip_summed = CHECKSUM_UNNECESSARY; 540 if (dst->dev->features & NETIF_F_SCTP_CSUM) {
541 /* no need to seed psuedo checksum for SCTP */
542 nskb->ip_summed = CHECKSUM_PARTIAL;
543 nskb->csum_start = (skb_transport_header(nskb) -
544 nskb->head);
545 nskb->csum_offset = offsetof(struct sctphdr, checksum);
546 } else {
547 nskb->ip_summed = CHECKSUM_UNNECESSARY;
548 }
549 }
539 550
540 /* IP layer ECN support 551 /* IP layer ECN support
541 * From RFC 2481 552 * From RFC 2481
diff --git a/net/wimax/op-rfkill.c b/net/wimax/op-rfkill.c
index 2b75aee04217..a3616e2ccb8a 100644
--- a/net/wimax/op-rfkill.c
+++ b/net/wimax/op-rfkill.c
@@ -113,7 +113,7 @@ void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev,
113 if (state != wimax_dev->rf_hw) { 113 if (state != wimax_dev->rf_hw) {
114 wimax_dev->rf_hw = state; 114 wimax_dev->rf_hw = state;
115 rfkill_state = state == WIMAX_RF_ON ? 115 rfkill_state = state == WIMAX_RF_ON ?
116 RFKILL_STATE_OFF : RFKILL_STATE_ON; 116 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
117 if (wimax_dev->rf_hw == WIMAX_RF_ON 117 if (wimax_dev->rf_hw == WIMAX_RF_ON
118 && wimax_dev->rf_sw == WIMAX_RF_ON) 118 && wimax_dev->rf_sw == WIMAX_RF_ON)
119 wimax_state = WIMAX_ST_READY; 119 wimax_state = WIMAX_ST_READY;
@@ -259,10 +259,10 @@ int wimax_rfkill_toggle_radio(void *data, enum rfkill_state state)
259 259
260 d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state); 260 d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state);
261 switch (state) { 261 switch (state) {
262 case RFKILL_STATE_ON: 262 case RFKILL_STATE_SOFT_BLOCKED:
263 rf_state = WIMAX_RF_OFF; 263 rf_state = WIMAX_RF_OFF;
264 break; 264 break;
265 case RFKILL_STATE_OFF: 265 case RFKILL_STATE_UNBLOCKED:
266 rf_state = WIMAX_RF_ON; 266 rf_state = WIMAX_RF_ON;
267 break; 267 break;
268 default: 268 default:
@@ -361,10 +361,9 @@ int wimax_rfkill_add(struct wimax_dev *wimax_dev)
361 wimax_dev->rfkill = rfkill; 361 wimax_dev->rfkill = rfkill;
362 362
363 rfkill->name = wimax_dev->name; 363 rfkill->name = wimax_dev->name;
364 rfkill->state = RFKILL_STATE_OFF; 364 rfkill->state = RFKILL_STATE_UNBLOCKED;
365 rfkill->data = wimax_dev; 365 rfkill->data = wimax_dev;
366 rfkill->toggle_radio = wimax_rfkill_toggle_radio; 366 rfkill->toggle_radio = wimax_rfkill_toggle_radio;
367 rfkill->user_claim_unsupported = 1;
368 367
369 /* Initialize the input device for the hw key */ 368 /* Initialize the input device for the hw key */
370 input_dev = input_allocate_device(); 369 input_dev = input_allocate_device();
diff --git a/net/wireless/Makefile b/net/wireless/Makefile
index 6d1e7b27b752..14ea01c4a103 100644
--- a/net/wireless/Makefile
+++ b/net/wireless/Makefile
@@ -5,7 +5,7 @@ obj-$(CONFIG_LIB80211_CRYPT_WEP) += lib80211_crypt_wep.o
5obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o 5obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o
6obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o 6obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o
7 7
8cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o 8cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o ibss.o
9cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o 9cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o
10 10
11ccflags-y += -D__CHECK_ENDIAN__ 11ccflags-y += -D__CHECK_ENDIAN__
diff --git a/net/wireless/core.c b/net/wireless/core.c
index d1f556535f6d..2006a4ee60eb 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -14,7 +14,6 @@
14#include <linux/device.h> 14#include <linux/device.h>
15#include <net/genetlink.h> 15#include <net/genetlink.h>
16#include <net/cfg80211.h> 16#include <net/cfg80211.h>
17#include <net/wireless.h>
18#include "nl80211.h" 17#include "nl80211.h"
19#include "core.h" 18#include "core.h"
20#include "sysfs.h" 19#include "sysfs.h"
@@ -274,6 +273,16 @@ struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv)
274 drv->wiphy.dev.class = &ieee80211_class; 273 drv->wiphy.dev.class = &ieee80211_class;
275 drv->wiphy.dev.platform_data = drv; 274 drv->wiphy.dev.platform_data = drv;
276 275
276 /*
277 * Initialize wiphy parameters to IEEE 802.11 MIB default values.
278 * Fragmentation and RTS threshold are disabled by default with the
279 * special -1 value.
280 */
281 drv->wiphy.retry_short = 7;
282 drv->wiphy.retry_long = 4;
283 drv->wiphy.frag_threshold = (u32) -1;
284 drv->wiphy.rts_threshold = (u32) -1;
285
277 return &drv->wiphy; 286 return &drv->wiphy;
278} 287}
279EXPORT_SYMBOL(wiphy_new); 288EXPORT_SYMBOL(wiphy_new);
@@ -450,6 +459,22 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
450 dev->ieee80211_ptr->netdev = dev; 459 dev->ieee80211_ptr->netdev = dev;
451 mutex_unlock(&rdev->devlist_mtx); 460 mutex_unlock(&rdev->devlist_mtx);
452 break; 461 break;
462 case NETDEV_GOING_DOWN:
463 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
464 break;
465 if (!dev->ieee80211_ptr->ssid_len)
466 break;
467 cfg80211_leave_ibss(rdev, dev, true);
468 break;
469 case NETDEV_UP:
470#ifdef CONFIG_WIRELESS_EXT
471 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
472 break;
473 if (!dev->ieee80211_ptr->wext.ssid_len)
474 break;
475 cfg80211_join_ibss(rdev, dev, &dev->ieee80211_ptr->wext);
476 break;
477#endif
453 case NETDEV_UNREGISTER: 478 case NETDEV_UNREGISTER:
454 mutex_lock(&rdev->devlist_mtx); 479 mutex_lock(&rdev->devlist_mtx);
455 if (!list_empty(&dev->ieee80211_ptr->list)) { 480 if (!list_empty(&dev->ieee80211_ptr->list)) {
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 0a592e4295f0..3e49d3399311 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -10,9 +10,7 @@
10#include <linux/netdevice.h> 10#include <linux/netdevice.h>
11#include <linux/kref.h> 11#include <linux/kref.h>
12#include <linux/rbtree.h> 12#include <linux/rbtree.h>
13#include <linux/mutex.h>
14#include <net/genetlink.h> 13#include <net/genetlink.h>
15#include <net/wireless.h>
16#include <net/cfg80211.h> 14#include <net/cfg80211.h>
17#include "reg.h" 15#include "reg.h"
18 16
@@ -74,10 +72,7 @@ bool wiphy_idx_valid(int wiphy_idx)
74extern struct mutex cfg80211_mutex; 72extern struct mutex cfg80211_mutex;
75extern struct list_head cfg80211_drv_list; 73extern struct list_head cfg80211_drv_list;
76 74
77static inline void assert_cfg80211_lock(void) 75#define assert_cfg80211_lock() WARN_ON(!mutex_is_locked(&cfg80211_mutex))
78{
79 WARN_ON(!mutex_is_locked(&cfg80211_mutex));
80}
81 76
82/* 77/*
83 * You can use this to mark a wiphy_idx as not having an associated wiphy. 78 * You can use this to mark a wiphy_idx as not having an associated wiphy.
@@ -148,4 +143,12 @@ void cfg80211_bss_expire(struct cfg80211_registered_device *dev);
148void cfg80211_bss_age(struct cfg80211_registered_device *dev, 143void cfg80211_bss_age(struct cfg80211_registered_device *dev,
149 unsigned long age_secs); 144 unsigned long age_secs);
150 145
146/* IBSS */
147int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
148 struct net_device *dev,
149 struct cfg80211_ibss_params *params);
150void cfg80211_clear_ibss(struct net_device *dev, bool nowext);
151int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
152 struct net_device *dev, bool nowext);
153
151#endif /* __NET_WIRELESS_CORE_H */ 154#endif /* __NET_WIRELESS_CORE_H */
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
new file mode 100644
index 000000000000..3c38afaed28a
--- /dev/null
+++ b/net/wireless/ibss.c
@@ -0,0 +1,369 @@
1/*
2 * Some IBSS support code for cfg80211.
3 *
4 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
5 */
6
7#include <linux/etherdevice.h>
8#include <linux/if_arp.h>
9#include <net/cfg80211.h>
10#include "nl80211.h"
11
12
13void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
14{
15 struct wireless_dev *wdev = dev->ieee80211_ptr;
16 struct cfg80211_bss *bss;
17#ifdef CONFIG_WIRELESS_EXT
18 union iwreq_data wrqu;
19#endif
20
21 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
22 return;
23
24 if (WARN_ON(!wdev->ssid_len))
25 return;
26
27 if (memcmp(bssid, wdev->bssid, ETH_ALEN) == 0)
28 return;
29
30 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
31 wdev->ssid, wdev->ssid_len,
32 WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
33
34 if (WARN_ON(!bss))
35 return;
36
37 if (wdev->current_bss) {
38 cfg80211_unhold_bss(wdev->current_bss);
39 cfg80211_put_bss(wdev->current_bss);
40 }
41
42 cfg80211_hold_bss(bss);
43 wdev->current_bss = bss;
44 memcpy(wdev->bssid, bssid, ETH_ALEN);
45
46 nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid, gfp);
47#ifdef CONFIG_WIRELESS_EXT
48 memset(&wrqu, 0, sizeof(wrqu));
49 memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
50 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
51#endif
52}
53EXPORT_SYMBOL(cfg80211_ibss_joined);
54
55int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
56 struct net_device *dev,
57 struct cfg80211_ibss_params *params)
58{
59 struct wireless_dev *wdev = dev->ieee80211_ptr;
60 int err;
61
62 if (wdev->ssid_len)
63 return -EALREADY;
64
65#ifdef CONFIG_WIRELESS_EXT
66 wdev->wext.channel = params->channel;
67#endif
68 err = rdev->ops->join_ibss(&rdev->wiphy, dev, params);
69
70 if (err)
71 return err;
72
73 memcpy(wdev->ssid, params->ssid, params->ssid_len);
74 wdev->ssid_len = params->ssid_len;
75
76 return 0;
77}
78
79void cfg80211_clear_ibss(struct net_device *dev, bool nowext)
80{
81 struct wireless_dev *wdev = dev->ieee80211_ptr;
82
83 if (wdev->current_bss) {
84 cfg80211_unhold_bss(wdev->current_bss);
85 cfg80211_put_bss(wdev->current_bss);
86 }
87
88 wdev->current_bss = NULL;
89 wdev->ssid_len = 0;
90 memset(wdev->bssid, 0, ETH_ALEN);
91#ifdef CONFIG_WIRELESS_EXT
92 if (!nowext)
93 wdev->wext.ssid_len = 0;
94#endif
95}
96
97int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
98 struct net_device *dev, bool nowext)
99{
100 int err;
101
102 err = rdev->ops->leave_ibss(&rdev->wiphy, dev);
103
104 if (err)
105 return err;
106
107 cfg80211_clear_ibss(dev, nowext);
108
109 return 0;
110}
111
112#ifdef CONFIG_WIRELESS_EXT
113static int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
114 struct wireless_dev *wdev)
115{
116 enum ieee80211_band band;
117 int i;
118
119 if (!wdev->wext.beacon_interval)
120 wdev->wext.beacon_interval = 100;
121
122 /* try to find an IBSS channel if none requested ... */
123 if (!wdev->wext.channel) {
124 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
125 struct ieee80211_supported_band *sband;
126 struct ieee80211_channel *chan;
127
128 sband = rdev->wiphy.bands[band];
129 if (!sband)
130 continue;
131
132 for (i = 0; i < sband->n_channels; i++) {
133 chan = &sband->channels[i];
134 if (chan->flags & IEEE80211_CHAN_NO_IBSS)
135 continue;
136 if (chan->flags & IEEE80211_CHAN_DISABLED)
137 continue;
138 wdev->wext.channel = chan;
139 break;
140 }
141
142 if (wdev->wext.channel)
143 break;
144 }
145
146 if (!wdev->wext.channel)
147 return -EINVAL;
148 }
149
150 /* don't join -- SSID is not there */
151 if (!wdev->wext.ssid_len)
152 return 0;
153
154 if (!netif_running(wdev->netdev))
155 return 0;
156
157 return cfg80211_join_ibss(wiphy_to_dev(wdev->wiphy),
158 wdev->netdev, &wdev->wext);
159}
160
161int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
162 struct iw_request_info *info,
163 struct iw_freq *freq, char *extra)
164{
165 struct wireless_dev *wdev = dev->ieee80211_ptr;
166 struct ieee80211_channel *chan;
167 int err;
168
169 /* call only for ibss! */
170 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
171 return -EINVAL;
172
173 if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
174 return -EOPNOTSUPP;
175
176 chan = cfg80211_wext_freq(wdev->wiphy, freq);
177 if (chan && IS_ERR(chan))
178 return PTR_ERR(chan);
179
180 if (chan &&
181 (chan->flags & IEEE80211_CHAN_NO_IBSS ||
182 chan->flags & IEEE80211_CHAN_DISABLED))
183 return -EINVAL;
184
185 if (wdev->wext.channel == chan)
186 return 0;
187
188 if (wdev->ssid_len) {
189 err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy),
190 dev, true);
191 if (err)
192 return err;
193 }
194
195 if (chan) {
196 wdev->wext.channel = chan;
197 wdev->wext.channel_fixed = true;
198 } else {
199 /* cfg80211_ibss_wext_join will pick one if needed */
200 wdev->wext.channel_fixed = false;
201 }
202
203 return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
204}
205/* temporary symbol - mark GPL - in the future the handler won't be */
206EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwfreq);
207
208int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
209 struct iw_request_info *info,
210 struct iw_freq *freq, char *extra)
211{
212 struct wireless_dev *wdev = dev->ieee80211_ptr;
213 struct ieee80211_channel *chan = NULL;
214
215 /* call only for ibss! */
216 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
217 return -EINVAL;
218
219 if (wdev->current_bss)
220 chan = wdev->current_bss->channel;
221 else if (wdev->wext.channel)
222 chan = wdev->wext.channel;
223
224 if (chan) {
225 freq->m = chan->center_freq;
226 freq->e = 6;
227 return 0;
228 }
229
230 /* no channel if not joining */
231 return -EINVAL;
232}
233/* temporary symbol - mark GPL - in the future the handler won't be */
234EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwfreq);
235
236int cfg80211_ibss_wext_siwessid(struct net_device *dev,
237 struct iw_request_info *info,
238 struct iw_point *data, char *ssid)
239{
240 struct wireless_dev *wdev = dev->ieee80211_ptr;
241 size_t len = data->length;
242 int err;
243
244 /* call only for ibss! */
245 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
246 return -EINVAL;
247
248 if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
249 return -EOPNOTSUPP;
250
251 if (wdev->ssid_len) {
252 err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy),
253 dev, true);
254 if (err)
255 return err;
256 }
257
258 /* iwconfig uses nul termination in SSID.. */
259 if (len > 0 && ssid[len - 1] == '\0')
260 len--;
261
262 wdev->wext.ssid = wdev->ssid;
263 memcpy(wdev->wext.ssid, ssid, len);
264 wdev->wext.ssid_len = len;
265
266 return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
267}
268/* temporary symbol - mark GPL - in the future the handler won't be */
269EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwessid);
270
271int cfg80211_ibss_wext_giwessid(struct net_device *dev,
272 struct iw_request_info *info,
273 struct iw_point *data, char *ssid)
274{
275 struct wireless_dev *wdev = dev->ieee80211_ptr;
276
277 /* call only for ibss! */
278 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
279 return -EINVAL;
280
281 data->flags = 0;
282
283 if (wdev->ssid_len) {
284 data->flags = 1;
285 data->length = wdev->ssid_len;
286 memcpy(ssid, wdev->ssid, data->length);
287 } else if (wdev->wext.ssid && wdev->wext.ssid_len) {
288 data->flags = 1;
289 data->length = wdev->wext.ssid_len;
290 memcpy(ssid, wdev->wext.ssid, data->length);
291 }
292
293 return 0;
294}
295/* temporary symbol - mark GPL - in the future the handler won't be */
296EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwessid);
297
298int cfg80211_ibss_wext_siwap(struct net_device *dev,
299 struct iw_request_info *info,
300 struct sockaddr *ap_addr, char *extra)
301{
302 struct wireless_dev *wdev = dev->ieee80211_ptr;
303 u8 *bssid = ap_addr->sa_data;
304 int err;
305
306 /* call only for ibss! */
307 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
308 return -EINVAL;
309
310 if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
311 return -EOPNOTSUPP;
312
313 if (ap_addr->sa_family != ARPHRD_ETHER)
314 return -EINVAL;
315
316 /* automatic mode */
317 if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid))
318 bssid = NULL;
319
320 /* both automatic */
321 if (!bssid && !wdev->wext.bssid)
322 return 0;
323
324 /* fixed already - and no change */
325 if (wdev->wext.bssid && bssid &&
326 compare_ether_addr(bssid, wdev->wext.bssid) == 0)
327 return 0;
328
329 if (wdev->ssid_len) {
330 err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy),
331 dev, true);
332 if (err)
333 return err;
334 }
335
336 if (bssid) {
337 memcpy(wdev->wext_bssid, bssid, ETH_ALEN);
338 wdev->wext.bssid = wdev->wext_bssid;
339 } else
340 wdev->wext.bssid = NULL;
341
342 return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
343}
344/* temporary symbol - mark GPL - in the future the handler won't be */
345EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwap);
346
347int cfg80211_ibss_wext_giwap(struct net_device *dev,
348 struct iw_request_info *info,
349 struct sockaddr *ap_addr, char *extra)
350{
351 struct wireless_dev *wdev = dev->ieee80211_ptr;
352
353 /* call only for ibss! */
354 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
355 return -EINVAL;
356
357 ap_addr->sa_family = ARPHRD_ETHER;
358
359 if (wdev->wext.bssid) {
360 memcpy(ap_addr->sa_data, wdev->wext.bssid, ETH_ALEN);
361 return 0;
362 }
363
364 memcpy(ap_addr->sa_data, wdev->bssid, ETH_ALEN);
365 return 0;
366}
367/* temporary symbol - mark GPL - in the future the handler won't be */
368EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwap);
369#endif
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index bec5721b6f99..42184361a109 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -28,19 +28,55 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
28} 28}
29EXPORT_SYMBOL(cfg80211_send_rx_assoc); 29EXPORT_SYMBOL(cfg80211_send_rx_assoc);
30 30
31void cfg80211_send_rx_deauth(struct net_device *dev, const u8 *buf, size_t len) 31void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len)
32{ 32{
33 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; 33 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
34 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 34 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
35 nl80211_send_rx_deauth(rdev, dev, buf, len); 35 nl80211_send_deauth(rdev, dev, buf, len);
36} 36}
37EXPORT_SYMBOL(cfg80211_send_rx_deauth); 37EXPORT_SYMBOL(cfg80211_send_deauth);
38 38
39void cfg80211_send_rx_disassoc(struct net_device *dev, const u8 *buf, 39void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
40 size_t len)
41{ 40{
42 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; 41 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
43 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 42 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
44 nl80211_send_rx_disassoc(rdev, dev, buf, len); 43 nl80211_send_disassoc(rdev, dev, buf, len);
45} 44}
46EXPORT_SYMBOL(cfg80211_send_rx_disassoc); 45EXPORT_SYMBOL(cfg80211_send_disassoc);
46
47static void cfg80211_wext_disconnected(struct net_device *dev)
48{
49#ifdef CONFIG_WIRELESS_EXT
50 union iwreq_data wrqu;
51 memset(&wrqu, 0, sizeof(wrqu));
52 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
53#endif
54}
55
56void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
57{
58 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
59 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
60 nl80211_send_auth_timeout(rdev, dev, addr);
61 cfg80211_wext_disconnected(dev);
62}
63EXPORT_SYMBOL(cfg80211_send_auth_timeout);
64
65void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
66{
67 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
68 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
69 nl80211_send_assoc_timeout(rdev, dev, addr);
70 cfg80211_wext_disconnected(dev);
71}
72EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
73
74void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
75 enum nl80211_key_type key_type, int key_id,
76 const u8 *tsc)
77{
78 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
79 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
80 nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc);
81}
82EXPORT_SYMBOL(cfg80211_michael_mic_failure);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 2456e4ee445e..b1fc98225fd1 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -61,6 +61,10 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
61 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED }, 61 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
62 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 }, 62 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
63 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 }, 63 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
64 [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 },
65 [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 },
66 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
67 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
64 68
65 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, 69 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
66 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, 70 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
@@ -116,8 +120,40 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
116 .len = IEEE80211_MAX_SSID_LEN }, 120 .len = IEEE80211_MAX_SSID_LEN },
117 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 }, 121 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
118 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 }, 122 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
123 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
124 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
119}; 125};
120 126
127/* IE validation */
128static bool is_valid_ie_attr(const struct nlattr *attr)
129{
130 const u8 *pos;
131 int len;
132
133 if (!attr)
134 return true;
135
136 pos = nla_data(attr);
137 len = nla_len(attr);
138
139 while (len) {
140 u8 elemlen;
141
142 if (len < 2)
143 return false;
144 len -= 2;
145
146 elemlen = pos[1];
147 if (elemlen > len)
148 return false;
149
150 len -= elemlen;
151 pos += 2 + elemlen;
152 }
153
154 return true;
155}
156
121/* message building helper */ 157/* message building helper */
122static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq, 158static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq,
123 int flags, u8 cmd) 159 int flags, u8 cmd)
@@ -126,6 +162,30 @@ static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq,
126 return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd); 162 return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd);
127} 163}
128 164
165static int nl80211_msg_put_channel(struct sk_buff *msg,
166 struct ieee80211_channel *chan)
167{
168 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ,
169 chan->center_freq);
170
171 if (chan->flags & IEEE80211_CHAN_DISABLED)
172 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED);
173 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
174 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN);
175 if (chan->flags & IEEE80211_CHAN_NO_IBSS)
176 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS);
177 if (chan->flags & IEEE80211_CHAN_RADAR)
178 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR);
179
180 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
181 DBM_TO_MBM(chan->max_power));
182
183 return 0;
184
185 nla_put_failure:
186 return -ENOBUFS;
187}
188
129/* netlink command implementations */ 189/* netlink command implementations */
130 190
131static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, 191static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
@@ -149,8 +209,24 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
149 209
150 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx); 210 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx);
151 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)); 211 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
212
213 NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
214 dev->wiphy.retry_short);
215 NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
216 dev->wiphy.retry_long);
217 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
218 dev->wiphy.frag_threshold);
219 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
220 dev->wiphy.rts_threshold);
221
152 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS, 222 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
153 dev->wiphy.max_scan_ssids); 223 dev->wiphy.max_scan_ssids);
224 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
225 dev->wiphy.max_scan_ie_len);
226
227 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
228 sizeof(u32) * dev->wiphy.n_cipher_suites,
229 dev->wiphy.cipher_suites);
154 230
155 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES); 231 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES);
156 if (!nl_modes) 232 if (!nl_modes)
@@ -202,20 +278,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
202 goto nla_put_failure; 278 goto nla_put_failure;
203 279
204 chan = &dev->wiphy.bands[band]->channels[i]; 280 chan = &dev->wiphy.bands[band]->channels[i];
205 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ,
206 chan->center_freq);
207
208 if (chan->flags & IEEE80211_CHAN_DISABLED)
209 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED);
210 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
211 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN);
212 if (chan->flags & IEEE80211_CHAN_NO_IBSS)
213 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS);
214 if (chan->flags & IEEE80211_CHAN_RADAR)
215 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR);
216 281
217 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 282 if (nl80211_msg_put_channel(msg, chan))
218 DBM_TO_MBM(chan->max_power)); 283 goto nla_put_failure;
219 284
220 nla_nest_end(msg, nl_freq); 285 nla_nest_end(msg, nl_freq);
221 } 286 }
@@ -273,6 +338,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
273 CMD(assoc, ASSOCIATE); 338 CMD(assoc, ASSOCIATE);
274 CMD(deauth, DEAUTHENTICATE); 339 CMD(deauth, DEAUTHENTICATE);
275 CMD(disassoc, DISASSOCIATE); 340 CMD(disassoc, DISASSOCIATE);
341 CMD(join_ibss, JOIN_IBSS);
276 342
277#undef CMD 343#undef CMD
278 nla_nest_end(msg, nl_cmds); 344 nla_nest_end(msg, nl_cmds);
@@ -365,6 +431,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
365 struct cfg80211_registered_device *rdev; 431 struct cfg80211_registered_device *rdev;
366 int result = 0, rem_txq_params = 0; 432 int result = 0, rem_txq_params = 0;
367 struct nlattr *nl_txq_params; 433 struct nlattr *nl_txq_params;
434 u32 changed;
435 u8 retry_short = 0, retry_long = 0;
436 u32 frag_threshold = 0, rts_threshold = 0;
368 437
369 rtnl_lock(); 438 rtnl_lock();
370 439
@@ -479,6 +548,84 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
479 goto bad_res; 548 goto bad_res;
480 } 549 }
481 550
551 changed = 0;
552
553 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
554 retry_short = nla_get_u8(
555 info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
556 if (retry_short == 0) {
557 result = -EINVAL;
558 goto bad_res;
559 }
560 changed |= WIPHY_PARAM_RETRY_SHORT;
561 }
562
563 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
564 retry_long = nla_get_u8(
565 info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
566 if (retry_long == 0) {
567 result = -EINVAL;
568 goto bad_res;
569 }
570 changed |= WIPHY_PARAM_RETRY_LONG;
571 }
572
573 if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
574 frag_threshold = nla_get_u32(
575 info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
576 if (frag_threshold < 256) {
577 result = -EINVAL;
578 goto bad_res;
579 }
580 if (frag_threshold != (u32) -1) {
581 /*
582 * Fragments (apart from the last one) are required to
583 * have even length. Make the fragmentation code
584 * simpler by stripping LSB should someone try to use
585 * odd threshold value.
586 */
587 frag_threshold &= ~0x1;
588 }
589 changed |= WIPHY_PARAM_FRAG_THRESHOLD;
590 }
591
592 if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
593 rts_threshold = nla_get_u32(
594 info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
595 changed |= WIPHY_PARAM_RTS_THRESHOLD;
596 }
597
598 if (changed) {
599 u8 old_retry_short, old_retry_long;
600 u32 old_frag_threshold, old_rts_threshold;
601
602 if (!rdev->ops->set_wiphy_params) {
603 result = -EOPNOTSUPP;
604 goto bad_res;
605 }
606
607 old_retry_short = rdev->wiphy.retry_short;
608 old_retry_long = rdev->wiphy.retry_long;
609 old_frag_threshold = rdev->wiphy.frag_threshold;
610 old_rts_threshold = rdev->wiphy.rts_threshold;
611
612 if (changed & WIPHY_PARAM_RETRY_SHORT)
613 rdev->wiphy.retry_short = retry_short;
614 if (changed & WIPHY_PARAM_RETRY_LONG)
615 rdev->wiphy.retry_long = retry_long;
616 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
617 rdev->wiphy.frag_threshold = frag_threshold;
618 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
619 rdev->wiphy.rts_threshold = rts_threshold;
620
621 result = rdev->ops->set_wiphy_params(&rdev->wiphy, changed);
622 if (result) {
623 rdev->wiphy.retry_short = old_retry_short;
624 rdev->wiphy.retry_long = old_retry_long;
625 rdev->wiphy.frag_threshold = old_frag_threshold;
626 rdev->wiphy.rts_threshold = old_rts_threshold;
627 }
628 }
482 629
483 bad_res: 630 bad_res:
484 mutex_unlock(&rdev->mtx); 631 mutex_unlock(&rdev->mtx);
@@ -489,6 +636,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
489 636
490 637
491static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags, 638static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
639 struct cfg80211_registered_device *rdev,
492 struct net_device *dev) 640 struct net_device *dev)
493{ 641{
494 void *hdr; 642 void *hdr;
@@ -498,6 +646,7 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
498 return -1; 646 return -1;
499 647
500 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); 648 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
649 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
501 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name); 650 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name);
502 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype); 651 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype);
503 return genlmsg_end(msg, hdr); 652 return genlmsg_end(msg, hdr);
@@ -532,7 +681,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
532 } 681 }
533 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid, 682 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid,
534 cb->nlh->nlmsg_seq, NLM_F_MULTI, 683 cb->nlh->nlmsg_seq, NLM_F_MULTI,
535 wdev->netdev) < 0) { 684 dev, wdev->netdev) < 0) {
536 mutex_unlock(&dev->devlist_mtx); 685 mutex_unlock(&dev->devlist_mtx);
537 goto out; 686 goto out;
538 } 687 }
@@ -566,7 +715,8 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
566 if (!msg) 715 if (!msg)
567 goto out_err; 716 goto out_err;
568 717
569 if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, netdev) < 0) 718 if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0,
719 dev, netdev) < 0)
570 goto out_free; 720 goto out_free;
571 721
572 dev_put(netdev); 722 dev_put(netdev);
@@ -616,7 +766,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
616 struct cfg80211_registered_device *drv; 766 struct cfg80211_registered_device *drv;
617 struct vif_params params; 767 struct vif_params params;
618 int err, ifindex; 768 int err, ifindex;
619 enum nl80211_iftype type; 769 enum nl80211_iftype otype, ntype;
620 struct net_device *dev; 770 struct net_device *dev;
621 u32 _flags, *flags = NULL; 771 u32 _flags, *flags = NULL;
622 bool change = false; 772 bool change = false;
@@ -630,30 +780,27 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
630 goto unlock_rtnl; 780 goto unlock_rtnl;
631 781
632 ifindex = dev->ifindex; 782 ifindex = dev->ifindex;
633 type = dev->ieee80211_ptr->iftype; 783 otype = ntype = dev->ieee80211_ptr->iftype;
634 dev_put(dev); 784 dev_put(dev);
635 785
636 if (info->attrs[NL80211_ATTR_IFTYPE]) { 786 if (info->attrs[NL80211_ATTR_IFTYPE]) {
637 enum nl80211_iftype ntype;
638
639 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]); 787 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
640 if (type != ntype) 788 if (otype != ntype)
641 change = true; 789 change = true;
642 type = ntype; 790 if (ntype > NL80211_IFTYPE_MAX) {
643 if (type > NL80211_IFTYPE_MAX) {
644 err = -EINVAL; 791 err = -EINVAL;
645 goto unlock; 792 goto unlock;
646 } 793 }
647 } 794 }
648 795
649 if (!drv->ops->change_virtual_intf || 796 if (!drv->ops->change_virtual_intf ||
650 !(drv->wiphy.interface_modes & (1 << type))) { 797 !(drv->wiphy.interface_modes & (1 << ntype))) {
651 err = -EOPNOTSUPP; 798 err = -EOPNOTSUPP;
652 goto unlock; 799 goto unlock;
653 } 800 }
654 801
655 if (info->attrs[NL80211_ATTR_MESH_ID]) { 802 if (info->attrs[NL80211_ATTR_MESH_ID]) {
656 if (type != NL80211_IFTYPE_MESH_POINT) { 803 if (ntype != NL80211_IFTYPE_MESH_POINT) {
657 err = -EINVAL; 804 err = -EINVAL;
658 goto unlock; 805 goto unlock;
659 } 806 }
@@ -663,7 +810,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
663 } 810 }
664 811
665 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) { 812 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
666 if (type != NL80211_IFTYPE_MONITOR) { 813 if (ntype != NL80211_IFTYPE_MONITOR) {
667 err = -EINVAL; 814 err = -EINVAL;
668 goto unlock; 815 goto unlock;
669 } 816 }
@@ -678,12 +825,17 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
678 825
679 if (change) 826 if (change)
680 err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex, 827 err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
681 type, flags, &params); 828 ntype, flags, &params);
682 else 829 else
683 err = 0; 830 err = 0;
684 831
685 dev = __dev_get_by_index(&init_net, ifindex); 832 dev = __dev_get_by_index(&init_net, ifindex);
686 WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != type)); 833 WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != ntype));
834
835 if (dev && !err && (ntype != otype)) {
836 if (otype == NL80211_IFTYPE_ADHOC)
837 cfg80211_clear_ibss(dev, false);
838 }
687 839
688 unlock: 840 unlock:
689 cfg80211_put_dev(drv); 841 cfg80211_put_dev(drv);
@@ -934,7 +1086,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
934static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) 1086static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
935{ 1087{
936 struct cfg80211_registered_device *drv; 1088 struct cfg80211_registered_device *drv;
937 int err; 1089 int err, i;
938 struct net_device *dev; 1090 struct net_device *dev;
939 struct key_params params; 1091 struct key_params params;
940 u8 key_idx = 0; 1092 u8 key_idx = 0;
@@ -1003,6 +1155,14 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
1003 if (err) 1155 if (err)
1004 goto unlock_rtnl; 1156 goto unlock_rtnl;
1005 1157
1158 for (i = 0; i < drv->wiphy.n_cipher_suites; i++)
1159 if (params.cipher == drv->wiphy.cipher_suites[i])
1160 break;
1161 if (i == drv->wiphy.n_cipher_suites) {
1162 err = -EINVAL;
1163 goto out;
1164 }
1165
1006 if (!drv->ops->add_key) { 1166 if (!drv->ops->add_key) {
1007 err = -EOPNOTSUPP; 1167 err = -EOPNOTSUPP;
1008 goto out; 1168 goto out;
@@ -1069,6 +1229,9 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1069 struct beacon_parameters params; 1229 struct beacon_parameters params;
1070 int haveinfo = 0; 1230 int haveinfo = 0;
1071 1231
1232 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]))
1233 return -EINVAL;
1234
1072 rtnl_lock(); 1235 rtnl_lock();
1073 1236
1074 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1237 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2442,6 +2605,9 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2442 enum ieee80211_band band; 2605 enum ieee80211_band band;
2443 size_t ie_len; 2606 size_t ie_len;
2444 2607
2608 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
2609 return -EINVAL;
2610
2445 rtnl_lock(); 2611 rtnl_lock();
2446 2612
2447 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 2613 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2492,6 +2658,11 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2492 else 2658 else
2493 ie_len = 0; 2659 ie_len = 0;
2494 2660
2661 if (ie_len > wiphy->max_scan_ie_len) {
2662 err = -EINVAL;
2663 goto out;
2664 }
2665
2495 request = kzalloc(sizeof(*request) 2666 request = kzalloc(sizeof(*request)
2496 + sizeof(*ssid) * n_ssids 2667 + sizeof(*ssid) * n_ssids
2497 + sizeof(channel) * n_channels 2668 + sizeof(channel) * n_channels
@@ -2554,7 +2725,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2554 2725
2555 if (info->attrs[NL80211_ATTR_IE]) { 2726 if (info->attrs[NL80211_ATTR_IE]) {
2556 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 2727 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2557 memcpy(request->ie, nla_data(info->attrs[NL80211_ATTR_IE]), 2728 memcpy((void *)request->ie,
2729 nla_data(info->attrs[NL80211_ATTR_IE]),
2558 request->ie_len); 2730 request->ie_len);
2559 } 2731 }
2560 2732
@@ -2710,6 +2882,15 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
2710 struct wiphy *wiphy; 2882 struct wiphy *wiphy;
2711 int err; 2883 int err;
2712 2884
2885 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
2886 return -EINVAL;
2887
2888 if (!info->attrs[NL80211_ATTR_MAC])
2889 return -EINVAL;
2890
2891 if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
2892 return -EINVAL;
2893
2713 rtnl_lock(); 2894 rtnl_lock();
2714 2895
2715 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 2896 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2731,11 +2912,6 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
2731 goto out; 2912 goto out;
2732 } 2913 }
2733 2914
2734 if (!info->attrs[NL80211_ATTR_MAC]) {
2735 err = -EINVAL;
2736 goto out;
2737 }
2738
2739 wiphy = &drv->wiphy; 2915 wiphy = &drv->wiphy;
2740 memset(&req, 0, sizeof(req)); 2916 memset(&req, 0, sizeof(req));
2741 2917
@@ -2761,13 +2937,10 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
2761 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 2937 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2762 } 2938 }
2763 2939
2764 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) { 2940 req.auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
2765 req.auth_type = 2941 if (!nl80211_valid_auth_type(req.auth_type)) {
2766 nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); 2942 err = -EINVAL;
2767 if (!nl80211_valid_auth_type(req.auth_type)) { 2943 goto out;
2768 err = -EINVAL;
2769 goto out;
2770 }
2771 } 2944 }
2772 2945
2773 err = drv->ops->auth(&drv->wiphy, dev, &req); 2946 err = drv->ops->auth(&drv->wiphy, dev, &req);
@@ -2788,6 +2961,13 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
2788 struct wiphy *wiphy; 2961 struct wiphy *wiphy;
2789 int err; 2962 int err;
2790 2963
2964 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
2965 return -EINVAL;
2966
2967 if (!info->attrs[NL80211_ATTR_MAC] ||
2968 !info->attrs[NL80211_ATTR_SSID])
2969 return -EINVAL;
2970
2791 rtnl_lock(); 2971 rtnl_lock();
2792 2972
2793 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 2973 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2809,12 +2989,6 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
2809 goto out; 2989 goto out;
2810 } 2990 }
2811 2991
2812 if (!info->attrs[NL80211_ATTR_MAC] ||
2813 !info->attrs[NL80211_ATTR_SSID]) {
2814 err = -EINVAL;
2815 goto out;
2816 }
2817
2818 wiphy = &drv->wiphy; 2992 wiphy = &drv->wiphy;
2819 memset(&req, 0, sizeof(req)); 2993 memset(&req, 0, sizeof(req));
2820 2994
@@ -2856,6 +3030,15 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
2856 struct wiphy *wiphy; 3030 struct wiphy *wiphy;
2857 int err; 3031 int err;
2858 3032
3033 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3034 return -EINVAL;
3035
3036 if (!info->attrs[NL80211_ATTR_MAC])
3037 return -EINVAL;
3038
3039 if (!info->attrs[NL80211_ATTR_REASON_CODE])
3040 return -EINVAL;
3041
2859 rtnl_lock(); 3042 rtnl_lock();
2860 3043
2861 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 3044 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2877,24 +3060,16 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
2877 goto out; 3060 goto out;
2878 } 3061 }
2879 3062
2880 if (!info->attrs[NL80211_ATTR_MAC]) {
2881 err = -EINVAL;
2882 goto out;
2883 }
2884
2885 wiphy = &drv->wiphy; 3063 wiphy = &drv->wiphy;
2886 memset(&req, 0, sizeof(req)); 3064 memset(&req, 0, sizeof(req));
2887 3065
2888 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 3066 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2889 3067
2890 if (info->attrs[NL80211_ATTR_REASON_CODE]) { 3068 req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
2891 req.reason_code = 3069 if (req.reason_code == 0) {
2892 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); 3070 /* Reason Code 0 is reserved */
2893 if (req.reason_code == 0) { 3071 err = -EINVAL;
2894 /* Reason Code 0 is reserved */ 3072 goto out;
2895 err = -EINVAL;
2896 goto out;
2897 }
2898 } 3073 }
2899 3074
2900 if (info->attrs[NL80211_ATTR_IE]) { 3075 if (info->attrs[NL80211_ATTR_IE]) {
@@ -2920,6 +3095,15 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
2920 struct wiphy *wiphy; 3095 struct wiphy *wiphy;
2921 int err; 3096 int err;
2922 3097
3098 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3099 return -EINVAL;
3100
3101 if (!info->attrs[NL80211_ATTR_MAC])
3102 return -EINVAL;
3103
3104 if (!info->attrs[NL80211_ATTR_REASON_CODE])
3105 return -EINVAL;
3106
2923 rtnl_lock(); 3107 rtnl_lock();
2924 3108
2925 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 3109 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2941,24 +3125,16 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
2941 goto out; 3125 goto out;
2942 } 3126 }
2943 3127
2944 if (!info->attrs[NL80211_ATTR_MAC]) {
2945 err = -EINVAL;
2946 goto out;
2947 }
2948
2949 wiphy = &drv->wiphy; 3128 wiphy = &drv->wiphy;
2950 memset(&req, 0, sizeof(req)); 3129 memset(&req, 0, sizeof(req));
2951 3130
2952 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 3131 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2953 3132
2954 if (info->attrs[NL80211_ATTR_REASON_CODE]) { 3133 req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
2955 req.reason_code = 3134 if (req.reason_code == 0) {
2956 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); 3135 /* Reason Code 0 is reserved */
2957 if (req.reason_code == 0) { 3136 err = -EINVAL;
2958 /* Reason Code 0 is reserved */ 3137 goto out;
2959 err = -EINVAL;
2960 goto out;
2961 }
2962 } 3138 }
2963 3139
2964 if (info->attrs[NL80211_ATTR_IE]) { 3140 if (info->attrs[NL80211_ATTR_IE]) {
@@ -2976,6 +3152,124 @@ unlock_rtnl:
2976 return err; 3152 return err;
2977} 3153}
2978 3154
3155static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
3156{
3157 struct cfg80211_registered_device *drv;
3158 struct net_device *dev;
3159 struct cfg80211_ibss_params ibss;
3160 struct wiphy *wiphy;
3161 int err;
3162
3163 memset(&ibss, 0, sizeof(ibss));
3164
3165 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3166 return -EINVAL;
3167
3168 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
3169 !info->attrs[NL80211_ATTR_SSID] ||
3170 !nla_len(info->attrs[NL80211_ATTR_SSID]))
3171 return -EINVAL;
3172
3173 ibss.beacon_interval = 100;
3174
3175 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
3176 ibss.beacon_interval =
3177 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
3178 if (ibss.beacon_interval < 1 || ibss.beacon_interval > 10000)
3179 return -EINVAL;
3180 }
3181
3182 rtnl_lock();
3183
3184 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
3185 if (err)
3186 goto unlock_rtnl;
3187
3188 if (!drv->ops->join_ibss) {
3189 err = -EOPNOTSUPP;
3190 goto out;
3191 }
3192
3193 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
3194 err = -EOPNOTSUPP;
3195 goto out;
3196 }
3197
3198 if (!netif_running(dev)) {
3199 err = -ENETDOWN;
3200 goto out;
3201 }
3202
3203 wiphy = &drv->wiphy;
3204
3205 if (info->attrs[NL80211_ATTR_MAC])
3206 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
3207 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
3208 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
3209
3210 if (info->attrs[NL80211_ATTR_IE]) {
3211 ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
3212 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3213 }
3214
3215 ibss.channel = ieee80211_get_channel(wiphy,
3216 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
3217 if (!ibss.channel ||
3218 ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
3219 ibss.channel->flags & IEEE80211_CHAN_DISABLED) {
3220 err = -EINVAL;
3221 goto out;
3222 }
3223
3224 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
3225
3226 err = cfg80211_join_ibss(drv, dev, &ibss);
3227
3228out:
3229 cfg80211_put_dev(drv);
3230 dev_put(dev);
3231unlock_rtnl:
3232 rtnl_unlock();
3233 return err;
3234}
3235
3236static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
3237{
3238 struct cfg80211_registered_device *drv;
3239 struct net_device *dev;
3240 int err;
3241
3242 rtnl_lock();
3243
3244 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
3245 if (err)
3246 goto unlock_rtnl;
3247
3248 if (!drv->ops->leave_ibss) {
3249 err = -EOPNOTSUPP;
3250 goto out;
3251 }
3252
3253 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
3254 err = -EOPNOTSUPP;
3255 goto out;
3256 }
3257
3258 if (!netif_running(dev)) {
3259 err = -ENETDOWN;
3260 goto out;
3261 }
3262
3263 err = cfg80211_leave_ibss(drv, dev, false);
3264
3265out:
3266 cfg80211_put_dev(drv);
3267 dev_put(dev);
3268unlock_rtnl:
3269 rtnl_unlock();
3270 return err;
3271}
3272
2979static struct genl_ops nl80211_ops[] = { 3273static struct genl_ops nl80211_ops[] = {
2980 { 3274 {
2981 .cmd = NL80211_CMD_GET_WIPHY, 3275 .cmd = NL80211_CMD_GET_WIPHY,
@@ -3177,6 +3471,18 @@ static struct genl_ops nl80211_ops[] = {
3177 .policy = nl80211_policy, 3471 .policy = nl80211_policy,
3178 .flags = GENL_ADMIN_PERM, 3472 .flags = GENL_ADMIN_PERM,
3179 }, 3473 },
3474 {
3475 .cmd = NL80211_CMD_JOIN_IBSS,
3476 .doit = nl80211_join_ibss,
3477 .policy = nl80211_policy,
3478 .flags = GENL_ADMIN_PERM,
3479 },
3480 {
3481 .cmd = NL80211_CMD_LEAVE_IBSS,
3482 .doit = nl80211_leave_ibss,
3483 .policy = nl80211_policy,
3484 .flags = GENL_ADMIN_PERM,
3485 },
3180}; 3486};
3181static struct genl_multicast_group nl80211_mlme_mcgrp = { 3487static struct genl_multicast_group nl80211_mlme_mcgrp = {
3182 .name = "mlme", 3488 .name = "mlme",
@@ -3375,22 +3681,197 @@ void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
3375 nl80211_send_mlme_event(rdev, netdev, buf, len, NL80211_CMD_ASSOCIATE); 3681 nl80211_send_mlme_event(rdev, netdev, buf, len, NL80211_CMD_ASSOCIATE);
3376} 3682}
3377 3683
3378void nl80211_send_rx_deauth(struct cfg80211_registered_device *rdev, 3684void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
3379 struct net_device *netdev, const u8 *buf, 3685 struct net_device *netdev, const u8 *buf, size_t len)
3380 size_t len)
3381{ 3686{
3382 nl80211_send_mlme_event(rdev, netdev, buf, len, 3687 nl80211_send_mlme_event(rdev, netdev, buf, len,
3383 NL80211_CMD_DEAUTHENTICATE); 3688 NL80211_CMD_DEAUTHENTICATE);
3384} 3689}
3385 3690
3386void nl80211_send_rx_disassoc(struct cfg80211_registered_device *rdev, 3691void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
3387 struct net_device *netdev, const u8 *buf, 3692 struct net_device *netdev, const u8 *buf,
3388 size_t len) 3693 size_t len)
3389{ 3694{
3390 nl80211_send_mlme_event(rdev, netdev, buf, len, 3695 nl80211_send_mlme_event(rdev, netdev, buf, len,
3391 NL80211_CMD_DISASSOCIATE); 3696 NL80211_CMD_DISASSOCIATE);
3392} 3697}
3393 3698
3699void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
3700 struct net_device *netdev, int cmd,
3701 const u8 *addr)
3702{
3703 struct sk_buff *msg;
3704 void *hdr;
3705
3706 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
3707 if (!msg)
3708 return;
3709
3710 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
3711 if (!hdr) {
3712 nlmsg_free(msg);
3713 return;
3714 }
3715
3716 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3717 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3718 NLA_PUT_FLAG(msg, NL80211_ATTR_TIMED_OUT);
3719 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
3720
3721 if (genlmsg_end(msg, hdr) < 0) {
3722 nlmsg_free(msg);
3723 return;
3724 }
3725
3726 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_ATOMIC);
3727 return;
3728
3729 nla_put_failure:
3730 genlmsg_cancel(msg, hdr);
3731 nlmsg_free(msg);
3732}
3733
3734void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
3735 struct net_device *netdev, const u8 *addr)
3736{
3737 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
3738 addr);
3739}
3740
3741void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
3742 struct net_device *netdev, const u8 *addr)
3743{
3744 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE, addr);
3745}
3746
3747void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
3748 struct net_device *netdev, const u8 *bssid,
3749 gfp_t gfp)
3750{
3751 struct sk_buff *msg;
3752 void *hdr;
3753
3754 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
3755 if (!msg)
3756 return;
3757
3758 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
3759 if (!hdr) {
3760 nlmsg_free(msg);
3761 return;
3762 }
3763
3764 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3765 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3766 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
3767
3768 if (genlmsg_end(msg, hdr) < 0) {
3769 nlmsg_free(msg);
3770 return;
3771 }
3772
3773 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp);
3774 return;
3775
3776 nla_put_failure:
3777 genlmsg_cancel(msg, hdr);
3778 nlmsg_free(msg);
3779}
3780
3781void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
3782 struct net_device *netdev, const u8 *addr,
3783 enum nl80211_key_type key_type, int key_id,
3784 const u8 *tsc)
3785{
3786 struct sk_buff *msg;
3787 void *hdr;
3788
3789 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
3790 if (!msg)
3791 return;
3792
3793 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
3794 if (!hdr) {
3795 nlmsg_free(msg);
3796 return;
3797 }
3798
3799 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3800 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3801 if (addr)
3802 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
3803 NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE, key_type);
3804 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_id);
3805 if (tsc)
3806 NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc);
3807
3808 if (genlmsg_end(msg, hdr) < 0) {
3809 nlmsg_free(msg);
3810 return;
3811 }
3812
3813 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_KERNEL);
3814 return;
3815
3816 nla_put_failure:
3817 genlmsg_cancel(msg, hdr);
3818 nlmsg_free(msg);
3819}
3820
3821void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
3822 struct ieee80211_channel *channel_before,
3823 struct ieee80211_channel *channel_after)
3824{
3825 struct sk_buff *msg;
3826 void *hdr;
3827 struct nlattr *nl_freq;
3828
3829 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
3830 if (!msg)
3831 return;
3832
3833 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
3834 if (!hdr) {
3835 nlmsg_free(msg);
3836 return;
3837 }
3838
3839 /*
3840 * Since we are applying the beacon hint to a wiphy we know its
3841 * wiphy_idx is valid
3842 */
3843 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy));
3844
3845 /* Before */
3846 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE);
3847 if (!nl_freq)
3848 goto nla_put_failure;
3849 if (nl80211_msg_put_channel(msg, channel_before))
3850 goto nla_put_failure;
3851 nla_nest_end(msg, nl_freq);
3852
3853 /* After */
3854 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER);
3855 if (!nl_freq)
3856 goto nla_put_failure;
3857 if (nl80211_msg_put_channel(msg, channel_after))
3858 goto nla_put_failure;
3859 nla_nest_end(msg, nl_freq);
3860
3861 if (genlmsg_end(msg, hdr) < 0) {
3862 nlmsg_free(msg);
3863 return;
3864 }
3865
3866 genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_ATOMIC);
3867
3868 return;
3869
3870nla_put_failure:
3871 genlmsg_cancel(msg, hdr);
3872 nlmsg_free(msg);
3873}
3874
3394/* initialisation/exit functions */ 3875/* initialisation/exit functions */
3395 3876
3396int nl80211_init(void) 3877int nl80211_init(void)
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index b77af4ab80be..5c12ad13499b 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -17,11 +17,31 @@ extern void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
17extern void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev, 17extern void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
18 struct net_device *netdev, 18 struct net_device *netdev,
19 const u8 *buf, size_t len); 19 const u8 *buf, size_t len);
20extern void nl80211_send_rx_deauth(struct cfg80211_registered_device *rdev, 20extern void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
21 struct net_device *netdev, 21 struct net_device *netdev,
22 const u8 *buf, size_t len); 22 const u8 *buf, size_t len);
23extern void nl80211_send_rx_disassoc(struct cfg80211_registered_device *rdev, 23extern void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
24 struct net_device *netdev, 24 struct net_device *netdev,
25 const u8 *buf, size_t len); 25 const u8 *buf, size_t len);
26extern void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
27 struct net_device *netdev,
28 const u8 *addr);
29extern void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
30 struct net_device *netdev,
31 const u8 *addr);
32extern void
33nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
34 struct net_device *netdev, const u8 *addr,
35 enum nl80211_key_type key_type,
36 int key_id, const u8 *tsc);
37
38extern void
39nl80211_send_beacon_hint_event(struct wiphy *wiphy,
40 struct ieee80211_channel *channel_before,
41 struct ieee80211_channel *channel_after);
42
43void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
44 struct net_device *netdev, const u8 *bssid,
45 gfp_t gfp);
26 46
27#endif /* __NET_WIRELESS_NL80211_H */ 47#endif /* __NET_WIRELESS_NL80211_H */
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 6c1993d99902..f38cc39fa79e 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -37,7 +37,6 @@
37#include <linux/random.h> 37#include <linux/random.h>
38#include <linux/nl80211.h> 38#include <linux/nl80211.h>
39#include <linux/platform_device.h> 39#include <linux/platform_device.h>
40#include <net/wireless.h>
41#include <net/cfg80211.h> 40#include <net/cfg80211.h>
42#include "core.h" 41#include "core.h"
43#include "reg.h" 42#include "reg.h"
@@ -1049,18 +1048,10 @@ static void handle_reg_beacon(struct wiphy *wiphy,
1049 unsigned int chan_idx, 1048 unsigned int chan_idx,
1050 struct reg_beacon *reg_beacon) 1049 struct reg_beacon *reg_beacon)
1051{ 1050{
1052#ifdef CONFIG_CFG80211_REG_DEBUG
1053#define REG_DEBUG_BEACON_FLAG(desc) \
1054 printk(KERN_DEBUG "cfg80211: Enabling " desc " on " \
1055 "frequency: %d MHz (Ch %d) on %s\n", \
1056 reg_beacon->chan.center_freq, \
1057 ieee80211_frequency_to_channel(reg_beacon->chan.center_freq), \
1058 wiphy_name(wiphy));
1059#else
1060#define REG_DEBUG_BEACON_FLAG(desc) do {} while (0)
1061#endif
1062 struct ieee80211_supported_band *sband; 1051 struct ieee80211_supported_band *sband;
1063 struct ieee80211_channel *chan; 1052 struct ieee80211_channel *chan;
1053 bool channel_changed = false;
1054 struct ieee80211_channel chan_before;
1064 1055
1065 assert_cfg80211_lock(); 1056 assert_cfg80211_lock();
1066 1057
@@ -1070,18 +1061,28 @@ static void handle_reg_beacon(struct wiphy *wiphy,
1070 if (likely(chan->center_freq != reg_beacon->chan.center_freq)) 1061 if (likely(chan->center_freq != reg_beacon->chan.center_freq))
1071 return; 1062 return;
1072 1063
1073 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) { 1064 if (chan->beacon_found)
1065 return;
1066
1067 chan->beacon_found = true;
1068
1069 chan_before.center_freq = chan->center_freq;
1070 chan_before.flags = chan->flags;
1071
1072 if ((chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
1073 !(chan->orig_flags & IEEE80211_CHAN_PASSIVE_SCAN)) {
1074 chan->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 1074 chan->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
1075 REG_DEBUG_BEACON_FLAG("active scanning"); 1075 channel_changed = true;
1076 } 1076 }
1077 1077
1078 if (chan->flags & IEEE80211_CHAN_NO_IBSS) { 1078 if ((chan->flags & IEEE80211_CHAN_NO_IBSS) &&
1079 !(chan->orig_flags & IEEE80211_CHAN_NO_IBSS)) {
1079 chan->flags &= ~IEEE80211_CHAN_NO_IBSS; 1080 chan->flags &= ~IEEE80211_CHAN_NO_IBSS;
1080 REG_DEBUG_BEACON_FLAG("beaconing"); 1081 channel_changed = true;
1081 } 1082 }
1082 1083
1083 chan->beacon_found = true; 1084 if (channel_changed)
1084#undef REG_DEBUG_BEACON_FLAG 1085 nl80211_send_beacon_hint_event(wiphy, &chan_before, chan);
1085} 1086}
1086 1087
1087/* 1088/*
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 2ae65b39b529..723aeb3d9462 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -414,6 +414,55 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
414 return found; 414 return found;
415} 415}
416 416
417struct cfg80211_bss*
418cfg80211_inform_bss(struct wiphy *wiphy,
419 struct ieee80211_channel *channel,
420 const u8 *bssid,
421 u64 timestamp, u16 capability, u16 beacon_interval,
422 const u8 *ie, size_t ielen,
423 s32 signal, gfp_t gfp)
424{
425 struct cfg80211_internal_bss *res;
426 size_t privsz;
427
428 if (WARN_ON(!wiphy))
429 return NULL;
430
431 privsz = wiphy->bss_priv_size;
432
433 if (WARN_ON(wiphy->signal_type == NL80211_BSS_SIGNAL_UNSPEC &&
434 (signal < 0 || signal > 100)))
435 return NULL;
436
437 res = kzalloc(sizeof(*res) + privsz + ielen, gfp);
438 if (!res)
439 return NULL;
440
441 memcpy(res->pub.bssid, bssid, ETH_ALEN);
442 res->pub.channel = channel;
443 res->pub.signal = signal;
444 res->pub.tsf = timestamp;
445 res->pub.beacon_interval = beacon_interval;
446 res->pub.capability = capability;
447 /* point to after the private area */
448 res->pub.information_elements = (u8 *)res + sizeof(*res) + privsz;
449 memcpy(res->pub.information_elements, ie, ielen);
450 res->pub.len_information_elements = ielen;
451
452 kref_init(&res->ref);
453
454 res = cfg80211_bss_update(wiphy_to_dev(wiphy), res, 0);
455 if (!res)
456 return NULL;
457
458 if (res->pub.capability & WLAN_CAPABILITY_ESS)
459 regulatory_hint_found_beacon(wiphy, channel, gfp);
460
461 /* cfg80211_bss_update gives us a referenced result */
462 return &res->pub;
463}
464EXPORT_SYMBOL(cfg80211_inform_bss);
465
417struct cfg80211_bss * 466struct cfg80211_bss *
418cfg80211_inform_bss_frame(struct wiphy *wiphy, 467cfg80211_inform_bss_frame(struct wiphy *wiphy,
419 struct ieee80211_channel *channel, 468 struct ieee80211_channel *channel,
@@ -604,7 +653,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
604 cfg80211_put_dev(rdev); 653 cfg80211_put_dev(rdev);
605 return err; 654 return err;
606} 655}
607EXPORT_SYMBOL(cfg80211_wext_siwscan); 656EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan);
608 657
609static void ieee80211_scan_add_ies(struct iw_request_info *info, 658static void ieee80211_scan_add_ies(struct iw_request_info *info,
610 struct cfg80211_bss *bss, 659 struct cfg80211_bss *bss,
@@ -913,5 +962,5 @@ int cfg80211_wext_giwscan(struct net_device *dev,
913 cfg80211_put_dev(rdev); 962 cfg80211_put_dev(rdev);
914 return res; 963 return res;
915} 964}
916EXPORT_SYMBOL(cfg80211_wext_giwscan); 965EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan);
917#endif 966#endif
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 487cdd9bcffc..5f7e997195c7 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * Wireless utility functions 2 * Wireless utility functions
3 * 3 *
4 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2007-2009 Johannes Berg <johannes@sipsolutions.net>
5 */ 5 */
6#include <net/wireless.h> 6#include <linux/bitops.h>
7#include <asm/bitops.h> 7#include <net/cfg80211.h>
8#include "core.h" 8#include "core.h"
9 9
10struct ieee80211_rate * 10struct ieee80211_rate *
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 0fd1db6e95bb..5ef82f2ca88f 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -10,8 +10,8 @@
10 10
11#include <linux/wireless.h> 11#include <linux/wireless.h>
12#include <linux/nl80211.h> 12#include <linux/nl80211.h>
13#include <linux/if_arp.h>
13#include <net/iw_handler.h> 14#include <net/iw_handler.h>
14#include <net/wireless.h>
15#include <net/cfg80211.h> 15#include <net/cfg80211.h>
16#include "core.h" 16#include "core.h"
17 17
@@ -57,7 +57,7 @@ int cfg80211_wext_giwname(struct net_device *dev,
57 57
58 return 0; 58 return 0;
59} 59}
60EXPORT_SYMBOL(cfg80211_wext_giwname); 60EXPORT_SYMBOL_GPL(cfg80211_wext_giwname);
61 61
62int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info, 62int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
63 u32 *mode, char *extra) 63 u32 *mode, char *extra)
@@ -108,7 +108,7 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
108 108
109 return ret; 109 return ret;
110} 110}
111EXPORT_SYMBOL(cfg80211_wext_siwmode); 111EXPORT_SYMBOL_GPL(cfg80211_wext_siwmode);
112 112
113int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info, 113int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
114 u32 *mode, char *extra) 114 u32 *mode, char *extra)
@@ -143,7 +143,7 @@ int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
143 } 143 }
144 return 0; 144 return 0;
145} 145}
146EXPORT_SYMBOL(cfg80211_wext_giwmode); 146EXPORT_SYMBOL_GPL(cfg80211_wext_giwmode);
147 147
148 148
149int cfg80211_wext_giwrange(struct net_device *dev, 149int cfg80211_wext_giwrange(struct net_device *dev,
@@ -206,7 +206,6 @@ int cfg80211_wext_giwrange(struct net_device *dev,
206 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | 206 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
207 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; 207 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
208 208
209
210 for (band = 0; band < IEEE80211_NUM_BANDS; band ++) { 209 for (band = 0; band < IEEE80211_NUM_BANDS; band ++) {
211 int i; 210 int i;
212 struct ieee80211_supported_band *sband; 211 struct ieee80211_supported_band *sband;
@@ -240,4 +239,229 @@ int cfg80211_wext_giwrange(struct net_device *dev,
240 239
241 return 0; 240 return 0;
242} 241}
243EXPORT_SYMBOL(cfg80211_wext_giwrange); 242EXPORT_SYMBOL_GPL(cfg80211_wext_giwrange);
243
244int cfg80211_wext_siwmlme(struct net_device *dev,
245 struct iw_request_info *info,
246 struct iw_point *data, char *extra)
247{
248 struct wireless_dev *wdev = dev->ieee80211_ptr;
249 struct iw_mlme *mlme = (struct iw_mlme *)extra;
250 struct cfg80211_registered_device *rdev;
251 union {
252 struct cfg80211_disassoc_request disassoc;
253 struct cfg80211_deauth_request deauth;
254 } cmd;
255
256 if (!wdev)
257 return -EOPNOTSUPP;
258
259 rdev = wiphy_to_dev(wdev->wiphy);
260
261 if (wdev->iftype != NL80211_IFTYPE_STATION)
262 return -EINVAL;
263
264 if (mlme->addr.sa_family != ARPHRD_ETHER)
265 return -EINVAL;
266
267 memset(&cmd, 0, sizeof(cmd));
268
269 switch (mlme->cmd) {
270 case IW_MLME_DEAUTH:
271 if (!rdev->ops->deauth)
272 return -EOPNOTSUPP;
273 cmd.deauth.peer_addr = mlme->addr.sa_data;
274 cmd.deauth.reason_code = mlme->reason_code;
275 return rdev->ops->deauth(wdev->wiphy, dev, &cmd.deauth);
276 case IW_MLME_DISASSOC:
277 if (!rdev->ops->disassoc)
278 return -EOPNOTSUPP;
279 cmd.disassoc.peer_addr = mlme->addr.sa_data;
280 cmd.disassoc.reason_code = mlme->reason_code;
281 return rdev->ops->disassoc(wdev->wiphy, dev, &cmd.disassoc);
282 default:
283 return -EOPNOTSUPP;
284 }
285}
286EXPORT_SYMBOL_GPL(cfg80211_wext_siwmlme);
287
288
289/**
290 * cfg80211_wext_freq - get wext frequency for non-"auto"
291 * @wiphy: the wiphy
292 * @freq: the wext freq encoding
293 *
294 * Returns a channel, %NULL for auto, or an ERR_PTR for errors!
295 */
296struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
297 struct iw_freq *freq)
298{
299 if (freq->e == 0) {
300 if (freq->m < 0)
301 return NULL;
302 else
303 return ieee80211_get_channel(wiphy,
304 ieee80211_channel_to_frequency(freq->m));
305 } else {
306 int i, div = 1000000;
307 for (i = 0; i < freq->e; i++)
308 div /= 10;
309 if (div > 0)
310 return ieee80211_get_channel(wiphy, freq->m / div);
311 else
312 return ERR_PTR(-EINVAL);
313 }
314
315}
316EXPORT_SYMBOL_GPL(cfg80211_wext_freq);
317
318int cfg80211_wext_siwrts(struct net_device *dev,
319 struct iw_request_info *info,
320 struct iw_param *rts, char *extra)
321{
322 struct wireless_dev *wdev = dev->ieee80211_ptr;
323 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
324 u32 orts = wdev->wiphy->rts_threshold;
325 int err;
326
327 if (rts->disabled || !rts->fixed)
328 wdev->wiphy->rts_threshold = (u32) -1;
329 else if (rts->value < 0)
330 return -EINVAL;
331 else
332 wdev->wiphy->rts_threshold = rts->value;
333
334 err = rdev->ops->set_wiphy_params(wdev->wiphy,
335 WIPHY_PARAM_RTS_THRESHOLD);
336 if (err)
337 wdev->wiphy->rts_threshold = orts;
338
339 return err;
340}
341EXPORT_SYMBOL_GPL(cfg80211_wext_siwrts);
342
343int cfg80211_wext_giwrts(struct net_device *dev,
344 struct iw_request_info *info,
345 struct iw_param *rts, char *extra)
346{
347 struct wireless_dev *wdev = dev->ieee80211_ptr;
348
349 rts->value = wdev->wiphy->rts_threshold;
350 rts->disabled = rts->value == (u32) -1;
351 rts->fixed = 1;
352
353 return 0;
354}
355EXPORT_SYMBOL_GPL(cfg80211_wext_giwrts);
356
357int cfg80211_wext_siwfrag(struct net_device *dev,
358 struct iw_request_info *info,
359 struct iw_param *frag, char *extra)
360{
361 struct wireless_dev *wdev = dev->ieee80211_ptr;
362 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
363 u32 ofrag = wdev->wiphy->frag_threshold;
364 int err;
365
366 if (frag->disabled || !frag->fixed)
367 wdev->wiphy->frag_threshold = (u32) -1;
368 else if (frag->value < 256)
369 return -EINVAL;
370 else {
371 /* Fragment length must be even, so strip LSB. */
372 wdev->wiphy->frag_threshold = frag->value & ~0x1;
373 }
374
375 err = rdev->ops->set_wiphy_params(wdev->wiphy,
376 WIPHY_PARAM_FRAG_THRESHOLD);
377 if (err)
378 wdev->wiphy->frag_threshold = ofrag;
379
380 return err;
381}
382EXPORT_SYMBOL_GPL(cfg80211_wext_siwfrag);
383
384int cfg80211_wext_giwfrag(struct net_device *dev,
385 struct iw_request_info *info,
386 struct iw_param *frag, char *extra)
387{
388 struct wireless_dev *wdev = dev->ieee80211_ptr;
389
390 frag->value = wdev->wiphy->frag_threshold;
391 frag->disabled = frag->value == (u32) -1;
392 frag->fixed = 1;
393
394 return 0;
395}
396EXPORT_SYMBOL_GPL(cfg80211_wext_giwfrag);
397
398int cfg80211_wext_siwretry(struct net_device *dev,
399 struct iw_request_info *info,
400 struct iw_param *retry, char *extra)
401{
402 struct wireless_dev *wdev = dev->ieee80211_ptr;
403 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
404 u32 changed = 0;
405 u8 olong = wdev->wiphy->retry_long;
406 u8 oshort = wdev->wiphy->retry_short;
407 int err;
408
409 if (retry->disabled ||
410 (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
411 return -EINVAL;
412
413 if (retry->flags & IW_RETRY_LONG) {
414 wdev->wiphy->retry_long = retry->value;
415 changed |= WIPHY_PARAM_RETRY_LONG;
416 } else if (retry->flags & IW_RETRY_SHORT) {
417 wdev->wiphy->retry_short = retry->value;
418 changed |= WIPHY_PARAM_RETRY_SHORT;
419 } else {
420 wdev->wiphy->retry_short = retry->value;
421 wdev->wiphy->retry_long = retry->value;
422 changed |= WIPHY_PARAM_RETRY_LONG;
423 changed |= WIPHY_PARAM_RETRY_SHORT;
424 }
425
426 if (!changed)
427 return 0;
428
429 err = rdev->ops->set_wiphy_params(wdev->wiphy, changed);
430 if (err) {
431 wdev->wiphy->retry_short = oshort;
432 wdev->wiphy->retry_long = olong;
433 }
434
435 return err;
436}
437EXPORT_SYMBOL_GPL(cfg80211_wext_siwretry);
438
439int cfg80211_wext_giwretry(struct net_device *dev,
440 struct iw_request_info *info,
441 struct iw_param *retry, char *extra)
442{
443 struct wireless_dev *wdev = dev->ieee80211_ptr;
444
445 retry->disabled = 0;
446
447 if (retry->flags == 0 || (retry->flags & IW_RETRY_SHORT)) {
448 /*
449 * First return short value, iwconfig will ask long value
450 * later if needed
451 */
452 retry->flags |= IW_RETRY_LIMIT;
453 retry->value = wdev->wiphy->retry_short;
454 if (wdev->wiphy->retry_long != wdev->wiphy->retry_short)
455 retry->flags |= IW_RETRY_LONG;
456
457 return 0;
458 }
459
460 if (retry->flags & IW_RETRY_LONG) {
461 retry->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
462 retry->value = wdev->wiphy->retry_long;
463 }
464
465 return 0;
466}
467EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry);