diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/mlme.c | 21 | ||||
-rw-r--r-- | net/mac80211/rx.c | 9 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 8 | ||||
-rw-r--r-- | net/mac80211/util.c | 4 |
4 files changed, 34 insertions, 8 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 72c8bea81a6c..b1b1bb368f70 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1487,6 +1487,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, | |||
1487 | int i, j, err; | 1487 | int i, j, err; |
1488 | bool have_higher_than_11mbit = false; | 1488 | bool have_higher_than_11mbit = false; |
1489 | u16 ap_ht_cap_flags; | 1489 | u16 ap_ht_cap_flags; |
1490 | int min_rate = INT_MAX, min_rate_index = -1; | ||
1490 | 1491 | ||
1491 | /* AssocResp and ReassocResp have identical structure */ | 1492 | /* AssocResp and ReassocResp have identical structure */ |
1492 | 1493 | ||
@@ -1553,6 +1554,10 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, | |||
1553 | rates |= BIT(j); | 1554 | rates |= BIT(j); |
1554 | if (is_basic) | 1555 | if (is_basic) |
1555 | basic_rates |= BIT(j); | 1556 | basic_rates |= BIT(j); |
1557 | if (rate < min_rate) { | ||
1558 | min_rate = rate; | ||
1559 | min_rate_index = j; | ||
1560 | } | ||
1556 | break; | 1561 | break; |
1557 | } | 1562 | } |
1558 | } | 1563 | } |
@@ -1570,11 +1575,25 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, | |||
1570 | rates |= BIT(j); | 1575 | rates |= BIT(j); |
1571 | if (is_basic) | 1576 | if (is_basic) |
1572 | basic_rates |= BIT(j); | 1577 | basic_rates |= BIT(j); |
1578 | if (rate < min_rate) { | ||
1579 | min_rate = rate; | ||
1580 | min_rate_index = j; | ||
1581 | } | ||
1573 | break; | 1582 | break; |
1574 | } | 1583 | } |
1575 | } | 1584 | } |
1576 | } | 1585 | } |
1577 | 1586 | ||
1587 | /* | ||
1588 | * some buggy APs don't advertise basic_rates. use the lowest | ||
1589 | * supported rate instead. | ||
1590 | */ | ||
1591 | if (unlikely(!basic_rates) && min_rate_index >= 0) { | ||
1592 | printk(KERN_DEBUG "%s: No basic rates in AssocResp. " | ||
1593 | "Using min supported rate instead.\n", sdata->name); | ||
1594 | basic_rates = BIT(min_rate_index); | ||
1595 | } | ||
1596 | |||
1578 | sta->sta.supp_rates[wk->chan->band] = rates; | 1597 | sta->sta.supp_rates[wk->chan->band] = rates; |
1579 | sdata->vif.bss_conf.basic_rates = basic_rates; | 1598 | sdata->vif.bss_conf.basic_rates = basic_rates; |
1580 | 1599 | ||
@@ -2269,6 +2288,7 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata) | |||
2269 | 2288 | ||
2270 | cancel_work_sync(&ifmgd->request_smps_work); | 2289 | cancel_work_sync(&ifmgd->request_smps_work); |
2271 | 2290 | ||
2291 | cancel_work_sync(&ifmgd->monitor_work); | ||
2272 | cancel_work_sync(&ifmgd->beacon_connection_loss_work); | 2292 | cancel_work_sync(&ifmgd->beacon_connection_loss_work); |
2273 | if (del_timer_sync(&ifmgd->timer)) | 2293 | if (del_timer_sync(&ifmgd->timer)) |
2274 | set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); | 2294 | set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); |
@@ -2277,7 +2297,6 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata) | |||
2277 | if (del_timer_sync(&ifmgd->chswitch_timer)) | 2297 | if (del_timer_sync(&ifmgd->chswitch_timer)) |
2278 | set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running); | 2298 | set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running); |
2279 | 2299 | ||
2280 | cancel_work_sync(&ifmgd->monitor_work); | ||
2281 | /* these will just be re-established on connection */ | 2300 | /* these will just be re-established on connection */ |
2282 | del_timer_sync(&ifmgd->conn_mon_timer); | 2301 | del_timer_sync(&ifmgd->conn_mon_timer); |
2283 | del_timer_sync(&ifmgd->bcn_mon_timer); | 2302 | del_timer_sync(&ifmgd->bcn_mon_timer); |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index bb53726cb04a..fb123e2e081a 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -141,8 +141,9 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
141 | pos++; | 141 | pos++; |
142 | 142 | ||
143 | /* IEEE80211_RADIOTAP_RATE */ | 143 | /* IEEE80211_RADIOTAP_RATE */ |
144 | if (status->flag & RX_FLAG_HT) { | 144 | if (!rate || status->flag & RX_FLAG_HT) { |
145 | /* | 145 | /* |
146 | * Without rate information don't add it. If we have, | ||
146 | * MCS information is a separate field in radiotap, | 147 | * MCS information is a separate field in radiotap, |
147 | * added below. The byte here is needed as padding | 148 | * added below. The byte here is needed as padding |
148 | * for the channel though, so initialise it to 0. | 149 | * for the channel though, so initialise it to 0. |
@@ -163,12 +164,14 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
163 | else if (status->flag & RX_FLAG_HT) | 164 | else if (status->flag & RX_FLAG_HT) |
164 | put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ, | 165 | put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ, |
165 | pos); | 166 | pos); |
166 | else if (rate->flags & IEEE80211_RATE_ERP_G) | 167 | else if (rate && rate->flags & IEEE80211_RATE_ERP_G) |
167 | put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ, | 168 | put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ, |
168 | pos); | 169 | pos); |
169 | else | 170 | else if (rate) |
170 | put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ, | 171 | put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ, |
171 | pos); | 172 | pos); |
173 | else | ||
174 | put_unaligned_le16(IEEE80211_CHAN_2GHZ, pos); | ||
172 | pos += 2; | 175 | pos += 2; |
173 | 176 | ||
174 | /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ | 177 | /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ |
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/util.c b/net/mac80211/util.c index 51e256c5fb78..eca0fad09709 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -881,6 +881,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, | |||
881 | skb = ieee80211_probereq_get(&local->hw, &sdata->vif, | 881 | skb = ieee80211_probereq_get(&local->hw, &sdata->vif, |
882 | ssid, ssid_len, | 882 | ssid, ssid_len, |
883 | buf, buf_len); | 883 | buf, buf_len); |
884 | if (!skb) | ||
885 | goto out; | ||
884 | 886 | ||
885 | if (dst) { | 887 | if (dst) { |
886 | mgmt = (struct ieee80211_mgmt *) skb->data; | 888 | mgmt = (struct ieee80211_mgmt *) skb->data; |
@@ -889,6 +891,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, | |||
889 | } | 891 | } |
890 | 892 | ||
891 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 893 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
894 | |||
895 | out: | ||
892 | kfree(buf); | 896 | kfree(buf); |
893 | 897 | ||
894 | return skb; | 898 | return skb; |