aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/mlme.c90
-rw-r--r--net/mac80211/rx.c4
2 files changed, 64 insertions, 30 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 75510a9f3f1d..c396c3522f7b 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2557,6 +2557,33 @@ u64 ieee80211_sta_get_rates(struct ieee80211_local *local,
2557 return supp_rates; 2557 return supp_rates;
2558} 2558}
2559 2559
2560static u64 ieee80211_sta_get_mandatory_rates(struct ieee80211_local *local,
2561 enum ieee80211_band band)
2562{
2563 struct ieee80211_supported_band *sband;
2564 struct ieee80211_rate *bitrates;
2565 u64 mandatory_rates;
2566 enum ieee80211_rate_flags mandatory_flag;
2567 int i;
2568
2569 sband = local->hw.wiphy->bands[band];
2570 if (!sband) {
2571 WARN_ON(1);
2572 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
2573 }
2574
2575 if (band == IEEE80211_BAND_2GHZ)
2576 mandatory_flag = IEEE80211_RATE_MANDATORY_B;
2577 else
2578 mandatory_flag = IEEE80211_RATE_MANDATORY_A;
2579
2580 bitrates = sband->bitrates;
2581 mandatory_rates = 0;
2582 for (i = 0; i < sband->n_bitrates; i++)
2583 if (bitrates[i].flags & mandatory_flag)
2584 mandatory_rates |= BIT(i);
2585 return mandatory_rates;
2586}
2560 2587
2561static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, 2588static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2562 struct ieee80211_mgmt *mgmt, 2589 struct ieee80211_mgmt *mgmt,
@@ -2568,9 +2595,11 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2568 int freq, clen; 2595 int freq, clen;
2569 struct ieee80211_sta_bss *bss; 2596 struct ieee80211_sta_bss *bss;
2570 struct sta_info *sta; 2597 struct sta_info *sta;
2571 u64 beacon_timestamp, rx_timestamp;
2572 struct ieee80211_channel *channel; 2598 struct ieee80211_channel *channel;
2599 u64 beacon_timestamp, rx_timestamp;
2600 u64 supp_rates = 0;
2573 bool beacon = ieee80211_is_beacon(mgmt->frame_control); 2601 bool beacon = ieee80211_is_beacon(mgmt->frame_control);
2602 enum ieee80211_band band = rx_status->band;
2574 DECLARE_MAC_BUF(mac); 2603 DECLARE_MAC_BUF(mac);
2575 DECLARE_MAC_BUF(mac2); 2604 DECLARE_MAC_BUF(mac2);
2576 2605
@@ -2578,30 +2607,41 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2578 2607
2579 if (ieee80211_vif_is_mesh(&sdata->vif) && elems->mesh_id && 2608 if (ieee80211_vif_is_mesh(&sdata->vif) && elems->mesh_id &&
2580 elems->mesh_config && mesh_matches_local(elems, sdata)) { 2609 elems->mesh_config && mesh_matches_local(elems, sdata)) {
2581 u64 rates = ieee80211_sta_get_rates(local, elems, 2610 supp_rates = ieee80211_sta_get_rates(local, elems, band);
2582 rx_status->band);
2583 2611
2584 mesh_neighbour_update(mgmt->sa, rates, sdata, 2612 mesh_neighbour_update(mgmt->sa, supp_rates, sdata,
2585 mesh_peer_accepts_plinks(elems)); 2613 mesh_peer_accepts_plinks(elems));
2586 } 2614 }
2587 2615
2588 rcu_read_lock(); 2616 rcu_read_lock();
2589 2617
2590 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems->supp_rates && 2618 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems->supp_rates &&
2591 memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && 2619 memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) {
2592 (sta = sta_info_get(local, mgmt->sa))) { 2620
2593 u64 prev_rates; 2621 supp_rates = ieee80211_sta_get_rates(local, elems, band);
2594 u64 supp_rates = ieee80211_sta_get_rates(local, elems, 2622
2595 rx_status->band); 2623 sta = sta_info_get(local, mgmt->sa);
2596 2624 if (sta) {
2597 prev_rates = sta->supp_rates[rx_status->band]; 2625 u64 prev_rates;
2598 sta->supp_rates[rx_status->band] = supp_rates; 2626
2599 if (sta->supp_rates[rx_status->band] == 0) { 2627 prev_rates = sta->supp_rates[band];
2600 /* No matching rates - this should not really happen. 2628 /* make sure mandatory rates are always added */
2601 * Make sure that at least one rate is marked 2629 sta->supp_rates[band] = supp_rates |
2602 * supported to avoid issues with TX rate ctrl. */ 2630 ieee80211_sta_get_mandatory_rates(local, band);
2603 sta->supp_rates[rx_status->band] = 2631
2604 sdata->u.sta.supp_rates_bits[rx_status->band]; 2632#ifdef CONFIG_MAC80211_IBSS_DEBUG
2633 if (sta->supp_rates[band] != prev_rates)
2634 printk(KERN_DEBUG "%s: updated supp_rates set "
2635 "for %s based on beacon info (0x%llx | "
2636 "0x%llx -> 0x%llx)\n",
2637 sdata->dev->name, print_mac(mac, sta->addr),
2638 (unsigned long long) prev_rates,
2639 (unsigned long long) supp_rates,
2640 (unsigned long long) sta->supp_rates[band]);
2641#endif
2642 } else {
2643 ieee80211_ibss_add_sta(sdata, NULL, mgmt->bssid,
2644 mgmt->sa, supp_rates);
2605 } 2645 }
2606 } 2646 }
2607 2647
@@ -2683,7 +2723,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2683 bss->supp_rates_len += clen; 2723 bss->supp_rates_len += clen;
2684 } 2724 }
2685 2725
2686 bss->band = rx_status->band; 2726 bss->band = band;
2687 2727
2688 bss->timestamp = beacon_timestamp; 2728 bss->timestamp = beacon_timestamp;
2689 bss->last_update = jiffies; 2729 bss->last_update = jiffies;
@@ -2738,7 +2778,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2738 * e.g: at 1 MBit that means mactime is 192 usec earlier 2778 * e.g: at 1 MBit that means mactime is 192 usec earlier
2739 * (=24 bytes * 8 usecs/byte) than the beacon timestamp. 2779 * (=24 bytes * 8 usecs/byte) than the beacon timestamp.
2740 */ 2780 */
2741 int rate = local->hw.wiphy->bands[rx_status->band]-> 2781 int rate = local->hw.wiphy->bands[band]->
2742 bitrates[rx_status->rate_idx].bitrate; 2782 bitrates[rx_status->rate_idx].bitrate;
2743 rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate); 2783 rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate);
2744 } else if (local && local->ops && local->ops->get_tsf) 2784 } else if (local && local->ops && local->ops->get_tsf)
@@ -2766,7 +2806,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2766 ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss); 2806 ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss);
2767 ieee80211_ibss_add_sta(sdata, NULL, 2807 ieee80211_ibss_add_sta(sdata, NULL,
2768 mgmt->bssid, mgmt->sa, 2808 mgmt->bssid, mgmt->sa,
2769 BIT(rx_status->rate_idx)); 2809 supp_rates);
2770 } 2810 }
2771 } 2811 }
2772 2812
@@ -3032,7 +3072,6 @@ void ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *
3032 kfree_skb(skb); 3072 kfree_skb(skb);
3033} 3073}
3034 3074
3035
3036static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, 3075static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
3037 struct sk_buff *skb) 3076 struct sk_buff *skb)
3038{ 3077{
@@ -4316,10 +4355,9 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
4316 4355
4317 set_sta_flags(sta, WLAN_STA_AUTHORIZED); 4356 set_sta_flags(sta, WLAN_STA_AUTHORIZED);
4318 4357
4319 if (supp_rates) 4358 /* make sure mandatory rates are always added */
4320 sta->supp_rates[band] = supp_rates; 4359 sta->supp_rates[band] = supp_rates |
4321 else 4360 ieee80211_sta_get_mandatory_rates(local, band);
4322 sta->supp_rates[band] = sdata->u.sta.supp_rates_bits[band];
4323 4361
4324 rate_control_rate_init(sta, local); 4362 rate_control_rate_init(sta, local);
4325 4363
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index fd83ef760a37..7e09b30dd393 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1743,10 +1743,6 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
1743 if (!bssid) 1743 if (!bssid)
1744 return 0; 1744 return 0;
1745 if (ieee80211_is_beacon(hdr->frame_control)) { 1745 if (ieee80211_is_beacon(hdr->frame_control)) {
1746 if (!rx->sta)
1747 rx->sta = ieee80211_ibss_add_sta(sdata,
1748 rx->skb, bssid, hdr->addr2,
1749 BIT(rx->status->rate_idx));
1750 return 1; 1746 return 1;
1751 } 1747 }
1752 else if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) { 1748 else if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) {