~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to net/mac80211/mlme.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
#include "rate.h"
29
29
#include "led.h"
30
30
 
31
 
#define IEEE80211_MAX_NULLFUNC_TRIES 2
32
 
#define IEEE80211_MAX_PROBE_TRIES 5
 
31
static int max_nullfunc_tries = 2;
 
32
module_param(max_nullfunc_tries, int, 0644);
 
33
MODULE_PARM_DESC(max_nullfunc_tries,
 
34
                 "Maximum nullfunc tx tries before disconnecting (reason 4).");
 
35
 
 
36
static int max_probe_tries = 5;
 
37
module_param(max_probe_tries, int, 0644);
 
38
MODULE_PARM_DESC(max_probe_tries,
 
39
                 "Maximum probe tries before disconnecting (reason 4).");
33
40
 
34
41
/*
35
42
 * Beacon loss timeout is calculated as N frames times the
51
58
 * a probe request because of beacon loss or for
52
59
 * checking the connection still works.
53
60
 */
54
 
#define IEEE80211_PROBE_WAIT            (HZ / 2)
 
61
static int probe_wait_ms = 500;
 
62
module_param(probe_wait_ms, int, 0644);
 
63
MODULE_PARM_DESC(probe_wait_ms,
 
64
                 "Maximum time(ms) to wait for probe response"
 
65
                 " before disconnecting (reason 4).");
55
66
 
56
67
/*
57
68
 * Weight given to the latest Beacon frame when calculating average signal
79
90
        /* no action required */
80
91
        RX_MGMT_NONE,
81
92
 
82
 
        /* caller must call cfg80211_send_rx_auth() */
83
 
        RX_MGMT_CFG80211_AUTH,
84
 
 
85
 
        /* caller must call cfg80211_send_rx_assoc() */
86
 
        RX_MGMT_CFG80211_ASSOC,
87
 
 
88
93
        /* caller must call cfg80211_send_deauth() */
89
94
        RX_MGMT_CFG80211_DEAUTH,
90
95
 
91
96
        /* caller must call cfg80211_send_disassoc() */
92
97
        RX_MGMT_CFG80211_DISASSOC,
93
 
 
94
 
        /* caller must tell cfg80211 about internal error */
95
 
        RX_MGMT_CFG80211_ASSOC_ERROR,
96
98
};
97
99
 
98
100
/* utils */
134
136
{
135
137
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
136
138
 
 
139
        if (unlikely(!sdata->u.mgd.associated))
 
140
                return;
 
141
 
137
142
        if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
138
143
                return;
139
144
 
161
166
        struct ieee80211_supported_band *sband;
162
167
        struct sta_info *sta;
163
168
        u32 changed = 0;
 
169
        int hti_cfreq;
164
170
        u16 ht_opmode;
165
171
        bool enable_ht = true;
166
172
        enum nl80211_channel_type prev_chantype;
174
180
        if (!sband->ht_cap.ht_supported)
175
181
                enable_ht = false;
176
182
 
177
 
        /* check that channel matches the right operating channel */
178
 
        if (local->hw.conf.channel->center_freq !=
179
 
            ieee80211_channel_to_frequency(hti->control_chan))
180
 
                enable_ht = false;
 
183
        if (enable_ht) {
 
184
                hti_cfreq = ieee80211_channel_to_frequency(hti->control_chan,
 
185
                                                           sband->band);
 
186
                /* check that channel matches the right operating channel */
 
187
                if (local->hw.conf.channel->center_freq != hti_cfreq) {
 
188
                        /* Some APs mess this up, evidently.
 
189
                         * Netgear WNDR3700 sometimes reports 4 higher than
 
190
                         * the actual channel, for instance.
 
191
                         */
 
192
                        printk(KERN_DEBUG
 
193
                               "%s: Wrong control channel in association"
 
194
                               " response: configured center-freq: %d"
 
195
                               " hti-cfreq: %d  hti->control_chan: %d"
 
196
                               " band: %d.  Disabling HT.\n",
 
197
                               sdata->name,
 
198
                               local->hw.conf.channel->center_freq,
 
199
                               hti_cfreq, hti->control_chan,
 
200
                               sband->band);
 
201
                        enable_ht = false;
 
202
                }
 
203
        }
181
204
 
182
205
        if (enable_ht) {
183
206
                channel_type = NL80211_CHAN_HT20;
429
452
                container_of((void *)bss, struct cfg80211_bss, priv);
430
453
        struct ieee80211_channel *new_ch;
431
454
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
432
 
        int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num);
 
455
        int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num,
 
456
                                                      cbss->channel->band);
433
457
 
434
458
        ASSERT_MGD_MTX(ifmgd);
435
459
 
580
604
        }
581
605
}
582
606
 
 
607
static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata)
 
