~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to net/mac80211/work.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno
  • Date: 2011-06-07 12:14:05 UTC
  • mfrom: (43.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20110607121405-i3h1rd7nrnd2b73h
Tags: 2.6.39-2
[ Ben Hutchings ]
* [x86] Enable BACKLIGHT_APPLE, replacing BACKLIGHT_MBP_NVIDIA
  (Closes: #627492)
* cgroups: Disable memory resource controller by default. Allow it
  to be enabled using kernel parameter 'cgroup_enable=memory'.
* rt2800usb: Enable support for more USB devices including
  Linksys WUSB600N (Closes: #596626) (this change was accidentally
  omitted from 2.6.39-1)
* [x86] Remove Celeron from list of processors supporting PAE. Most
  'Celeron M' models do not.
* Update debconf template translations:
  - Swedish (Martin Bagge) (Closes: #628932)
  - French (David Prévot) (Closes: #628191)
* aufs: Update for 2.6.39 (Closes: #627837)
* Add stable 2.6.39.1, including:
  - ext4: dont set PageUptodate in ext4_end_bio()
  - pata_cmd64x: fix boot crash on parisc (Closes: #622997, #622745)
  - ext3: Fix fs corruption when make_indexed_dir() fails
  - netfilter: nf_ct_sip: validate Content-Length in TCP SIP messages
  - sctp: fix race between sctp_bind_addr_free() and
    sctp_bind_addr_conflict()
  - sctp: fix memory leak of the ASCONF queue when free asoc
  - md/bitmap: fix saving of events_cleared and other state
  - cdc_acm: Fix oops when Droids MuIn LCD is connected
  - cx88: Fix conversion from BKL to fine-grained locks (Closes: #619827)
  - keys: Set cred->user_ns in key_replace_session_keyring (CVE-2011-2184)
  - tmpfs: fix race between truncate and writepage
  - nfs41: Correct offset for LAYOUTCOMMIT
  - xen/mmu: fix a race window causing leave_mm BUG()
  - ext4: fix possible use-after-free in ext4_remove_li_request()
  For the complete list of changes, see:
   http://www.kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.39.1
* Bump ABI to 2
* netfilter: Enable IP_SET, IP_SET_BITMAP_IP, IP_SET_BITMAP_IPMAC,
  IP_SET_BITMAP_PORT, IP_SET_HASH_IP, IP_SET_HASH_IPPORT,
  IP_SET_HASH_IPPORTIP, IP_SET_HASH_IPPORTNET, IP_SET_HASH_NET,
  IP_SET_HASH_NETPORT, IP_SET_LIST_SET, NETFILTER_XT_SET as modules
  (Closes: #629401)

[ Aurelien Jarno ]
* [mipsel/loongson-2f] Disable_SCSI_LPFC to workaround GCC ICE.

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
#define IEEE80211_AUTH_MAX_TRIES 3
31
31
#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
32
32
#define IEEE80211_ASSOC_MAX_TRIES 3
33
 
#define IEEE80211_MAX_PROBE_TRIES 5
34
33
 
35
34
enum work_action {
36
35
        WORK_ACT_MISMATCH,
126
125
 
127
126
        /* determine capability flags */
128
127
 
129
 
        if (ieee80211_disable_40mhz_24ghz &&
130
 
            sband->band == IEEE80211_BAND_2GHZ) {
131
 
                cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
132
 
                cap &= ~IEEE80211_HT_CAP_SGI_40;
133
 
        }
134
 
 
135
128
        switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
136
129
        case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
137
130
                if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
874
867
        kfree_skb(skb);
875
868
}
876
869
 
 
870
static bool ieee80211_work_ct_coexists(enum nl80211_channel_type wk_ct,
 
871
                                       enum nl80211_channel_type oper_ct)
 
872
{
 
873
        switch (wk_ct) {
 
874
        case NL80211_CHAN_NO_HT:
 
875
                return true;
 
876
        case NL80211_CHAN_HT20:
 
877
                if (oper_ct != NL80211_CHAN_NO_HT)
 
878
                        return true;
 
879
                return false;
 
880
        case NL80211_CHAN_HT40MINUS:
 
881
        case NL80211_CHAN_HT40PLUS:
 
882
                return (wk_ct == oper_ct);
 
883
        }
 
884
        WARN_ON(1); /* shouldn't get here */
 
885
        return false;
 
886
}
 
887
 
 
888
static enum nl80211_channel_type
 
889
ieee80211_calc_ct(enum nl80211_channel_type wk_ct,
 
890
                  enum nl80211_channel_type oper_ct)
 
891
{
 
892
        switch (wk_ct) {
 
893
        case NL80211_CHAN_NO_HT:
 
894
                return oper_ct;
 
895
        case NL80211_CHAN_HT20:
 
896
                if (oper_ct != NL80211_CHAN_NO_HT)
 
897
                        return oper_ct;
 
898
                return wk_ct;
 
899
        case NL80211_CHAN_HT40MINUS:
 
900
        case NL80211_CHAN_HT40PLUS:
 
901
                return wk_ct;
 
902
        }
 
903
        WARN_ON(1); /* shouldn't get here */
 
904
        return wk_ct;
 
905
}
 
906
 
 
907
 
877
908
static void ieee80211_work_timer(unsigned long data)
878
909
{
879
910
        struct ieee80211_local *local = (void *) data;
924
955
                }
925
956
 
926
957
                if (!started && !local->tmp_channel) {
927
 
                        /*
928
 
                         * TODO: could optimize this by leaving the
929
 
                         *       station vifs in awake mode if they
930
 
                         *       happen to be on the same channel as
931
 
                         *       the requested channel
932
 
                         */
933
 
                        ieee80211_offchannel_stop_beaconing(local);
934
 
                        ieee80211_offchannel_stop_station(local);
 
958
                        bool on_oper_chan;
 
959
                        bool tmp_chan_changed = false;
 
960
                        bool on_oper_chan2;
 
961
                        enum nl80211_channel_type wk_ct;
 
962
                        on_oper_chan = ieee80211_cfg_on_oper_channel(local);
 
963
 
 
964
                        /* Work with existing channel type if possible. */
 
965
                        wk_ct = wk->chan_type;
 
966
                        if (wk->chan == local->hw.conf.channel)
 
967
                                wk_ct = ieee80211_calc_ct(wk->chan_type,
 
968
                                                local->hw.conf.channel_type);
 
969
 
 
970
                        if (local->tmp_channel)
 
971
                                if ((local->tmp_channel != wk->chan) ||
 
972
                                    (local->tmp_channel_type != wk_ct))
 
973
                                        tmp_chan_changed = true;
935
974
 
936
975
                        local->tmp_channel = wk->chan;
937
 
                        local->tmp_channel_type = wk->chan_type;
938
 
                        ieee80211_hw_config(local, 0);
 
976
                        local->tmp_channel_type = wk_ct;
 
977
                        /*
 
978
                         * Leave the station vifs in awake mode if they
 
979
                         * happen to be on the same channel as
 
980
                         * the requested channel.
 
981
                         */
 
982
                        on_oper_chan2 = ieee80211_cfg_on_oper_channel(local);
 
983
                        if (on_oper_chan != on_oper_chan2) {
 
984
                                if (on_oper_chan2) {
 
985
                                        /* going off oper channel, PS too */
 
986
                                        ieee80211_offchannel_stop_vifs(local,
 
987
                                                                       true);
 
988
                                        ieee80211_hw_config(local, 0);
 
989
                                } else {
 
990
                                        /* going on channel, but leave PS
 
991
                                         * off-channel. */
 
992
                                        ieee80211_hw_config(local, 0);
 
993
                                        ieee80211_offchannel_return(local,
 
994
                                                                    true,
 
995
                                                                    false);
 
996
                                }
 
997
                        } else if (tmp_chan_changed)
 
998
                                /* Still off-channel, but on some other
 
999
                                 * channel, so update hardware.
 
1000
                                 * PS should already be off-channel.
 
1001
                                 */
 
1002
                                ieee80211_hw_config(local, 0);
 
1003
 
939
1004
                        started = true;
940
1005
                        wk->timeout = jiffies;
941
1006
                }
1005
1070
                        continue;
1006
1071
                if (wk->chan != local->tmp_channel)
1007
1072
                        continue;
1008
 
                if (wk->chan_type != local->tmp_channel_type)
 
1073
                if (ieee80211_work_ct_coexists(wk->chan_type,
 
1074
                                               local->tmp_channel_type))
1009
1075
                        continue;
1010
1076
                remain_off_channel = true;
1011
1077
        }
1012
1078
 
1013
1079
        if (!remain_off_channel && local->tmp_channel) {
 
1080
                bool on_oper_chan = ieee80211_cfg_on_oper_channel(local);
1014
1081
                local->tmp_channel = NULL;
1015
 
                ieee80211_hw_config(local, 0);
1016
 
                ieee80211_offchannel_return(local, true);
 
1082
                /* If tmp_channel wasn't operating channel, then
 
1083
                 * we need to go back on-channel.
 
1084
                 * NOTE:  If we can ever be here while scannning,
 
1085
                 * or if the hw_config() channel config logic changes,
 
1086
                 * then we may need to do a more thorough check to see if
 
1087
                 * we still need to do a hardware config.  Currently,
 
1088
                 * we cannot be here while scanning, however.
 
1089
                 */
 
1090
                if (ieee80211_cfg_on_oper_channel(local) && !on_oper_chan)
 
1091
                        ieee80211_hw_config(local, 0);
 
1092
 
 
1093
                /* At the least, we need to disable offchannel_ps,
 
1094
                 * so just go ahead and run the entire offchannel
 
1095
                 * return logic here.  We *could* skip enabling
 
1096
                 * beaconing if we were already on-oper-channel
 
1097
                 * as a future optimization.
 
1098
                 */
 
1099
                ieee80211_offchannel_return(local, true, true);
 
1100
 
1017
1101
                /* give connection some time to breathe */
1018
1102
                run_again(local, jiffies + HZ/2);
1019
1103
        }