diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-11-09 14:49:23 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-11-09 14:49:23 -0500 |
commit | 5e819059a20b0fc5a71875f28b4cae359e38d85a (patch) | |
tree | b94a18142abc5e60c84f90ee2490e8a6af01c2a9 /net/mac80211 | |
parent | ae2772b313b98a14f69b5bc67135c9fee48771be (diff) | |
parent | cc438fccd5783c9f7b4c4858358ac897dcf8a58d (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.c | 12 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 1 | ||||
-rw-r--r-- | net/mac80211/main.c | 2 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 39 | ||||
-rw-r--r-- | net/mac80211/scan.c | 2 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 8 | ||||
-rw-r--r-- | net/mac80211/work.c | 7 |
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, |