608
{
 
609
        struct ieee80211_if_managed *mgd = &sdata->u.mgd;
 
610
        struct sta_info *sta = NULL;
 
611
        u32 sta_flags = 0;
 
612
 
 
613
        if (!mgd->powersave)
 
614
                return false;
 
615
 
 
616
        if (!mgd->associated)
 
617
                return false;
 
618
 
 
619
        if (!mgd->associated->beacon_ies)
 
620
                return false;
 
621
 
 
622
        if (mgd->flags & (IEEE80211_STA_BEACON_POLL |
 
623
                          IEEE80211_STA_CONNECTION_POLL))
 
624
                return false;
 
625
 
 
626
        rcu_read_lock();
 
627
        sta = sta_info_get(sdata, mgd->bssid);
 
628
        if (sta)
 
629
                sta_flags = get_sta_flags(sta);
 
630
        rcu_read_unlock();
 
631
 
 
632
        if (!(sta_flags & WLAN_STA_AUTHORIZED))
 
633
                return false;
 
634
 
 
635
        return true;
 
636
}
 
637
 
583
638
/* need to hold RTNL or interface lock */
584
639
void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
585
640
{
600
655
        list_for_each_entry(sdata, &local->interfaces, list) {
601
656
                if (!ieee80211_sdata_running(sdata))
602
657
                        continue;
 
658
                if (sdata->vif.type == NL80211_IFTYPE_AP) {
 
659
                        /* If an AP vif is found, then disable PS
 
660
                         * by setting the count to zero thereby setting
 
661
                         * ps_sdata to NULL.
 
662
                         */
 
663
                        count = 0;
 
664
                        break;
 
665
                }
603
666
                if (sdata->vif.type != NL80211_IFTYPE_STATION)
604
667
                        continue;
605
668
                found = sdata;
606
669
                count++;
607
670
        }
608
671
 
609
 
        if (count == 1 && found->u.mgd.powersave &&
610
 
            found->u.mgd.associated &&
611
 
            found->u.mgd.associated->beacon_ies &&
612
 
            !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL |
613
 
                                    IEEE80211_STA_CONNECTION_POLL))) {
 
672
        if (count == 1 && ieee80211_powersave_allowed(found)) {
614
673
                struct ieee80211_conf *conf = &local->hw.conf;
615
674
                s32 beaconint_us;
616
675
 
691
750
                             dynamic_ps_enable_work);
692
751
        struct ieee80211_sub_if_data *sdata = local->ps_sdata;
693
752
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 
753
        unsigned long flags;
 
754
        int q;
694
755
 
695
756
        /* can only happen when PS was just disabled anyway */
696
757
        if (!sdata)
699
760
        if (local->hw.conf.flags & IEEE80211_CONF_PS)
700
761
                return;
701
762
 
 
763
        /*
 
764
         * transmission can be stopped by others which leads to
 
765
         * dynamic_ps_timer expiry. Postpond the ps timer if it
 
766
         * is not the actual idle state.
 
767
         */
 
768
        spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
 
769
        for (q = 0; q < local->hw.queues; q++) {
 
770
                if (local->queue_stop_reasons[q]) {
 
771
                        spin_unlock_irqrestore(&local->queue_stop_reason_lock,
 
772
                                               flags);
 
773
                        mod_timer(&local->dynamic_ps_timer, jiffies +
 
774
                                  msecs_to_jiffies(
 
775
                                  local->hw.conf.dynamic_ps_timeout));
 
776
                        return;
 
777
                }
 
778
        }
 
779
        spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
 
780
 
702
781
        if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
703
 
            (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)))
704
 
                ieee80211_send_nullfunc(local, sdata, 1);
 
782
            (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) {
 
783
                netif_tx_stop_all_queues(sdata->dev);
 
784
 
 
785
                if (drv_tx_frames_pending(local))
 
786
                        mod_timer(&local->dynamic_ps_timer, jiffies +
 
787
                                  msecs_to_jiffies(
 
788
                                  local->hw.conf.dynamic_ps_timeout));
 
789
                else {
 
790
                        ieee80211_send_nullfunc(local, sdata, 1);
 
791
                        /* Flush to get the tx status of nullfunc frame */
 
792
                        drv_flush(local, false);
 
793
                }
 
794
        }
705
795
 
706
796
        if (!((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) &&
707
797
              (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)) ||
710
800
                local->hw.conf.flags |= IEEE80211_CONF_PS;
711
801
                ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
712
802
        }
 
803
 
 
804
        netif_tx_wake_all_queues(sdata->dev);
713
805
}
714
806
 
715
807
void ieee80211_dynamic_ps_timer(unsigned long data)
997
1089
                local->hw.conf.flags &= ~IEEE80211_CONF_PS;
998
1090
                config_changed |= IEEE80211_CONF_CHANGE_PS;
999
1091
        }
 
1092
        local->ps_sdata = NULL;
1000
1093
 
1001
1094
        ieee80211_hw_config(local, config_changed);
1002
1095
 
1033
1126
        if (is_multicast_ether_addr(hdr->addr1))
1034
1127
                return;
1035
1128
 
1036
 
        /*
1037
 
         * In case we receive frames after disassociation.
1038
 
         */
