Sophie

Sophie

distrib > CentOS > 5 > i386 > by-pkgid > ea32411352494358b8d75a78402a4713 > files > 3343

kernel-2.6.18-238.19.1.el5.centos.plus.src.rpm

From: John Linville <linville@redhat.com>
Date: Mon, 1 Feb 2010 18:42:38 -0500
Subject: [net] wireless fixes through 2.6.32.3
Message-id: <20100201184237.GE28565@redhat.com>
Patchwork-id: 23057
O-Subject: [RHEL5 Patch 2/4] wireless fixes through 2.6.32.3
Bugzilla: 559711
RH-Acked-by: David S. Miller <davem@redhat.com>
RH-Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>

On Mon, Feb 01, 2010 at 01:36:11PM -0500, John W. Linville wrote:
> As you may know, the mac80211-based wireless bits in RHEL 5.5 are
> basically identical to the equivalent components in 2.6.32.  Since it's
> release, there have been a number of fixes propogated to the 2.6.32
> -stable tree.  This series brings those fixes to the RHEL 5.5 kernel.
>
> BZ559711

These are the bits included in 2.6.32.3.

Reasonably extensive "real world" testing by me, with positive
results...

commit 3815270b3107d31c8b7bd69461f0bb3c350ee25c
Author: Gertjan van Wingerde <gwingerde@gmail.com>
Date:   Mon Dec 14 20:33:55 2009 +0100

    rt2x00: Disable powersaving for rt61pci and rt2800pci.

    commit 93b6bd26b74efe46b4579592560f9f1cb7b61994 upstream.

    We've had many reports of rt61pci failures with powersaving enabled.
    Therefore, as a stop-gap measure, disable powersaving of the rt61pci
    until we have found a proper solution.
    Also disable powersaving on rt2800pci as it most probably will show
    the same problem.

    Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
    Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

commit 1cfe005024b5c820f9b37c9045ec87ee75a8cfb6
Author: Luis R. Rodriguez <lrodriguez@atheros.com>
Date:   Thu Dec 24 15:26:09 2009 -0500

    mac80211: fix race with suspend and dynamic_ps_disable_work

    commit b98c06b6debfe84c90200143bb1102f312f50a33 upstream.

    When mac80211 suspends it calls a driver's suspend callback
    as a last step and after that the driver assumes no calls will
    be made to it until we resume and its start callback is kicked.
    If such calls are made, however, suspend can end up throwing
    hardware in an unexpected state and making the device unusable
    upon resume.

    Fix this by preventing mac80211 to schedule dynamic_ps_disable_work
    by checking for when mac80211 starts to suspend and starts
    quiescing. Frames should be allowed to go through though as
    that is part of the quiescing steps and we do not flush the
    mac80211 workqueue since it was already done towards the
    beginning of suspend cycle.

    The other mac80211 issue will be hanled in the next patch.

    For further details see refer to the thread:

    http://marc.info/?t=126144866100001&r=1&w=2

    Cc: stable@kernel.org
    Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

commit 14b4d749ab35158853bca4868b42c0a8cb947206
Author: Reinette Chatre <reinette.chatre@intel.com>
Date:   Mon Dec 14 14:12:13 2009 -0800

    iwlwifi: fix 40MHz operation setting on cards that do not allow it

    commit 6c3069b1e7e983e176a5f826e2edffefdd404a08 upstream.

    Some devices have 40MHz operation disabled entirely. Ensure that driver do
    not enable 40MHz operation if a channel does not allow this.

    This fixes http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2135

    Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

commit c4ae8aea88809050e8ae76a8c3e252ba3fe6e2cc
Author: Johannes Berg <johannes@sipsolutions.net>
Date:   Mon Dec 14 14:12:09 2009 -0800

    iwlwifi: fix more eeprom endian bugs

    commit b7bb1756cb6a610cdbac8cfdad9e79bb5670b63b upstream.

    I've also for a long time had a problem with the
    temperature calculation code, which I had fixed
    by byte-swapping the values, and now it turns out
    that was the correct fix after all.

    Also, any use of iwl_eeprom_query_addr() that is
    for more than a u8 must be cast to little endian,
    and some structs as well.

    Fix all this. Again, no real impact on platforms
    that already are little endian.

    Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
    Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

commit df5d119f46660631b9d50b91b1b888cdb512bdb2
Author: Johannes Berg <johannes@sipsolutions.net>
Date:   Mon Dec 14 14:12:08 2009 -0800

    iwlwifi: fix EEPROM/OTP reading endian annotations and a bug

    commit af6b8ee38833b39f70946f767740565ceb126961 upstream.

    The construct "le16_to_cpu((__force __le16)(r >> 16))" has
    always bothered me when looking through the iwlwifi code,
    it shouldn't be necessary to __force anything, and before
    this code, "r" was obtained with an ioread32, which swaps
    each of the two u16 values in it properly when swapping the
    entire u32 value. I've had arguments about this code with
    people before, but always conceded they were right because
    removing it only made things not work at all on big endian
    platforms.

    However, analysing a failure of the OTP reading code, I now
    finally figured out what is going on, and why my intuition
    about that code being wrong was right all along.

    It turns out that the 'priv->eeprom' u8 array really wants
    to have the data in it in little endian. So the force code
    above and all really converts *to* little endian, not from
    it. Cf., for instance, the function iwl_eeprom_query16() --
    it reads two u8 values and combines them into a u16, in a
    little-endian way. And considering it more, it makes sense
    to have the eeprom array as on the device, after all not
    all values really are 16-bit values, the MAC address for
    instance is not.

    Now, what this really means is that all the annotations are
    completely wrong. The eeprom reading code should fill the
    priv->eeprom array as a __le16 array, with __le16 values.

    This also means that iwl_read_otp_word() should really have
    a __le16 pointer as the data argument, since it should be
    filling that in a format suitable for priv->eeprom.

    Propagating these changes throughout, iwl_find_otp_image()
    is found to be, now obviously visible, defective -- it uses
    the data returned by iwl_read_otp_word() directly as if it
    was CPU endianness. Fixing that, which is this hunk of the
    patch:

    -               next_link_addr = link_value * sizeof(u16);
    +               next_link_addr = le16_to_cpu(link_value) * sizeof(u16);

    is the only real change of this patch. Everything else is
    just fixing the sparse annotations.

    Also, the bug only shows up on big endian platforms with a
    1000 series card. 5000 and previous series do not use OTP,
    and 6000 series has shadow RAM support which means we don't
    ever use the defective code on any cards but 1000.

    Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
    Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

