aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2008-09-03 16:42:20 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-08 14:22:46 -0400
commit8e1535d51bc93fbe9b3ded6555680044bc571d19 (patch)
tree74fa1729b2fe5e9928930edd65d92859b57eecd7
parent9818babc8fd9a542978a235f1c1786f948cbac68 (diff)
mac80211: Fix rate scale initialization in IBSS
This patch address some IBSS rate issues introduced or not covered by "mac80211: eliminate IBSS warning in rate_lowest_index()" and "cfg80211 API for channels/bitrates, mac80211 and driver conversion". This patch: 1. Moves addition of IBSS station from prepare_for_handlers to ieee80211_rx_bss_info when triggered from beacon eliminating bogus supported rates. 2. Initialize properly supported rates also in IBSS merging 3. Ensure that mandatory rates are always added into supported rates. This is needed in case when station addition is triggered from non beacon/probe packet. Some management frames need to be sent 4. Remove initialization of supported rates from self rates. This path was dead code after 6bc37c06bc4 and in general incorrect. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Cc: Vladimir Koutny <vlado@work.ksp.sk> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-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)) {