1039
 
        if (!sdata->u.mgd.associated)
1040
 
                return;
1041
 
 
1042
1129
        ieee80211_sta_reset_conn_monitor(sdata);
1043
1130
}
1044
1131
 
1095
1182
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1096
1183
        const u8 *ssid;
1097
1184
        u8 *dst = ifmgd->associated->bssid;
1098
 
        u8 unicast_limit = max(1, IEEE80211_MAX_PROBE_TRIES - 3);
 
1185
        u8 unicast_limit = max(1, max_probe_tries - 3);
1099
1186
 
1100
1187
        /*
1101
1188
         * Try sending broadcast probe requests for the last three
1121
1208
        }
1122
1209
 
1123
1210
        ifmgd->probe_send_count++;
1124
 
        ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT;
 
1211
        ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms);
1125
1212
        run_again(ifmgd, ifmgd->probe_timeout);
1126
1213
}
1127
1214
 
1222
1309
 
1223
1310
        memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
1224
1311
 
1225
 
        printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid);
 
1312
        printk(KERN_DEBUG "%s: Connection to AP %pM lost.\n",
 
1313
               sdata->name, bssid);
1226
1314
 
1227
1315
        ieee80211_set_disassoc(sdata, true, true);
1228
1316
        mutex_unlock(&ifmgd->mtx);
1525
1613
        }
1526
1614
 
1527
1615
        if (elems->ds_params && elems->ds_params_len == 1)
1528
 
                freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
 
1616
                freq = ieee80211_channel_to_frequency(elems->ds_params[0],
 
1617
                                                      rx_status->band);
1529
1618
        else
1530
1619
                freq = rx_status->freq;
1531
1620
 
1966
2055
                memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
1967
2056
 
1968
2057
                if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
1969
 
                        max_tries = IEEE80211_MAX_NULLFUNC_TRIES;
 
2058
                        max_tries = max_nullfunc_tries;
1970
2059
                else
1971
 
                        max_tries = IEEE80211_MAX_PROBE_TRIES;
 
2060
                        max_tries = max_probe_tries;
1972
2061
 
1973
2062
                /* ACK received for nullfunc probing frame */
1974
2063
                if (!ifmgd->probe_send_count)
1978
2067
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1979
2068
                                wiphy_debug(local->hw.wiphy,
1980
2069
                                            "%s: No ack for nullfunc frame to"
1981
 
                                            " AP %pM, try %d\n",
 
2070
                                            " AP %pM, try %d/%i\n",
1982
2071
                                            sdata->name, bssid,
1983
 
                                            ifmgd->probe_send_count);
 
2072
                                            ifmgd->probe_send_count, max_tries);
1984
2073
#endif
1985
2074
                                ieee80211_mgd_probe_ap_send(sdata);
1986
2075
                        } else {
2000
2089
                                    "%s: Failed to send nullfunc to AP %pM"
2001
2090
                                    " after %dms, disconnecting.\n",
2002
2091
                                    sdata->name,
2003
 
                                    bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
 
2092
                                    bssid, probe_wait_ms);
2004
2093
#endif
2005
2094
                        ieee80211_sta_connection_lost(sdata, bssid);
2006
2095
                } else if (ifmgd->probe_send_count < max_tries) {
2007
2096
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
2008
2097
                        wiphy_debug(local->hw.wiphy,
2009
2098
                                    "%s: No probe response from AP %pM"
2010
 
                                    " after %dms, try %d\n",
 
2099
                                    " after %dms, try %d/%i\n",
2011
2100
                                    sdata->name,
2012
 
                                    bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ,
2013
 
                                    ifmgd->probe_send_count);
 
2101
                                    bssid, probe_wait_ms,
 
2102
                                    ifmgd->probe_send_count, max_tries);
2014
2103
#endif
2015
2104
                        ieee80211_mgd_probe_ap_send(sdata);
2016
2105
                } else {
2022
2111
                                    "%s: No probe response from AP %pM"
2023
2112
                                    " after %dms, disconnecting.\n",
2024
2113
                                    sdata->name,
2025
 
                                    bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
 
2114
                                    bssid, probe_wait_ms);
2026
2115
 
2027
2116
                        ieee80211_sta_connection_lost(sdata, bssid);
2028
2117
                }
2260
2349
        else
2261
2350
                wk->type = IEEE80211_WORK_DIRECT_PROBE;
2262
2351
        wk->chan = req->bss->channel;
 
2352
        wk->chan_type = NL80211_CHAN_NO_HT;
2263
2353
        wk->sdata = sdata;
2264
2354
        wk->done = ieee80211_probe_auth_done;
2265
2355
 
2409
2499
                memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN);
2410
2500
 
2411
2501
        wk->chan = req->bss->channel;
 
2502
        wk->chan_type = NL80211_CHAN_NO_HT;
2412
2503
        wk->sdata = sdata;
2413
2504
        wk->done = ieee80211_assoc_done;
2414
2505
        if (!bss->dtim_period &&