commit 0c0cdaff83704490511b462c7ba76d3ff2d0eedb
Author: Zhu Yi <yi.zhu@intel.com>
Date:   Mon Dec 14 14:12:12 2009 -0800

    iwl3945: fix panic in iwl3945 driver

    commit dc57a303faab8562b92e85df0d79c4a05d7e2a61 upstream.

    3945 updated write_ptr without regard to read_ptr on the Tx path.
    This messes up our TFD on high load and result in the following:

    <1>[ 7290.414172] IP: [<ffffffffa0dd53a1>] iwl3945_rx_reply_tx+0xc1/0x450 [iwl3945]
    <4>[ 7290.414205] PGD 0
    <1>[ 7290.414214] Thread overran stack, or stack corrupted
    <0>[ 7290.414229] Oops: 0002 [#1] PREEMPT SMP
    <0>[ 7290.414246] last sysfs file: /sys/devices/platform/coretemp.1/temp1_input
    <4>[ 7290.414265] CPU 0
    <4>[ 7290.414274] Modules linked in: af_packet nfsd usb_storage usb_libusual cpufreq_powersave exportfs cpufreq_conservative iwl3945 nfs cpufreq_userspace snd_hda_codec_realtek acpi_cpufreq uvcvideo lockd iwlcore snd_hda_intel joydev coretemp nfs_acl videodev snd_hda_codec mac80211 v4l1_compat snd_hwdep sbp2 v4l2_compat_ioctl32 uhci_hcd psmouse auth_rpcgss ohci1394 cfg80211 ehci_hcd video ieee1394 snd_pcm serio_raw battery ac nvidia(P) usbcore output sunrpc evdev lirc_ene0100 snd_page_alloc rfkill tg3 libphy fuse lzo lzo_decompress lzo_compress
    <6>[ 7290.414486] Pid: 0, comm: swapper Tainted: P           2.6.32-rc8-wl #213 Aspire 5720
    <6>[ 7290.414507] RIP: 0010:[<ffffffffa0dd53a1>]  [<ffffffffa0dd53a1>] iwl3945_rx_reply_tx+0xc1/0x450 [iwl3945]
    <6>[ 7290.414541] RSP: 0018:ffff880002203d60  EFLAGS: 00010246
    <6>[ 7290.414557] RAX: 000000000000004f RBX: ffff880064c11600 RCX: 0000000000000013
    <6>[ 7290.414576] RDX: ffffffffa0ddcf20 RSI: ffff8800512b7008 RDI: 0000000000000038
    <6>[ 7290.414596] RBP: ffff880002203dd0 R08: 0000000000000000 R09: 0000000000000100
    <6>[ 7290.414616] R10: 0000000000000001 R11: 0000000000000000 R12: 00000000000000a0
    <6>[ 7290.414635] R13: 0000000000000002 R14: 0000000000000013 R15: 0000000000020201
    <6>[ 7290.414655] FS:  0000000000000000(0000) GS:ffff880002200000(0000) knlGS:0000000000000000
    <6>[ 7290.414677] CS:  0010 DS: 0018 ES: 0018 CR0: 000000008005003b
    <6>[ 7290.414693] CR2: 0000000000000041 CR3: 0000000001001000 CR4: 00000000000006f0
    <6>[ 7290.414712] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    <6>[ 7290.414732] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
    <4>[ 7290.414752] Process swapper (pid: 0, threadinfo ffffffff81524000, task ffffffff81528b60)
    <0>[ 7290.414772] Stack:
    <4>[ 7290.414780]  ffff880002203da0 0000000000000046 0000000000000000 0000000000000046
    <4>[ 7290.414804] <0> 0000000000000282 0000000000000282 0000000000000282 ffff880064c12010
    <4>[ 7290.414830] <0> ffff880002203db0 ffff880064c11600 ffff880064c12e50 ffff8800512b7000
    <0>[ 7290.414858] Call Trace:
    <0>[ 7290.414867]  <IRQ>
    <4>[ 7290.414884]  [<ffffffffa0dc8c47>] iwl3945_irq_tasklet+0x657/0x1740 [iwl3945]
    <4>[ 7290.414910]  [<ffffffff8138fc60>] ? _spin_unlock+0x30/0x60
    <4>[ 7290.414931]  [<ffffffff81049a21>] tasklet_action+0x101/0x110
    <4>[ 7290.414950]  [<ffffffff8104a3d0>] __do_softirq+0xc0/0x160
    <4>[ 7290.414968]  [<ffffffff8100d01c>] call_softirq+0x1c/0x30
    <4>[ 7290.414986]  [<ffffffff8100eff5>] do_softirq+0x75/0xb0
    <4>[ 7290.415003]  [<ffffffff81049ee5>] irq_exit+0x95/0xa0
    <4>[ 7290.415020]  [<ffffffff8100e547>] do_IRQ+0x77/0xf0
    <4>[ 7290.415038]  [<ffffffff8100c7d3>] ret_from_intr+0x0/0xf
    <0>[ 7290.415052]  <EOI>
    <4>[ 7290.415067]  [<ffffffff81234efa>] ? acpi_idle_enter_bm+0x270/0x2a5
    <4>[ 7290.415087]  [<ffffffff81234f04>] ? acpi_idle_enter_bm+0x27a/0x2a5
    <4>[ 7290.415107]  [<ffffffff81234efa>] ? acpi_idle_enter_bm+0x270/0x2a5
    <4>[ 7290.415130]  [<ffffffff812c11f3>] ? cpuidle_idle_call+0x93/0xf0
    <4>[ 7290.415149]  [<ffffffff8100b0d7>] ? cpu_idle+0xa7/0x110
    <4>[ 7290.415168]  [<ffffffff8137b3d5>] ? rest_init+0x75/0x80
    <4>[ 7290.415187]  [<ffffffff8158cd0a>] ? start_kernel+0x3a7/0x3b3
    <4>[ 7290.415206]  [<ffffffff8158c315>] ? x86_64_start_reservations+0x125/0x129
    <4>[ 7290.415227]  [<ffffffff8158c3fd>] ? x86_64_start_kernel+0xe4/0xeb
    <0>[ 7290.415243] Code: 00 41 39 ce 0f 8d e8 01 00 00 48 8b 47 40 48 63 d2 48 69 d2 98 00 00 00 4c 8b 04 02 48 c7 c2 20 cf dd a0 49 8d 78 38 49 8d 40 4f <c6> 47 09 00 c6 47 0c 00 c6 47 0f 00 c6 47 12 00 c6 47 15 00 49
    <1>[ 7290.415382] RIP  [<ffffffffa0dd53a1>] iwl3945_rx_reply_tx+0xc1/0x450 [iwl3945]
    <4>[ 7290.415410]  RSP <ffff880002203d60>
    <0>[ 7290.415421] CR2: 0000000000000041
    <4>[ 7290.415436] ---[ end trace ec46807277caa515 ]---
    <0>[ 7290.415450] Kernel panic - not syncing: Fatal exception in interrupt
    <4>[ 7290.415468] Pid: 0, comm: swapper Tainted: P      D    2.6.32-rc8-wl #213
    <4>[ 7290.415486] Call Trace:
    <4>[ 7290.415495]  <IRQ>  [<ffffffff8138c040>] panic+0x7d/0x13a
    <4>[ 7290.415519]  [<ffffffff8101071a>] oops_end+0xda/0xe0
    <4>[ 7290.415538]  [<ffffffff8102e1ea>] no_context+0xea/0x250
    <4>[ 7290.415557]  [<ffffffff81038991>] ? select_task_rq_fair+0x511/0x780
    <4>[ 7290.415578]  [<ffffffff8102e475>] __bad_area_nosemaphore+0x125/0x1e0
    <4>[ 7290.415597]  [<ffffffff81038d0c>] ? __enqueue_entity+0x7c/0x80
    <4>[ 7290.415616]  [<ffffffff81039201>] ? enqueue_task_fair+0x111/0x150
    <4>[ 7290.415636]  [<ffffffff8102e53e>] bad_area_nosemaphore+0xe/0x10
    <4>[ 7290.415656]  [<ffffffff8102e8fa>] do_page_fault+0x26a/0x320
    <4>[ 7290.415674]  [<ffffffff813905df>] page_fault+0x1f/0x30
    <4>[ 7290.415697]  [<ffffffffa0dd53a1>] ? iwl3945_rx_reply_tx+0xc1/0x450 [iwl3945]
    <4>[ 7290.415723]  [<ffffffffa0dc8c47>] iwl3945_irq_tasklet+0x657/0x1740 [iwl3945]
    <4>[ 7290.415746]  [<ffffffff8138fc60>] ? _spin_unlock+0x30/0x60
    <4>[ 7290.415764]  [<ffffffff81049a21>] tasklet_action+0x101/0x110
    <4>[ 7290.415783]  [<ffffffff8104a3d0>] __do_softirq+0xc0/0x160
    <4>[ 7290.415801]  [<ffffffff8100d01c>] call_softirq+0x1c/0x30
    <4>[ 7290.415818]  [<ffffffff8100eff5>] do_softirq+0x75/0xb0
    <4>[ 7290.415835]  [<ffffffff81049ee5>] irq_exit+0x95/0xa0
    <4>[ 7290.415852]  [<ffffffff8100e547>] do_IRQ+0x77/0xf0
    <4>[ 7290.415869]  [<ffffffff8100c7d3>] ret_from_intr+0x0/0xf
    <4>[ 7290.415883]  <EOI>  [<ffffffff81234efa>] ? acpi_idle_enter_bm+0x270/0x2a5
    <4>[ 7290.415911]  [<ffffffff81234f04>] ? acpi_idle_enter_bm+0x27a/0x2a5
    <4>[ 7290.415931]  [<ffffffff81234efa>] ? acpi_idle_enter_bm+0x270/0x2a5
    <4>[ 7290.415952]  [<ffffffff812c11f3>] ? cpuidle_idle_call+0x93/0xf0
    <4>[ 7290.415971]  [<ffffffff8100b0d7>] ? cpu_idle+0xa7/0x110
    <4>[ 7290.415989]  [<ffffffff8137b3d5>] ? rest_init+0x75/0x80
    <4>[ 7290.416007]  [<ffffffff8158cd0a>] ? start_kernel+0x3a7/0x3b3
    <4>[ 7290.416026]  [<ffffffff8158c315>] ? x86_64_start_reservations+0x125/0x129
    <4>[ 7290.416047]  [<ffffffff8158c3fd>] ? x86_64_start_kernel+0xe4/0xeb

    Reported-by: Maxim Levitsky <maximlevitsky@gmail.com>
    Tested-by: Maxim Levitsky <maximlevitsky@gmail.com>
    Signed-off-by: Zhu Yi <yi.zhu@intel.com>
    Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

commit 66c9e44e5740fe9024e3ed02fd66ad6e0e57408f
Author: Reinette Chatre <reinette.chatre@intel.com>
Date:   Mon Dec 14 14:12:10 2009 -0800

    iwl3945: disable power save

    commit bc45a67079c916a9bd0a95b0b879cc0f259bac6e upstream.

    we see from http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2125
    that power saving does not work well on 3945. Since then power saving has
    also been connected with association problems where an AP deathenticates a
    3945 after it is unable to transmit data to it - this happens when 3945
    enters power savings mode.

    Disable power save support until issues are resolved.

    Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

commit 87d512cacd0aff44719736ef6d583cafd5c0e1be
Author: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Date:   Fri Nov 13 14:32:40 2009 +0530

    ath9k_hw: Fix AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB and its shift value in 0x4054

    commit c37919bfe0a5c1bee9a31701a31e05a2f8840936 upstream.

    The bit value of AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB is wrong, it should
    be 0x400 and the number of bits to be right shifted is 10. Having this
    wrong value in 0x4054 sometimes affects bt quality on btcoex environment.

    Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

commit a6d8cc616a9058b2e08776f971febf5c84534551
Author: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Date:   Fri Nov 13 14:32:39 2009 +0530

    ath9k_hw: Fix possible OOB array indexing in gen_timer_index[] on 64-bit

    commit c90017dd43f0cdb42134b9229761e8be02bcd524 upstream.

    debruijn32 (0x077CB531) is used to index gen_timer_index[]
    which is an array of 32 u32. Having debruijn32 as unsigned
    long on a 64-bit platform  will result in indexing more than 32
    in gen_timer_index[] and there by causing a crash. Make it
    unsigned to fix this issue.

    Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

commit 12ba7097e0996b27d768504ae4b337ae3e892221
Author: Sujith <Sujith.Manoharan@atheros.com>
Date:   Wed Dec 23 20:03:27 2009 -0500

    ath9k: fix suspend by waking device prior to stop

    commit 3867cf6a8c699846e928e8f5a9f31013708df192 upstream.

    Ensure the device is awake prior to trying to tell hardware
    to stop it. Impact of not doing this is we can likely leave
    the device in an undefined state likely causing issues with
    suspend and resume. This patch ensures harware is where it
    should be prior to suspend.

    Signed-off-by: Sujith <Sujith.Manoharan@atheros.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

commit c965e1efdb88a1c42afb119b276d649cddb70387
Author: Luis R. Rodriguez <lrodriguez@atheros.com>
Date:   Wed Dec 23 20:03:29 2009 -0500

    ath9k: wake hardware during AMPDU TX actions

    commit 8b685ba9de803f210936400612a32a2003f47cd3 upstream.

    AMDPDU actions poke hardware for TX operation, as such
    we want to turn hardware on for these actions. AMDPU RX operations
    do not require hardware on as nothing is done in hardware for
    those actions. Without this we cannot guarantee hardware has
    been programmed correctly for each AMPDU TX action.

    Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

commit 463a7f9b2752b659f93272c0067dcbc10bd73674
Author: Felix Fietkau <nbd@openwrt.org>
Date:   Thu Dec 24 14:04:32 2009 +0100

    ath9k: fix missed error codes in the tx status check

    commit 5b479a076de091590423a9e6dfc2584126b28761 upstream.

    My previous change added in:

     commit 815833e7ecf0b9a017315cae6aef4d7cd9517681
        ath9k: fix tx status reporting

    was not checking all possible tx error conditions. This could possibly
    lead to throughput issues due to slow rate control adaption or missed
    retransmissions of failed A-MPDU frames.

    This patch adds a mask for all possible error conditions and uses it
    in the xmit ok check.

    Reported-by: Björn Smedman <bjorn.smedman@venatech.se>
    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

commit bef82b626e39357fd28b8303e9f88ea5c5d1b51f
Author: Sujith <Sujith.Manoharan@atheros.com>
Date:   Mon Dec 14 14:57:08 2009 +0530

    ath9k: Fix TX queue draining

    commit e8009e9850d59000d518296af372888911a129bd upstream.

    When TX DMA termination has failed, the HW has to be reset
    completely. Doing a fast channel change in this case is insufficient.
    Also, change the debug level of a couple of messages to FATAL.

    Signed-off-by: Sujith <Sujith.Manoharan@atheros.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

commit 0ebbdd734f2509bae17f4340fc4fd07c530dbc59
Author: Luis R. Rodriguez <lrodriguez@atheros.com>
Date:   Wed Dec 23 20:03:28 2009 -0500

    ath9k: wake hardware for interface IBSS/AP/Mesh removal

    commit 5f70a88f631c3480107853cae12925185eb4c598 upstream.

    When we remove a IBSS/AP/Mesh interface we stop DMA
    but to do this we should ensure hardware is on. Awaken
    the device prior to these calls. This should ensure
    DMA is stopped upon suspend and plain device removal.

    Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

commit d5086b90c5986d33308b1ee99546a86ff1571d07
Author: Bob Copeland <me@bobcopeland.com>
Date:   Mon Dec 21 22:26:48 2009 -0500

    ath5k: fix SWI calibration interrupt storm

    commit 242ab7ad689accafd5e87ffd22b85cf1bf7fbbef upstream.

    The calibration period is now invoked by triggering a software
    interrupt from within the ISR by ath5k_hw_calibration_poll()
    instead of via a timer.

    However, the calibration interval isn't initialized before
    interrupts are enabled, so we can have a situation where an
    interrupt occurs before the interval is assigned, so the
    interval is actually negative.  As a result, the ISR will
    arm a software interrupt to schedule the tasklet, and then
    rearm it when the SWI is processed, and so on, leading to a
    softlockup at modprobe time.

    Move the initialization order around so the calibration interval
    is set before interrupts are active.  Another possible fix
    is to schedule the tasklet directly from the poll routine,
    but I think there are additional plans for the SWI.

    Signed-off-by: Bob Copeland <me@bobcopeland.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

commit 477702056912abc2120a18e8494fb2204ccdd958
Author: Johannes Berg <johannes@sipsolutions.net>
Date:   Wed Dec 23 13:12:05 2009 +0100

    cfg80211: fix race between deauth and assoc response

    commit 3bdb2d48c5f58c781a4099c99044384a23620884 upstream.

    Joseph Nahmias reported, in http://bugs.debian.org/562016,
    that he was getting the following warning (with some log
    around the issue):

      ath0: direct probe to AP 00:11:95:77:e0:b0 (try 1)
      ath0: direct probe responded
      ath0: authenticate with AP 00:11:95:77:e0:b0 (try 1)
      ath0: authenticated
      ath0: associate with AP 00:11:95:77:e0:b0 (try 1)
      ath0: deauthenticating from 00:11:95:77:e0:b0 by local choice (reason=3)
      ath0: direct probe to AP 00:11:95:77:e0:b0 (try 1)
      ath0: RX AssocResp from 00:11:95:77:e0:b0 (capab=0x421 status=0 aid=2)
      ath0: associated
      ------------[ cut here ]------------
      WARNING: at net/wireless/mlme.c:97 cfg80211_send_rx_assoc+0x14d/0x152 [cfg80211]()
      Hardware name: 7658CTO
      ...
      Pid: 761, comm: phy0 Not tainted 2.6.32-trunk-686 #1
      Call Trace:
       [<c1030a5d>] ? warn_slowpath_common+0x5e/0x8a
       [<c1030a93>] ? warn_slowpath_null+0xa/0xc
       [<f86cafc7>] ? cfg80211_send_rx_assoc+0x14d/0x152
      ...
      ath0: link becomes ready
      ath0: deauthenticating from 00:11:95:77:e0:b0 by local choice (reason=3)
      ath0: no IPv6 routers present
      ath0: link is not ready
      ath0: direct probe to AP 00:11:95:77:e0:b0 (try 1)
      ath0: direct probe responded
      ath0: authenticate with AP 00:11:95:77:e0:b0 (try 1)
      ath0: authenticated
      ath0: associate with AP 00:11:95:77:e0:b0 (try 1)
      ath0: RX ReassocResp from 00:11:95:77:e0:b0 (capab=0x421 status=0 aid=2)
      ath0: associated

    It is not clear to me how the first "direct probe" here
    happens, but this seems to be a race condition, if the
    user requests to deauth after requesting assoc, but before
    the assoc response is received. In that case, it may
    happen that mac80211 tries to report the assoc success to
    cfg80211, but gets blocked on the wdev lock that is held
    because the user is requesting the deauth.

    The result is that we run into a warning. This is mostly
    harmless, but maybe cause an unexpected event to be sent
    to userspace; we'd send an assoc success event although
    userspace was no longer expecting that.

    To fix this, remove the warning and check whether the
    race happened and in that case abort processing.

    Reported-by: Joseph Nahmias <joe@nahmias.net>
    Cc: 562016-quiet@bugs.debian.org
    Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

commit 9f7028e71d940aadcdea9f777286b066971ba5da
Author: Sujith <Sujith.Manoharan@atheros.com>
Date:   Mon Nov 2 12:33:23 2009 +0530

    mac80211: Fix IBSS merge

    commit 450aae3d7b60a970f266349a837dfb30a539198b upstream.

    Currently, in IBSS mode, a single creator would go into
    a loop trying to merge/scan. This happens because the IBSS timer is
    rearmed on finishing a scan and the subsequent
    timer invocation requests another scan immediately.

    This patch fixes this issue by checking if we have just completed
    a scan run trying to merge with other IBSS networks.

    Signed-off-by: Sujith <Sujith.Manoharan@atheros.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    Cc: Luis Rodriguez <lrodriguez@atheros.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

commit 0b41c5a957e4fb2be4a8ef960e4e50c8791999f3
Author: Johannes Berg <johannes@sipsolutions.net>
Date:   Thu Dec 17 16:16:53 2009 +0100

    mac80211: fix WMM AP settings application

    commit 0183826b58a2712ffe608bc3302447be3e6a3ab8 upstream.

    My
      commit 77fdaa12cea26c204cc12c312fe40bc0f3dcdfd8
      Author: Johannes Berg <johannes@sipsolutions.net>
      Date:   Tue Jul 7 03:45:17 2009 +0200

          mac80211: rework MLME for multiple authentications

    inadvertedly broke WMM because it removed, along with
    a bunch of other now useless initialisations, the line
    initialising sdata->u.mgd.wmm_last_param_set to -1
    which would make it adopt any WMM parameter set. If,
    as is usually the case, the AP uses WMM parameter set
    sequence number zero, we'd never update it until the
    AP changes the sequence number.

    Add the missing initialisation back to get the WMM
    settings from the AP applied locally.

    Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

commit 330b9373f9b62fcad200f470be7f64c99322d7ef
Author: Luis R. Rodriguez <lrodriguez@atheros.com>
Date:   Thu Dec 24 15:38:22 2009 -0500

    mac80211: fix propagation of failed hardware reconfigurations

    commit 24feda0084722189468a65e20019cdd8ef99702b upstream.

    mac80211 does not propagate failed hardware reconfiguration
    requests. For suspend and resume this is important due to all
    the possible issues that can come out of the suspend <-> resume
    cycle. Not propagating the error means cfg80211 will assume
    the resume for the device went through fine and mac80211 will
    continue on trying to poke at the hardware, enable timers,
    queue work, and so on for a device which is completley
    unfunctional.

    The least we can do is to propagate device start issues and
    warn when this occurs upon resume. A side effect of this patch
    is we also now propagate the start errors upon harware
    reconfigurations (non-suspend), but this should also be desirable
    anyway, there is not point in continuing to reconfigure a
    device if mac80211 was unable to start the device.

    For further details refer to the thread:

    http://marc.info/?t=126151038700001&r=1&w=2

    Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

Signed-off-by: Jarod Wilson <jarod@redhat.com>

diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index a831494..83123cd 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2363,6 +2363,9 @@ ath5k_init(struct ath5k_softc *sc)
 	 */
 	ath5k_stop_locked(sc);
 
+	/* Set PHY calibration interval */
+	ah->ah_cal_intval = ath5k_calinterval;
+
 	/*
 	 * The basic interface to setting the hardware in a good
 	 * state is ``reset''.  On return the hardware is known to
@@ -2390,10 +2393,6 @@ ath5k_init(struct ath5k_softc *sc)
 
 	/* Set ack to be sent at low bit-rates */
 	ath5k_hw_set_ack_bitrate_high(ah, false);
-
-	/* Set PHY calibration inteval */
-	ah->ah_cal_intval = ath5k_calinterval;
-
 	ret = 0;
 done:
 	mmiowb();
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 57f1463..ff4383b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -408,7 +408,7 @@ struct ath9k_hw_version {
  * Using de Bruijin sequence to to look up 1's index in a 32 bit number
  * debruijn32 = 0000 0111 0111 1100 1011 0101 0011 0001
  */
-#define debruijn32 0x077CB531UL
+#define debruijn32 0x077CB531U
 
 struct ath_gen_timer_configuration {
 	u32 next_addr;
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index d4d9d82..110c16d 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -155,7 +155,7 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
 		wait = wait_time;
 		while (ath9k_hw_numtxpending(ah, q)) {
 			if ((--wait) == 0) {
-				DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
+				DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
 					"Failed to stop TX DMA in 100 "
 					"msec after killing last frame\n");
 				break;
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index ff65f85..9720c4d 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -77,6 +77,9 @@
 #define ATH9K_TXERR_XTXOP          0x08
 #define ATH9K_TXERR_TIMER_EXPIRED  0x10
 #define ATH9K_TX_ACKED		   0x20
+#define ATH9K_TXERR_MASK						\
+	(ATH9K_TXERR_XRETRY | ATH9K_TXERR_FILT | ATH9K_TXERR_FIFO |	\
+	 ATH9K_TXERR_XTXOP | ATH9K_TXERR_TIMER_EXPIRED)
 
 #define ATH9K_TX_BA                0x01
 #define ATH9K_TX_PWRMGMT           0x02
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 481b80b..049020c 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2164,6 +2164,9 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 		return; /* another wiphy still in use */
 	}
 
+	/* Ensure HW is awake when we try to shut it down. */
+	ath9k_ps_wakeup(sc);
+
 	if (sc->sc_flags & SC_OP_BTCOEX_ENABLED) {
 		ath9k_hw_btcoex_disable(sc->sc_ah);
 		if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
@@ -2184,6 +2187,9 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 	/* disable HAL and put h/w to sleep */
 	ath9k_hw_disable(sc->sc_ah);
 	ath9k_hw_configpcipowersave(sc->sc_ah, 1, 1);
+	ath9k_ps_restore(sc);
+
+	/* Finally, put the chip in FULL SLEEP mode */
 	ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
 
 	sc->sc_flags |= SC_OP_INVALID;
@@ -2294,8 +2300,10 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
 	if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
 	    (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
 	    (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
+		ath9k_ps_wakeup(sc);
 		ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
 		ath_beacon_return(sc, avp);
+		ath9k_ps_restore(sc);
 	}
 
 	sc->sc_flags &= ~SC_OP_BEACONS;
@@ -2741,15 +2749,21 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
 	case IEEE80211_AMPDU_RX_STOP:
 		break;
 	case IEEE80211_AMPDU_TX_START:
+		ath9k_ps_wakeup(sc);
 		ath_tx_aggr_start(sc, sta, tid, ssn);
 		ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid);
+		ath9k_ps_restore(sc);
 		break;
 	case IEEE80211_AMPDU_TX_STOP:
+		ath9k_ps_wakeup(sc);
 		ath_tx_aggr_stop(sc, sta, tid);
 		ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
+		ath9k_ps_restore(sc);
 		break;
 	case IEEE80211_AMPDU_TX_OPERATIONAL:
+		ath9k_ps_wakeup(sc);
 		ath_tx_aggr_resume(sc, sta, tid);
+		ath9k_ps_restore(sc);
 		break;
 	default:
 		DPRINTF(sc, ATH_DBG_FATAL, "Unknown AMPDU action\n");
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index d83b77f..c0d7e65 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -969,10 +969,10 @@ enum {
 #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_S         4
 #define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF        0x00000080
 #define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF_S      7
+#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB      0x00000400
+#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB_S    10
 #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB        0x00001000
 #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB_S      12
-#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB      0x00001000
-#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB_S    1
 #define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB         0x00008000
 #define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB_S       15
 #define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE        0x00010000
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 19d3075..2dc16f9 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1088,10 +1088,10 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
 	if (npend) {
 		int r;
 
-		DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n");
+		DPRINTF(sc, ATH_DBG_FATAL, "Unable to stop TxDMA. Reset HAL!\n");
 
 		spin_lock_bh(&sc->sc_resetlock);
-		r = ath9k_hw_reset(ah, sc->sc_ah->curchan, true);
+		r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
 		if (r)
 			DPRINTF(sc, ATH_DBG_FATAL,
 				"Unable to reset hardware; reset status %d\n",
@@ -2040,7 +2040,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
 		if (bf_isaggr(bf))
 			txq->axq_aggr_depth--;
 
-		txok = !(ds->ds_txstat.ts_status & ATH9K_TXERR_FILT);
+		txok = !(ds->ds_txstat.ts_status & ATH9K_TXERR_MASK);
 		txq->axq_tx_inprogress = false;
 		spin_unlock_bh(&txq->axq_lock);
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 1ee69e1..0792552 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -2901,6 +2901,7 @@ static struct iwl_cfg iwl3945_bg_cfg = {
 	.mod_params = &iwl3945_mod_params,
 	.use_isr_legacy = true,
 	.ht_greenfield_support = false,
+	.broken_powersave = true,
 };
 
 static struct iwl_cfg iwl3945_abg_cfg = {
@@ -2915,6 +2916,7 @@ static struct iwl_cfg iwl3945_abg_cfg = {
 	.mod_params = &iwl3945_mod_params,
 	.use_isr_legacy = true,
 	.ht_greenfield_support = false,
+	.broken_powersave = true,
 };
 
 struct pci_device_id iwl3945_hw_card_ids[] = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index bd2104d..7bf5543 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1338,7 +1338,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
 	iwl4965_interpolate_chan(priv, channel, &ch_eeprom_info);
 
 	/* calculate tx gain adjustment based on power supply voltage */
-	voltage = priv->calib_info->voltage;
+	voltage = le16_to_cpu(priv->calib_info->voltage);
 	init_voltage = (s32)le32_to_cpu(priv->card_alive_init.voltage);
 	voltage_compensation =
 	    iwl4965_get_voltage_compensation(voltage, init_voltage);
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index 4ef6804..bc056e9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -92,11 +92,15 @@
 
 static inline s32 iwl_temp_calib_to_offset(struct iwl_priv *priv)
 {
-	u16 *temp_calib = (u16 *)iwl_eeprom_query_addr(priv,
-						       EEPROM_5000_TEMPERATURE);
-	/* offset =  temperature -  voltage / coef */
-	s32 offset = (s32)(temp_calib[0] - temp_calib[1] / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF);
-	return offset;
+	u16 temperature, voltage;
+	__le16 *temp_calib =
+		(__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_TEMPERATURE);
+
+	temperature = le16_to_cpu(temp_calib[0]);
+	voltage = le16_to_cpu(temp_calib[1]);
+
+	/* offset = temp - volt / coeff */
+	return (s32)(temperature - voltage / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF);
 }
 
 /* Fixed (non-configurable) rx data from phy */
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 966eda6..944b510 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -466,14 +466,15 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
 static int iwl5000_set_Xtal_calib(struct iwl_priv *priv)
 {
 	struct iwl_calib_xtal_freq_cmd cmd;
-	u16 *xtal_calib = (u16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL);
+	__le16 *xtal_calib =
+		(__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL);
 
 	cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD;
 	cmd.hdr.first_group = 0;
 	cmd.hdr.groups_num = 1;
 	cmd.hdr.data_valid = 1;
-	cmd.cap_pin1 = (u8)xtal_calib[0];
-	cmd.cap_pin2 = (u8)xtal_calib[1];
+	cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]);
+	cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]);
 	return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL],
 			     (u8 *)&cmd, sizeof(cmd));
 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 48e52a5..3cb368b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1149,7 +1149,7 @@ struct iwl_priv {
 	u32 last_beacon_time;
 	u64 last_tsf;
 
-	/* eeprom */
+	/* eeprom -- this is in the card's little endian byte order */
 	u8 *eeprom;
 	int    nvm_device_type;
 	struct iwl_eeprom_calib_info *calib_info;
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 1d448fe..a102108 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -340,7 +340,7 @@ static int iwl_init_otp_access(struct iwl_priv *priv)
 	return ret;
 }
 
-static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, u16 *eeprom_data)
+static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, __le16 *eeprom_data)
 {
 	int ret = 0;
 	u32 r;
@@ -373,7 +373,7 @@ static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, u16 *eeprom_data)
 				CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK);
 		IWL_ERR(priv, "Correctable OTP ECC error, continue read\n");
 	}
