aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-11-09 14:49:23 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-11-09 14:49:23 -0500
commit5e819059a20b0fc5a71875f28b4cae359e38d85a (patch)
treeb94a18142abc5e60c84f90ee2490e8a6af01c2a9 /net/mac80211
parentae2772b313b98a14f69b5bc67135c9fee48771be (diff)
parentcc438fccd5783c9f7b4c4858358ac897dcf8a58d (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c12
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/main.c2
-rw-r--r--net/mac80211/mlme.c39
-rw-r--r--net/mac80211/scan.c2
-rw-r--r--net/mac80211/sta_info.c8
-rw-r--r--net/mac80211/work.c7
7 files changed, 52 insertions, 19 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 000a8ba987cd..65b72ae2b4e0 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -832,6 +832,12 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
832 if (is_multicast_ether_addr(mac)) 832 if (is_multicast_ether_addr(mac))
833 return -EINVAL; 833 return -EINVAL;
834 834
835 /* Only TDLS-supporting stations can add TDLS peers */
836 if ((params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
837 !((wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
838 sdata->vif.type == NL80211_IFTYPE_STATION))
839 return -ENOTSUPP;
840
835 sta = sta_info_alloc(sdata, mac, GFP_KERNEL); 841 sta = sta_info_alloc(sdata, mac, GFP_KERNEL);
836 if (!sta) 842 if (!sta)
837 return -ENOMEM; 843 return -ENOMEM;
@@ -841,12 +847,6 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
841 847
842 sta_apply_parameters(local, sta, params); 848 sta_apply_parameters(local, sta, params);
843 849
844 /* Only TDLS-supporting stations can add TDLS peers */
845 if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) &&
846 !((wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
847 sdata->vif.type == NL80211_IFTYPE_STATION))
848 return -ENOTSUPP;
849
850 rate_control_rate_init(sta); 850 rate_control_rate_init(sta);
851 851
852 layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN || 852 layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 30fc9e7c5c53..e2447096c94a 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -389,6 +389,7 @@ struct ieee80211_if_managed {
389 389
390 unsigned long timers_running; /* used for quiesce/restart */ 390 unsigned long timers_running; /* used for quiesce/restart */
391 bool powersave; /* powersave requested for this iface */ 391 bool powersave; /* powersave requested for this iface */
392 bool broken_ap; /* AP is broken -- turn off powersave */
392 enum ieee80211_smps_mode req_smps, /* requested smps mode */ 393 enum ieee80211_smps_mode req_smps, /* requested smps mode */
393 ap_smps, /* smps mode AP thinks we're in */ 394 ap_smps, /* smps mode AP thinks we're in */
394 driver_smps_mode; /* smps mode request */ 395 driver_smps_mode; /* smps mode request */
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index d4ee6d234a78..d999bf3b84e1 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -19,7 +19,7 @@
19#include <linux/if_arp.h> 19#include <linux/if_arp.h>
20#include <linux/rtnetlink.h> 20#include <linux/rtnetlink.h>
21#include <linux/bitmap.h> 21#include <linux/bitmap.h>
22#include <linux/pm_qos_params.h> 22#include <linux/pm_qos.h>
23#include <linux/inetdevice.h> 23#include <linux/inetdevice.h>
24#include <net/net_namespace.h> 24#include <net/net_namespace.h>
25#include <net/cfg80211.h> 25#include <net/cfg80211.h>
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 0e5d8daba1ee..d3b408cda08d 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -17,7 +17,7 @@
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> 20#include <linux/pm_qos.h>
21#include <linux/crc32.h> 21#include <linux/crc32.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <net/mac80211.h> 23#include <net/mac80211.h>
@@ -637,6 +637,9 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata)
637 if (!mgd->powersave) 637 if (!mgd->powersave)
638 return false; 638 return false;
639 639
640 if (mgd->broken_ap)
641 return false;
642
640 if (!mgd->associated) 643 if (!mgd->associated)
641 return false; 644 return false;
642 645
@@ -1482,6 +1485,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1482 int i, j, err; 1485 int i, j, err;
1483 bool have_higher_than_11mbit = false; 1486 bool have_higher_than_11mbit = false;
1484 u16 ap_ht_cap_flags; 1487 u16 ap_ht_cap_flags;
1488 int min_rate = INT_MAX, min_rate_index = -1;
1485 1489
1486 /* AssocResp and ReassocResp have identical structure */ 1490 /* AssocResp and ReassocResp have identical structure */
1487 1491
@@ -1489,10 +1493,21 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1489 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); 1493 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
1490 1494
1491 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) 1495 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
1492 printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not " 1496 printk(KERN_DEBUG
1493 "set\n", sdata->name, aid); 1497 "%s: invalid AID value 0x%x; bits 15:14 not set\n",
1498 sdata->name, aid);
1494 aid &= ~(BIT(15) | BIT(14)); 1499 aid &= ~(BIT(15) | BIT(14));
1495 1500
1501 ifmgd->broken_ap = false;
1502
1503 if (aid == 0 || aid > IEEE80211_MAX_AID) {
1504 printk(KERN_DEBUG
1505 "%s: invalid AID value %d (out of range), turn off PS\n",
1506 sdata->name, aid);
1507 aid = 0;
1508 ifmgd->broken_ap = true;
1509 }
1510
1496 pos = mgmt->u.assoc_resp.variable; 1511 pos = mgmt->u.assoc_resp.variable;
1497 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); 1512 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1498 1513
@@ -1537,6 +1552,10 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1537 rates |= BIT(j); 1552 rates |= BIT(j);
1538 if (is_basic) 1553 if (is_basic)
1539 basic_rates |= BIT(j); 1554 basic_rates |= BIT(j);
1555 if (rate < min_rate) {
1556 min_rate = rate;
1557 min_rate_index = j;
1558 }
1540 break; 1559 break;
1541 } 1560 }
1542 } 1561 }
@@ -1554,11 +1573,25 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1554 rates |= BIT(j); 1573 rates |= BIT(j);
1555 if (is_basic) 1574 if (is_basic)
1556 basic_rates |= BIT(j); 1575 basic_rates |= BIT(j);
1576 if (rate < min_rate) {
1577 min_rate = rate;
1578 min_rate_index = j;
1579 }
1557 break; 1580 break;
1558 } 1581 }
1559 } 1582 }
1560 } 1583 }
1561 1584
1585 /*
1586 * some buggy APs don't advertise basic_rates. use the lowest
1587 * supported rate instead.
1588 */
1589 if (unlikely(!basic_rates) && min_rate_index >= 0) {
1590 printk(KERN_DEBUG "%s: No basic rates in AssocResp. "
1591 "Using min supported rate instead.\n", sdata->name);
1592 basic_rates = BIT(min_rate_index);
1593 }
1594
1562 sta->sta.supp_rates[wk->chan->band] = rates; 1595 sta->sta.supp_rates[wk->chan->band] = rates;
1563 sdata->vif.bss_conf.basic_rates = basic_rates; 1596 sdata->vif.bss_conf.basic_rates = basic_rates;
1564 1597
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 397343a59275..83a0b050b374 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -14,7 +14,7 @@
14 14
15#include <linux/if_arp.h> 15#include <linux/if_arp.h>
16#include <linux/rtnetlink.h> 16#include <linux/rtnetlink.h>
17#include <linux/pm_qos_params.h> 17#include <linux/pm_qos.h>
18#include <net/sch_generic.h> 18#include <net/sch_generic.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <net/mac80211.h> 20#include <net/mac80211.h>
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index ce962d2c8782..8eaa746ec7a2 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1354,12 +1354,12 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta,
1354 * Use MoreData flag to indicate whether there are 1354 * Use MoreData flag to indicate whether there are
1355 * more buffered frames for this STA 1355 * more buffered frames for this STA
1356 */ 1356 */
1357 if (!more_data) 1357 if (more_data || !skb_queue_empty(&frames))
1358 hdr->frame_control &=
1359 cpu_to_le16(~IEEE80211_FCTL_MOREDATA);
1360 else
1361 hdr->frame_control |= 1358 hdr->frame_control |=
1362 cpu_to_le16(IEEE80211_FCTL_MOREDATA); 1359 cpu_to_le16(IEEE80211_FCTL_MOREDATA);
1360 else
1361 hdr->frame_control &=
1362 cpu_to_le16(~IEEE80211_FCTL_MOREDATA);
1363 1363
1364 if (ieee80211_is_data_qos(hdr->frame_control) || 1364 if (ieee80211_is_data_qos(hdr->frame_control) ||
1365 ieee80211_is_qos_nullfunc(hdr->frame_control)) 1365 ieee80211_is_qos_nullfunc(hdr->frame_control))
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index fab5092e3788..30da4e3f19f7 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -1057,14 +1057,13 @@ static void ieee80211_work_work(struct work_struct *work)
1057 continue; 1057 continue;
1058 if (wk->chan != local->tmp_channel) 1058 if (wk->chan != local->tmp_channel)
1059 continue; 1059 continue;
1060 if (ieee80211_work_ct_coexists(wk->chan_type, 1060 if (!ieee80211_work_ct_coexists(wk->chan_type,
1061 local->tmp_channel_type)) 1061 local->tmp_channel_type))
1062 continue; 1062 continue;
1063 remain_off_channel = true; 1063 remain_off_channel = true;
1064 } 1064 }
1065 1065
1066 if (!remain_off_channel && local->tmp_channel) { 1066 if (!remain_off_channel && local->tmp_channel) {
1067 bool on_oper_chan = ieee80211_cfg_on_oper_channel(local);
1068 local->tmp_channel = NULL; 1067 local->tmp_channel = NULL;
1069 /* If tmp_channel wasn't operating channel, then 1068 /* If tmp_channel wasn't operating channel, then
1070 * we need to go back on-channel. 1069 * we need to go back on-channel.
@@ -1074,7 +1073,7 @@ static void ieee80211_work_work(struct work_struct *work)
1074 * we still need to do a hardware config. Currently, 1073 * we still need to do a hardware config. Currently,
1075 * we cannot be here while scanning, however. 1074 * we cannot be here while scanning, however.
1076 */ 1075 */
1077 if (ieee80211_cfg_on_oper_channel(local) && !on_oper_chan) 1076 if (!ieee80211_cfg_on_oper_channel(local))
1078 ieee80211_hw_config(local, 0); 1077 ieee80211_hw_config(local, 0);
1079 1078
1080 /* At the least, we need to disable offchannel_ps, 1079 /* At the least, we need to disable offchannel_ps,