diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/mlme.c | 90 | ||||
-rw-r--r-- | net/mac80211/rx.c | 4 |
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 | ||
2560 | static 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 | ||
2561 | static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | 2588 | static 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 | |||
3036 | static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | 3075 | static 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)) { |