-	*eeprom_data = le16_to_cpu((__force __le16)(r >> 16));
+	*eeprom_data = cpu_to_le16(r >> 16);
 	return 0;
 }
 
@@ -382,7 +382,8 @@ static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, u16 *eeprom_data)
  */
 static bool iwl_is_otp_empty(struct iwl_priv *priv)
 {
-	u16 next_link_addr = 0, link_value;
+	u16 next_link_addr = 0;
+	__le16 link_value;
 	bool is_empty = false;
 
 	/* locate the beginning of OTP link list */
@@ -412,7 +413,8 @@ static bool iwl_is_otp_empty(struct iwl_priv *priv)
 static int iwl_find_otp_image(struct iwl_priv *priv,
 					u16 *validblockaddr)
 {
-	u16 next_link_addr = 0, link_value = 0, valid_addr;
+	u16 next_link_addr = 0, valid_addr;
+	__le16 link_value = 0;
 	int usedblocks = 0;
 
 	/* set addressing mode to absolute to traverse the link list */
@@ -432,7 +434,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
 		 * check for more block on the link list
 		 */
 		valid_addr = next_link_addr;
-		next_link_addr = link_value * sizeof(u16);
+		next_link_addr = le16_to_cpu(link_value) * sizeof(u16);
 		IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n",
 			       usedblocks, next_link_addr);
 		if (iwl_read_otp_word(priv, next_link_addr, &link_value))
@@ -466,7 +468,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
  */
 int iwl_eeprom_init(struct iwl_priv *priv)
 {
-	u16 *e;
+	__le16 *e;
 	u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
 	int sz;
 	int ret;
@@ -485,7 +487,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
 		ret = -ENOMEM;
 		goto alloc_err;
 	}
-	e = (u16 *)priv->eeprom;
+	e = (__le16 *)priv->eeprom;
 
 	ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv);
 	if (ret < 0) {
@@ -524,7 +526,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
 		}
 		for (addr = validblockaddr; addr < validblockaddr + sz;
 		     addr += sizeof(u16)) {
-			u16 eeprom_data;
+			__le16 eeprom_data;
 
 			ret = iwl_read_otp_word(priv, addr, &eeprom_data);
 			if (ret)
@@ -548,7 +550,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
 				goto done;
 			}
 			r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
-			e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
+			e[addr / 2] = cpu_to_le16(r >> 16);
 		}
 	}
 	ret = 0;
@@ -712,7 +714,8 @@ static int iwl_mod_ht40_chan_info(struct iwl_priv *priv,
 	ch_info->ht40_min_power = 0;
 	ch_info->ht40_scan_power = eeprom_ch->max_power_avg;
 	ch_info->ht40_flags = eeprom_ch->flags;
-	ch_info->ht40_extension_channel &= ~clear_ht40_extension_channel;
+	if (eeprom_ch->flags & EEPROM_CHANNEL_VALID)
+		ch_info->ht40_extension_channel &= ~clear_ht40_extension_channel;
 
 	return 0;
 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 80b9e45..fc93f12 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -133,7 +133,7 @@ struct iwl_eeprom_channel {
  *
  */
 struct iwl_eeprom_enhanced_txpwr {
-	u16 reserved;
+	__le16 common;
 	s8 chain_a_max;
 	s8 chain_b_max;
 	s8 chain_c_max;
@@ -347,7 +347,7 @@ struct iwl_eeprom_calib_subband_info {
 struct iwl_eeprom_calib_info {
 	u8 saturation_power24;	/* half-dBm (e.g. "34" = 17 dBm) */
 	u8 saturation_power52;	/* half-dBm */
-	s16 voltage;		/* signed */
+	__le16 voltage;		/* signed */
 	struct iwl_eeprom_calib_subband_info
 		band_info[EEPROM_TX_POWER_BANDS];
 } __attribute__ ((packed));
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index fc23edb..561a97a 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -568,6 +568,9 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 	txq = &priv->txq[txq_id];
 	q = &txq->q;
 
+	if ((iwl_queue_space(q) < q->high_mark))
+		goto drop;
+
 	spin_lock_irqsave(&priv->lock, flags);
 
 	idx = get_cmd_index(q, q->write_ptr, 0);
@@ -3866,9 +3869,11 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
 	/* Tell mac80211 our characteristics */
 	hw->flags = IEEE80211_HW_SIGNAL_DBM |
 		    IEEE80211_HW_NOISE_DBM |
-		    IEEE80211_HW_SPECTRUM_MGMT |
-		    IEEE80211_HW_SUPPORTS_PS |
-		    IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
+		    IEEE80211_HW_SPECTRUM_MGMT;
+
+	if (!priv->cfg->broken_powersave)
+		hw->flags |= IEEE80211_HW_SUPPORTS_PS |
+			     IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
 
 	hw->wiphy->interface_modes =
 		BIT(NL80211_IFTYPE_STATION) |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 899a2d8..474de80 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2543,6 +2543,11 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 	unsigned int i;
 
 	/*
+	 * Disable powersaving as default.
+	 */
+	rt2x00dev->hw->wiphy->ps_default = false;
+
+	/*
 	 * Initialize all hw fields.
 	 */
 	rt2x00dev->hw->flags =
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 294f91c..8c60e82 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -455,6 +455,10 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
 
 	ieee80211_sta_expire(sdata, IEEE80211_IBSS_INACTIVITY_LIMIT);
 
+	if (time_before(jiffies, ifibss->last_scan_completed +
+		       IEEE80211_IBSS_MERGE_INTERVAL))
+		return;
+
 	if (ieee80211_sta_active_ibss(sdata))
 		return;
 
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 8120744..3207932 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -912,6 +912,14 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
 	sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
 				IEEE80211_STA_BEACON_POLL);
 
+	/*
+	 * Always handle WMM once after association regardless
+	 * of the first value the AP uses. Setting -1 here has
+	 * that effect because the AP values is an unsigned
+	 * 4-bit value.
+	 */
+	sdata->u.mgd.wmm_last_param_set = -1;
+
 	ieee80211_led_assoc(local, 1);
 
 	sdata->vif.bss_conf.assoc = 1;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 0fbbb15..23ddf51 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1424,6 +1424,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
 
 	if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
 	    local->hw.conf.dynamic_ps_timeout > 0 &&
+	    !local->quiescing &&
 	    !(local->scanning) && local->ps_sdata) {
 		if (local->hw.conf.flags & IEEE80211_CONF_PS) {
 			ieee80211_stop_queues_by_reason(&local->hw,
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index efe0576..a7ccf02 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1060,7 +1060,22 @@ int ieee80211_reconfig(struct ieee80211_local *local)
 
 	/* restart hardware */
 	if (local->open_count) {
+		/*
+		 * Upon resume hardware can sometimes be goofy due to
+		 * various platform / driver / bus issues, so restarting
+		 * the device may at times not work immediately. Propagate
+		 * the error.
+		 */
 		res = drv_start(local);
+		if (res) {
+			if (local->suspended) {
+				printk(KERN_WARNING "Harware became unavailable "
+					"upon resume. This is could be a software issue"
+					"prior to suspend or a harware issue\n");
+				WARN_ON(1);
+			}
+			return res;
+		}
 
 		ieee80211_led_radio(local, true);
 	}
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 012c821..13fccdd 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -94,7 +94,18 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
 			}
 		}
 
-		WARN_ON(!bss);
+		/*
+		 * We might be coming here because the driver reported
+		 * a successful association at the same time as the
+		 * user requested a deauth. In that case, we will have
+		 * removed the BSS from the auth_bsses list due to the
+		 * deauth request when the assoc response makes it. If
+		 * the two code paths acquire the lock the other way
+		 * around, that's just the standard situation of a
+		 * deauth being requested while connected.
+		 */
+		if (!bss)
+			goto out;
 	} else if (wdev->conn) {
 		cfg80211_sme_failed_assoc(wdev);
 		need_connect_result = false;