]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.35 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Tue, 24 Aug 2010 17:40:51 +0000 (10:40 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 24 Aug 2010 17:40:51 +0000 (10:40 -0700)
queue-2.6.35/alsa-intel8x0-mute-external-amplifier-by-default-for-thinkpad-x31.patch [new file with mode: 0644]
queue-2.6.35/dm-separate-device-deletion-from-dm_put.patch [new file with mode: 0644]
queue-2.6.35/e1000e-disable-aspm-l1-on-82573.patch [new file with mode: 0644]
queue-2.6.35/e1000e-don-t-check-for-alternate-mac-addr-on-parts-that-don-t-support-it.patch [new file with mode: 0644]
queue-2.6.35/fixes-for-using-make-3.82.patch [new file with mode: 0644]
queue-2.6.35/iwlagn-fix-rts-cts-protection.patch [new file with mode: 0644]
queue-2.6.35/iwlwifi-fix-3945-filter-flags.patch [new file with mode: 0644]
queue-2.6.35/netlink-fix-compat-recvmsg.patch [new file with mode: 0644]
queue-2.6.35/series

diff --git a/queue-2.6.35/alsa-intel8x0-mute-external-amplifier-by-default-for-thinkpad-x31.patch b/queue-2.6.35/alsa-intel8x0-mute-external-amplifier-by-default-for-thinkpad-x31.patch
new file mode 100644 (file)
index 0000000..c3547a1
--- /dev/null
@@ -0,0 +1,38 @@
+From 9c77b846ec8b4e0c7107dd7f820172462dc84a61 Mon Sep 17 00:00:00 2001
+From: Daniel T Chen <crimsun@ubuntu.com>
+Date: Wed, 18 Aug 2010 19:33:43 -0400
+Subject: ALSA: intel8x0: Mute External Amplifier by default for ThinkPad X31
+
+From: Daniel T Chen <crimsun@ubuntu.com>
+
+commit 9c77b846ec8b4e0c7107dd7f820172462dc84a61 upstream.
+
+BugLink: https://bugs.launchpad.net/bugs/619439
+
+This ThinkPad model needs External Amplifier muted for audible playback,
+so set the inv_eapd quirk for it.
+
+Reported-and-tested-by: Dennis Bell <dennis.bell@parkerg.co.uk>
+Signed-off-by: Daniel T Chen <crimsun@ubuntu.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/pci/intel8x0.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/sound/pci/intel8x0.c
++++ b/sound/pci/intel8x0.c
+@@ -1776,6 +1776,12 @@ static struct ac97_quirk ac97_quirks[] _
+         },
+       {
+               .subvendor = 0x1014,
++              .subdevice = 0x0534,
++              .name = "ThinkPad X31",
++              .type = AC97_TUNE_INV_EAPD
++      },
++      {
++              .subvendor = 0x1014,
+               .subdevice = 0x1f00,
+               .name = "MS-9128",
+               .type = AC97_TUNE_ALC_JACK
diff --git a/queue-2.6.35/dm-separate-device-deletion-from-dm_put.patch b/queue-2.6.35/dm-separate-device-deletion-from-dm_put.patch
new file mode 100644 (file)
index 0000000..fba0437
--- /dev/null
@@ -0,0 +1,222 @@
+From 3f77316de0ec0fd208467fbee8d9edc70e2c73b2 Mon Sep 17 00:00:00 2001
+From: Kiyoshi Ueda <k-ueda@ct.jp.nec.com>
+Date: Thu, 12 Aug 2010 04:13:56 +0100
+Subject: dm: separate device deletion from dm_put
+
+From: Kiyoshi Ueda <k-ueda@ct.jp.nec.com>
+
+commit 3f77316de0ec0fd208467fbee8d9edc70e2c73b2 upstream.
+
+This patch separates the device deletion code from dm_put()
+to make sure the deletion happens in the process context.
+
+By this patch, device deletion always occurs in an ioctl (process)
+context and dm_put() can be called in interrupt context.
+As a result, the request-based dm's bad dm_put() usage pointed out
+by Mikulas below disappears.
+    http://marc.info/?l=dm-devel&m=126699981019735&w=2
+
+Without this patch, I confirmed there is a case to crash the system:
+    dm_put() => dm_table_destroy() => vfree() => BUG_ON(in_interrupt())
+
+Some more backgrounds and details:
+In request-based dm, a device opener can remove a mapped_device
+while the last request is still completing, because bios in the last
+request complete first and then the device opener can close and remove
+the mapped_device before the last request completes:
+  CPU0                                          CPU1
+  =================================================================
+  <<INTERRUPT>>
+  blk_end_request_all(clone_rq)
+    blk_update_request(clone_rq)
+      bio_endio(clone_bio) == end_clone_bio
+        blk_update_request(orig_rq)
+          bio_endio(orig_bio)
+                                                <<I/O completed>>
+                                                dm_blk_close()
+                                                dev_remove()
+                                                  dm_put(md)
+                                                    <<Free md>>
+   blk_finish_request(clone_rq)
+     ....
+     dm_end_request(clone_rq)
+       free_rq_clone(clone_rq)
+       blk_end_request_all(orig_rq)
+       rq_completed(md)
+
+So request-based dm used dm_get()/dm_put() to hold md for each I/O
+until its request completion handling is fully done.
+However, the final dm_put() can call the device deletion code which
+must not be run in interrupt context and may cause kernel panic.
+
+To solve the problem, this patch moves the device deletion code,
+dm_destroy(), to predetermined places that is actually deleting
+the mapped_device in ioctl (process) context, and changes dm_put()
+just to decrement the reference count of the mapped_device.
+By this change, dm_put() can be used in any context and the symmetric
+model below is introduced:
+    dm_create():  create a mapped_device
+    dm_destroy(): destroy a mapped_device
+    dm_get():     increment the reference count of a mapped_device
+    dm_put():     decrement the reference count of a mapped_device
+
+dm_destroy() waits for all references of the mapped_device to disappear,
+then deletes the mapped_device.
+
+dm_destroy() uses active waiting with msleep(1), since deleting
+the mapped_device isn't performance-critical task.
+And since at this point, nobody opens the mapped_device and no new
+reference will be taken, the pending counts are just for racing
+completing activity and will eventually decrease to zero.
+
+For the unlikely case of the forced module unload, dm_destroy_immediate(),
+which doesn't wait and forcibly deletes the mapped_device, is also
+introduced and used in dm_hash_remove_all().  Otherwise, "rmmod -f"
+may be stuck and never return.
+And now, because the mapped_device is deleted at this point, subsequent
+accesses to the mapped_device may cause NULL pointer references.
+
+Signed-off-by: Kiyoshi Ueda <k-ueda@ct.jp.nec.com>
+Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
+Signed-off-by: Alasdair G Kergon <agk@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/md/dm-ioctl.c |    6 ++++
+ drivers/md/dm.c       |   62 +++++++++++++++++++++++++++++++++++++-------------
+ drivers/md/dm.h       |    5 ++++
+ 3 files changed, 57 insertions(+), 16 deletions(-)
+
+--- a/drivers/md/dm-ioctl.c
++++ b/drivers/md/dm-ioctl.c
+@@ -274,6 +274,10 @@ retry:
+                       up_write(&_hash_lock);
+                       dm_put(md);
++                      if (likely(keep_open_devices))
++                              dm_destroy(md);
++                      else
++                              dm_destroy_immediate(md);
+                       /*
+                        * Some mapped devices may be using other mapped
+@@ -646,6 +650,7 @@ static int dev_create(struct dm_ioctl *p
+       r = dm_hash_insert(param->name, *param->uuid ? param->uuid : NULL, md);
+       if (r) {
+               dm_put(md);
++              dm_destroy(md);
+               return r;
+       }
+@@ -748,6 +753,7 @@ static int dev_remove(struct dm_ioctl *p
+               param->flags |= DM_UEVENT_GENERATED_FLAG;
+       dm_put(md);
++      dm_destroy(md);
+       return 0;
+ }
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -19,6 +19,7 @@
+ #include <linux/slab.h>
+ #include <linux/idr.h>
+ #include <linux/hdreg.h>
++#include <linux/delay.h>
+ #include <trace/events/block.h>
+@@ -2176,6 +2177,7 @@ void dm_set_mdptr(struct mapped_device *
+ void dm_get(struct mapped_device *md)
+ {
+       atomic_inc(&md->holders);
++      BUG_ON(test_bit(DMF_FREEING, &md->flags));
+ }
+ const char *dm_device_name(struct mapped_device *md)
+@@ -2184,27 +2186,55 @@ const char *dm_device_name(struct mapped
+ }
+ EXPORT_SYMBOL_GPL(dm_device_name);
+-void dm_put(struct mapped_device *md)
++static void __dm_destroy(struct mapped_device *md, bool wait)
+ {
+       struct dm_table *map;
+-      BUG_ON(test_bit(DMF_FREEING, &md->flags));
++      might_sleep();
+-      if (atomic_dec_and_lock(&md->holders, &_minor_lock)) {
+-              map = dm_get_live_table(md);
+-              idr_replace(&_minor_idr, MINOR_ALLOCED,
+-                          MINOR(disk_devt(dm_disk(md))));
+-              set_bit(DMF_FREEING, &md->flags);
+-              spin_unlock(&_minor_lock);
+-              if (!dm_suspended_md(md)) {
+-                      dm_table_presuspend_targets(map);
+-                      dm_table_postsuspend_targets(map);
+-              }
+-              dm_sysfs_exit(md);
+-              dm_table_put(map);
+-              dm_table_destroy(__unbind(md));
+-              free_dev(md);
++      spin_lock(&_minor_lock);
++      map = dm_get_live_table(md);
++      idr_replace(&_minor_idr, MINOR_ALLOCED, MINOR(disk_devt(dm_disk(md))));
++      set_bit(DMF_FREEING, &md->flags);
++      spin_unlock(&_minor_lock);
++
++      if (!dm_suspended_md(md)) {
++              dm_table_presuspend_targets(map);
++              dm_table_postsuspend_targets(map);
+       }
++
++      /*
++       * Rare, but there may be I/O requests still going to complete,
++       * for example.  Wait for all references to disappear.
++       * No one should increment the reference count of the mapped_device,
++       * after the mapped_device state becomes DMF_FREEING.
++       */
++      if (wait)
++              while (atomic_read(&md->holders))
++                      msleep(1);
++      else if (atomic_read(&md->holders))
++              DMWARN("%s: Forcibly removing mapped_device still in use! (%d users)",
++                     dm_device_name(md), atomic_read(&md->holders));
++
++      dm_sysfs_exit(md);
++      dm_table_put(map);
++      dm_table_destroy(__unbind(md));
++      free_dev(md);
++}
++
++void dm_destroy(struct mapped_device *md)
++{
++      __dm_destroy(md, true);
++}
++
++void dm_destroy_immediate(struct mapped_device *md)
++{
++      __dm_destroy(md, false);
++}
++
++void dm_put(struct mapped_device *md)
++{
++      atomic_dec(&md->holders);
+ }
+ EXPORT_SYMBOL_GPL(dm_put);
+--- a/drivers/md/dm.h
++++ b/drivers/md/dm.h
+@@ -122,6 +122,11 @@ void dm_linear_exit(void);
+ int dm_stripe_init(void);
+ void dm_stripe_exit(void);
++/*
++ * mapped_device operations
++ */
++void dm_destroy(struct mapped_device *md);
++void dm_destroy_immediate(struct mapped_device *md);
+ int dm_open_count(struct mapped_device *md);
+ int dm_lock_for_deletion(struct mapped_device *md);
diff --git a/queue-2.6.35/e1000e-disable-aspm-l1-on-82573.patch b/queue-2.6.35/e1000e-disable-aspm-l1-on-82573.patch
new file mode 100644 (file)
index 0000000..e76cb8c
--- /dev/null
@@ -0,0 +1,35 @@
+From 19833b5dffe2f2e92a1b377f9aae9d5f32239512 Mon Sep 17 00:00:00 2001
+From: Bruce Allan <bruce.w.allan@intel.com>
+Date: Thu, 19 Aug 2010 15:48:30 -0700
+Subject: e1000e: disable ASPM L1 on 82573
+
+From: Bruce Allan <bruce.w.allan@intel.com>
+
+commit 19833b5dffe2f2e92a1b377f9aae9d5f32239512 upstream.
+
+On the e1000-devel mailing list, Nils Faerber reported latency issues with
+the 82573 LOM on a ThinkPad X60.  It was found to be caused by ASPM L1;
+disabling it resolves the latency.  The issue is present in kernels back
+to 2.6.34 and possibly 2.6.33.
+
+
+Reported-by: Nils Faerber <nils.faerber@kernelconcepts.de>
+Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
+Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/e1000e/82571.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/e1000e/82571.c
++++ b/drivers/net/e1000e/82571.c
+@@ -1833,6 +1833,7 @@ struct e1000_info e1000_82573_info = {
+                                 | FLAG_HAS_SMART_POWER_DOWN
+                                 | FLAG_HAS_AMT
+                                 | FLAG_HAS_SWSM_ON_LOAD,
++      .flags2                 = FLAG2_DISABLE_ASPM_L1,
+       .pba                    = 20,
+       .max_hw_frame_size      = ETH_FRAME_LEN + ETH_FCS_LEN,
+       .get_variants           = e1000_get_variants_82571,
diff --git a/queue-2.6.35/e1000e-don-t-check-for-alternate-mac-addr-on-parts-that-don-t-support-it.patch b/queue-2.6.35/e1000e-don-t-check-for-alternate-mac-addr-on-parts-that-don-t-support-it.patch
new file mode 100644 (file)
index 0000000..fb30aa4
--- /dev/null
@@ -0,0 +1,118 @@
+From 1aef70ef125165e0114a8e475636eff242a52030 Mon Sep 17 00:00:00 2001
+From: Bruce Allan <bruce.w.allan@intel.com>
+Date: Thu, 19 Aug 2010 15:48:52 -0700
+Subject: e1000e: don't check for alternate MAC addr on parts that don't support it
+
+From: Bruce Allan <bruce.w.allan@intel.com>
+
+commit 1aef70ef125165e0114a8e475636eff242a52030 upstream.
+
+From: Bruce Allan <bruce.w.allan@intel.com>
+
+The alternate MAC address feature is only supported by 80003ES2LAN and
+82571 LOMs as well as a couple 82571 mezzanine cards.  Checking for an
+alternate MAC address on other parts can fail leading to the driver not
+able to load.  This patch limits the check for an alternate MAC address
+to be done only for parts that support the feature.
+
+This issue has been around since support for the feature was introduced
+to the e1000e driver in 2.6.34.
+
+Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
+Reported-by: Fabio Varesano <fax8@users.sourceforge.net>
+Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/e1000e/82571.c   |   30 +++++++++++++++++-------------
+ drivers/net/e1000e/defines.h |    4 ++++
+ drivers/net/e1000e/lib.c     |   10 ++++++++++
+ 3 files changed, 31 insertions(+), 13 deletions(-)
+
+--- a/drivers/net/e1000e/82571.c
++++ b/drivers/net/e1000e/82571.c
+@@ -936,12 +936,14 @@ static s32 e1000_reset_hw_82571(struct e
+       ew32(IMC, 0xffffffff);
+       icr = er32(ICR);
+-      /* Install any alternate MAC address into RAR0 */
+-      ret_val = e1000_check_alt_mac_addr_generic(hw);
+-      if (ret_val)
+-              return ret_val;
++      if (hw->mac.type == e1000_82571) {
++              /* Install any alternate MAC address into RAR0 */
++              ret_val = e1000_check_alt_mac_addr_generic(hw);
++              if (ret_val)
++                      return ret_val;
+-      e1000e_set_laa_state_82571(hw, true);
++              e1000e_set_laa_state_82571(hw, true);
++      }
+       /* Reinitialize the 82571 serdes link state machine */
+       if (hw->phy.media_type == e1000_media_type_internal_serdes)
+@@ -1618,14 +1620,16 @@ static s32 e1000_read_mac_addr_82571(str
+ {
+       s32 ret_val = 0;
+-      /*
+-       * If there's an alternate MAC address place it in RAR0
+-       * so that it will override the Si installed default perm
+-       * address.
+-       */
+-      ret_val = e1000_check_alt_mac_addr_generic(hw);
+-      if (ret_val)
+-              goto out;
++      if (hw->mac.type == e1000_82571) {
++              /*
++               * If there's an alternate MAC address place it in RAR0
++               * so that it will override the Si installed default perm
++               * address.
++               */
++              ret_val = e1000_check_alt_mac_addr_generic(hw);
++              if (ret_val)
++                      goto out;
++      }
+       ret_val = e1000_read_mac_addr_generic(hw);
+--- a/drivers/net/e1000e/defines.h
++++ b/drivers/net/e1000e/defines.h
+@@ -620,6 +620,7 @@
+ #define E1000_FLASH_UPDATES  2000
+ /* NVM Word Offsets */
++#define NVM_COMPAT                 0x0003
+ #define NVM_ID_LED_SETTINGS        0x0004
+ #define NVM_INIT_CONTROL2_REG      0x000F
+ #define NVM_INIT_CONTROL3_PORT_B   0x0014
+@@ -642,6 +643,9 @@
+ /* Mask bits for fields in Word 0x1a of the NVM */
+ #define NVM_WORD1A_ASPM_MASK  0x000C
++/* Mask bits for fields in Word 0x03 of the EEPROM */
++#define NVM_COMPAT_LOM    0x0800
++
+ /* For checksumming, the sum of all words in the NVM should equal 0xBABA. */
+ #define NVM_SUM                    0xBABA
+--- a/drivers/net/e1000e/lib.c
++++ b/drivers/net/e1000e/lib.c
+@@ -183,6 +183,16 @@ s32 e1000_check_alt_mac_addr_generic(str
+       u16 offset, nvm_alt_mac_addr_offset, nvm_data;
+       u8 alt_mac_addr[ETH_ALEN];
++      ret_val = e1000_read_nvm(hw, NVM_COMPAT, 1, &nvm_data);
++      if (ret_val)
++              goto out;
++
++      /* Check for LOM (vs. NIC) or one of two valid mezzanine cards */
++      if (!((nvm_data & NVM_COMPAT_LOM) ||
++            (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_DUAL) ||
++            (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD)))
++              goto out;
++
+       ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
+                                &nvm_alt_mac_addr_offset);
+       if (ret_val) {
diff --git a/queue-2.6.35/fixes-for-using-make-3.82.patch b/queue-2.6.35/fixes-for-using-make-3.82.patch
new file mode 100644 (file)
index 0000000..9197677
--- /dev/null
@@ -0,0 +1,48 @@
+From 3c955b407a084810f57260d61548cc92c14bc627 Mon Sep 17 00:00:00 2001
+From: Jan Beulich <JBeulich@novell.com>
+Date: Mon, 16 Aug 2010 11:58:58 +0100
+Subject: fixes for using make 3.82
+
+From: Jan Beulich <JBeulich@novell.com>
+
+commit 3c955b407a084810f57260d61548cc92c14bc627 upstream.
+
+It doesn't like pattern and explicit rules to be on the same line,
+and it seems to be more picky when matching file (or really directory)
+names with different numbers of trailing slashes.
+
+Signed-off-by: Jan Beulich <jbeulich@novell.com>
+Acked-by: Sam Ravnborg <sam@ravnborg.org>
+Andrew Benton <b3nton@gmail.com>
+Signed-off-by: Michal Marek <mmarek@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ firmware/Makefile  |    2 +-
+ scripts/mkmakefile |    4 +++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -142,7 +142,7 @@ fw-shipped-$(CONFIG_YAM) += yam/1200.bin
+ fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-)
+ # Directories which we _might_ need to create, so we have a rule for them.
+-firmware-dirs := $(sort $(patsubst %,$(objtree)/$(obj)/%/,$(dir $(fw-external-y) $(fw-shipped-all))))
++firmware-dirs := $(sort $(addprefix $(objtree)/$(obj)/,$(dir $(fw-external-y) $(fw-shipped-all))))
+ quiet_cmd_mkdir = MKDIR   $(patsubst $(objtree)/%,%,$@)
+       cmd_mkdir = mkdir -p $@
+--- a/scripts/mkmakefile
++++ b/scripts/mkmakefile
+@@ -44,7 +44,9 @@ all:
+ Makefile:;
+-\$(all) %/: all
++\$(all): all
+       @:
++%/: all
++      @:
+ EOF
diff --git a/queue-2.6.35/iwlagn-fix-rts-cts-protection.patch b/queue-2.6.35/iwlagn-fix-rts-cts-protection.patch
new file mode 100644 (file)
index 0000000..9982c28
--- /dev/null
@@ -0,0 +1,332 @@
+From 94597ab23ea10b3bdcba534be00a9f7b35791c07 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Mon, 9 Aug 2010 10:57:02 -0700
+Subject: iwlagn: fix rts cts protection
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+This is a backport of mainline commit
+94597ab23ea10b3bdcba534be00a9f7b35791c07.
+I removed the variable renamings from it
+and made it apply on 2.6.35. It now also
+incorporates some changes from commit
+cfecc6b492162fb49209a83dc207f182b87ea27a
+since those were required as well.
+commit 94597ab23ea10b3bdcba534be00a9f7b35791c07 upstream.
+
+Currently the driver will try to protect all frames,
+which leads to a lot of odd things like sending an
+RTS with a zeroed RA before multicast frames, which
+is clearly bogus.
+
+In order to fix all of this, we need to take a step
+back and see what we need to achieve:
+ * we need RTS/CTS protection if requested by
+   the AP for the BSS, mac80211 tells us this
+ * in that case, CTS-to-self should only be
+   enabled when mac80211 tells us
+ * additionally, as a hardware workaround, on
+   some devices we have to protect aggregated
+   frames with RTS
+
+To achieve the first two items, set up the RXON
+accordingly and set the protection required flag
+in the transmit command when mac80211 requests
+protection for the frame.
+
+To achieve the last item, set the rate-control
+RTS-requested flag for all stations that we have
+aggregation sessions with, and set the protection
+required flag when sending aggregated frames (on
+those devices where this is required).
+
+Since otherwise bugs can occur, do not allow the
+user to override the RTS-for-aggregation setting
+from sysfs any more.
+
+Finally, also clean up the way all these flags get
+set in the driver and move everything into the
+device-specific functions.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/net/wireless/iwlwifi/iwl-3945.c     |   16 -----------
+ drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c |   17 ++++++++++--
+ drivers/net/wireless/iwlwifi/iwl-agn-rs.c   |   17 +++---------
+ drivers/net/wireless/iwlwifi/iwl-agn-tx.c   |   20 --------------
+ drivers/net/wireless/iwlwifi/iwl-agn.c      |   38 +++++++++++++++++++++-------
+ drivers/net/wireless/iwlwifi/iwl-core.c     |   25 ++++++++++++++++--
+ drivers/net/wireless/iwlwifi/iwl-core.h     |   10 ++++---
+ drivers/net/wireless/iwlwifi/iwl3945-base.c |    5 ---
+ 8 files changed, 79 insertions(+), 69 deletions(-)
+
+--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
++++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
+@@ -915,22 +915,6 @@ void iwl3945_hw_build_tx_cmd_rate(struct
+               rts_retry_limit = data_retry_limit;
+       tx_cmd->rts_retry_limit = rts_retry_limit;
+-      if (ieee80211_is_mgmt(fc)) {
+-              switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
+-              case cpu_to_le16(IEEE80211_STYPE_AUTH):
+-              case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
+-              case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
+-              case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
+-                      if (tx_flags & TX_CMD_FLG_RTS_MSK) {
+-                              tx_flags &= ~TX_CMD_FLG_RTS_MSK;
+-                              tx_flags |= TX_CMD_FLG_CTS_MSK;
+-                      }
+-                      break;
+-              default:
+-                      break;
+-              }
+-      }
+-
+       tx_cmd->rate = rate;
+       tx_cmd->tx_flags = tx_flags;
+--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
++++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
+@@ -209,10 +209,21 @@ static void iwlagn_chain_noise_reset(str
+       }
+ }
+-static void iwlagn_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
+-                      __le32 *tx_flags)
++static void iwlagn_rts_tx_cmd_flag(struct iwl_priv *priv,
++                                   struct ieee80211_tx_info *info,
++                                   __le16 fc, __le32 *tx_flags)
+ {
+-      *tx_flags |= TX_CMD_FLG_RTS_CTS_MSK;
++      if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS ||
++          info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
++              *tx_flags |= TX_CMD_FLG_RTS_CTS_MSK;
++              return;
++      }
++
++      if (priv->cfg->use_rts_for_ht &&
++          info->flags & IEEE80211_TX_CTL_AMPDU) {
++              *tx_flags |= TX_CMD_FLG_RTS_CTS_MSK;
++              return;
++      }
+ }
+ /* Calc max signal level (dBm) among 3 possible receivers */
+--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
++++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+@@ -325,18 +325,11 @@ static void rs_tl_turn_on_agg(struct iwl
+                             struct iwl_lq_sta *lq_data,
+                             struct ieee80211_sta *sta)
+ {
+-      if ((tid < TID_MAX_LOAD_COUNT) &&
+-          !rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta)) {
+-              if (priv->cfg->use_rts_for_ht) {
+-                      /*
+-                       * switch to RTS/CTS if it is the prefer protection
+-                       * method for HT traffic
+-                       */
+-                      IWL_DEBUG_HT(priv, "use RTS/CTS protection for HT\n");
+-                      priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN;
+-                      iwlcore_commit_rxon(priv);
+-              }
+-      }
++      if (tid < TID_MAX_LOAD_COUNT)
++              rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
++      else
++              IWL_ERR(priv, "tid exceeds max load count: %d/%d\n",
++                      tid, TID_MAX_LOAD_COUNT);
+ }
+ static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
+--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
++++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+@@ -376,10 +376,7 @@ static void iwlagn_tx_cmd_build_basic(st
+               tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
+       }
+-      priv->cfg->ops->utils->rts_tx_cmd_flag(info, &tx_flags);
+-
+-      if ((tx_flags & TX_CMD_FLG_RTS_MSK) || (tx_flags & TX_CMD_FLG_CTS_MSK))
+-              tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
++      priv->cfg->ops->utils->rts_tx_cmd_flag(priv, info, fc, &tx_flags);
+       tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
+       if (ieee80211_is_mgmt(fc)) {
+@@ -453,21 +450,6 @@ static void iwlagn_tx_cmd_build_rate(str
+       if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
+               rate_flags |= RATE_MCS_CCK_MSK;
+-      /* Set up RTS and CTS flags for certain packets */
+-      switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
+-      case cpu_to_le16(IEEE80211_STYPE_AUTH):
+-      case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
+-      case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
+-      case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
+-              if (tx_cmd->tx_flags & TX_CMD_FLG_RTS_MSK) {
+-                      tx_cmd->tx_flags &= ~TX_CMD_FLG_RTS_MSK;
+-                      tx_cmd->tx_flags |= TX_CMD_FLG_CTS_MSK;
+-              }
+-              break;
+-      default:
+-              break;
+-      }
+-
+       /* Set up antennas */
+       priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant);
+       rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
+--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
++++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
+@@ -200,13 +200,6 @@ int iwl_commit_rxon(struct iwl_priv *pri
+       priv->start_calib = 0;
+       if (new_assoc) {
+-              /*
+-               * allow CTS-to-self if possible for new association.
+-               * this is relevant only for 5000 series and up,
+-               * but will not damage 4965
+-               */
+-              priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
+-
+               /* Apply the new configuration
+                * RXON assoc doesn't clear the station table in uCode,
+                */
+@@ -3336,13 +3329,40 @@ static int iwl_mac_ampdu_action(struct i
+                       IWL_DEBUG_HT(priv, "priv->_agn.agg_tids_count = %u\n",
+                                    priv->_agn.agg_tids_count);
+               }
++              if (priv->cfg->use_rts_for_ht) {
++                      struct iwl_station_priv *sta_priv =
++                              (void *) sta->drv_priv;
++                      /*
++                       * switch off RTS/CTS if it was previously enabled
++                       */
++
++                      sta_priv->lq_sta.lq.general_params.flags &=
++                              ~LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK;
++                      iwl_send_lq_cmd(priv, &sta_priv->lq_sta.lq,
++                              CMD_ASYNC, false);
++              }
++              break;
+               if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+                       return 0;
+               else
+                       return ret;
+       case IEEE80211_AMPDU_TX_OPERATIONAL:
+-              /* do nothing */
+-              return -EOPNOTSUPP;
++              if (priv->cfg->use_rts_for_ht) {
++                      struct iwl_station_priv *sta_priv =
++                              (void *) sta->drv_priv;
++
++                      /*
++                       * switch to RTS/CTS if it is the prefer protection
++                       * method for HT traffic
++                       */
++
++                      sta_priv->lq_sta.lq.general_params.flags |=
++                              LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK;
++                      iwl_send_lq_cmd(priv, &sta_priv->lq_sta.lq,
++                              CMD_ASYNC, false);
++              }
++              ret = 0;
++              break;
+       default:
+               IWL_DEBUG_HT(priv, "unknown\n");
+               return -EINVAL;
+--- a/drivers/net/wireless/iwlwifi/iwl-core.c
++++ b/drivers/net/wireless/iwlwifi/iwl-core.c
+@@ -403,19 +403,36 @@ EXPORT_SYMBOL(iwlcore_free_geos);
+  *  iwlcore_rts_tx_cmd_flag: Set rts/cts. 3945 and 4965 only share this
+  *  function.
+  */
+-void iwlcore_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
+-                              __le32 *tx_flags)
++void iwlcore_rts_tx_cmd_flag(struct iwl_priv *priv,
++                             struct ieee80211_tx_info *info,
++                             __le16 fc, __le32 *tx_flags)
+ {
+       if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
+               *tx_flags |= TX_CMD_FLG_RTS_MSK;
+               *tx_flags &= ~TX_CMD_FLG_CTS_MSK;
++              *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
++
++              if (!ieee80211_is_mgmt(fc))
++                      return;
++
++              switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
++              case cpu_to_le16(IEEE80211_STYPE_AUTH):
++              case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
++              case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
++              case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
++                      *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
++                      *tx_flags |= TX_CMD_FLG_CTS_MSK;
++                      break;
++              }
+       } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
+               *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
+               *tx_flags |= TX_CMD_FLG_CTS_MSK;
++              *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
+       }
+ }
+ EXPORT_SYMBOL(iwlcore_rts_tx_cmd_flag);
++
+ static bool is_single_rx_stream(struct iwl_priv *priv)
+ {
+       return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC ||
+@@ -1936,6 +1953,10 @@ void iwl_bss_info_changed(struct ieee802
+                       priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
+               else
+                       priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
++              if (bss_conf->use_cts_prot)
++                      priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
++              else
++                      priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN;
+       }
+       if (changes & BSS_CHANGED_BASIC_RATES) {
+--- a/drivers/net/wireless/iwlwifi/iwl-core.h
++++ b/drivers/net/wireless/iwlwifi/iwl-core.h
+@@ -102,8 +102,9 @@ struct iwl_hcmd_utils_ops {
+                       u32 min_average_noise,
+                       u8 default_chain);
+       void (*chain_noise_reset)(struct iwl_priv *priv);
+-      void (*rts_tx_cmd_flag)(struct ieee80211_tx_info *info,
+-                      __le32 *tx_flags);
++      void (*rts_tx_cmd_flag)(struct iwl_priv *priv,
++                                struct ieee80211_tx_info *info,
++                                __le16 fc, __le32 *tx_flags);
+       int  (*calc_rssi)(struct iwl_priv *priv,
+                         struct iwl_rx_phy_res *rx_resp);
+       void (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif);
+@@ -375,8 +376,9 @@ void iwl_config_ap(struct iwl_priv *priv
+ void iwl_mac_reset_tsf(struct ieee80211_hw *hw);
+ int iwl_alloc_txq_mem(struct iwl_priv *priv);
+ void iwl_free_txq_mem(struct iwl_priv *priv);
+-void iwlcore_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
+-                              __le32 *tx_flags);
++void iwlcore_rts_tx_cmd_flag(struct iwl_priv *priv,
++                             struct ieee80211_tx_info *info,
++                             __le16 fc, __le32 *tx_flags);
+ #ifdef CONFIG_IWLWIFI_DEBUGFS
+ int iwl_alloc_traffic_mem(struct iwl_priv *priv);
+ void iwl_free_traffic_mem(struct iwl_priv *priv);
+--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
++++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
+@@ -434,10 +434,7 @@ static void iwl3945_build_tx_cmd_basic(s
+               tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
+       }
+-      priv->cfg->ops->utils->rts_tx_cmd_flag(info, &tx_flags);
+-
+-      if ((tx_flags & TX_CMD_FLG_RTS_MSK) || (tx_flags & TX_CMD_FLG_CTS_MSK))
+-              tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
++      priv->cfg->ops->utils->rts_tx_cmd_flag(priv, info, fc, &tx_flags);
+       tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
+       if (ieee80211_is_mgmt(fc)) {
diff --git a/queue-2.6.35/iwlwifi-fix-3945-filter-flags.patch b/queue-2.6.35/iwlwifi-fix-3945-filter-flags.patch
new file mode 100644 (file)
index 0000000..4466ae4
--- /dev/null
@@ -0,0 +1,231 @@
+From 8b8ab9d5e352aae0dcae53c657b25ab61bb73f0f Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Tue, 17 Aug 2010 11:24:01 +0200
+Subject: iwlwifi: fix 3945 filter flags
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 8b8ab9d5e352aae0dcae53c657b25ab61bb73f0f upstream.
+
+Applying the filter flags directly as done since
+
+commit 3474ad635db371b0d8d0ee40086f15d223d5b6a4
+Author: Johannes Berg <johannes.berg@intel.com>
+Date:   Thu Apr 29 04:43:05 2010 -0700
+
+    iwlwifi: apply filter flags directly
+
+broke 3945 under some unknown circumstances, as
+reported by Alex.
+
+Since I want to keep the direct application of
+filter flags on iwlagn, duplicate the code into
+both 3945 and agn and remove committing the
+RXON that broke things from the 3945 version.
+
+Reported-by: Alex Romosan <romosan@sycorax.lbl.gov>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/iwlwifi/iwl-agn.c      |   45 ++++++++++++++++++++++++
+ drivers/net/wireless/iwlwifi/iwl-core.c     |   45 ------------------------
+ drivers/net/wireless/iwlwifi/iwl-core.h     |    3 -
+ drivers/net/wireless/iwlwifi/iwl3945-base.c |   51 +++++++++++++++++++++++++++-
+ 4 files changed, 94 insertions(+), 50 deletions(-)
+
+--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
++++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
+@@ -3443,6 +3443,49 @@ static int iwlagn_mac_sta_add(struct iee
+       return 0;
+ }
++static void iwlagn_configure_filter(struct ieee80211_hw *hw,
++                                  unsigned int changed_flags,
++                                  unsigned int *total_flags,
++                                  u64 multicast)
++{
++      struct iwl_priv *priv = hw->priv;
++      __le32 filter_or = 0, filter_nand = 0;
++
++#define CHK(test, flag)       do { \
++      if (*total_flags & (test))              \
++              filter_or |= (flag);            \
++      else                                    \
++              filter_nand |= (flag);          \
++      } while (0)
++
++      IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n",
++                      changed_flags, *total_flags);
++
++      CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK);
++      CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK);
++      CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK);
++
++#undef CHK
++
++      mutex_lock(&priv->mutex);
++
++      priv->staging_rxon.filter_flags &= ~filter_nand;
++      priv->staging_rxon.filter_flags |= filter_or;
++
++      iwlcore_commit_rxon(priv);
++
++      mutex_unlock(&priv->mutex);
++
++      /*
++       * Receiving all multicast frames is always enabled by the
++       * default flags setup in iwl_connection_init_rx_config()
++       * since we currently do not support programming multicast
++       * filters into the device.
++       */
++      *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
++                      FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
++}
++
+ /*****************************************************************************
+  *
+  * driver setup and teardown
+@@ -3603,7 +3646,7 @@ static struct ieee80211_ops iwl_hw_ops =
+       .add_interface = iwl_mac_add_interface,
+       .remove_interface = iwl_mac_remove_interface,
+       .config = iwl_mac_config,
+-      .configure_filter = iwl_configure_filter,
++      .configure_filter = iwlagn_configure_filter,
+       .set_key = iwl_mac_set_key,
+       .update_tkip_key = iwl_mac_update_tkip_key,
+       .conf_tx = iwl_mac_conf_tx,
+--- a/drivers/net/wireless/iwlwifi/iwl-core.c
++++ b/drivers/net/wireless/iwlwifi/iwl-core.c
+@@ -1311,51 +1311,6 @@ out:
+ EXPORT_SYMBOL(iwl_apm_init);
+-
+-void iwl_configure_filter(struct ieee80211_hw *hw,
+-                        unsigned int changed_flags,
+-                        unsigned int *total_flags,
+-                        u64 multicast)
+-{
+-      struct iwl_priv *priv = hw->priv;
+-      __le32 filter_or = 0, filter_nand = 0;
+-
+-#define CHK(test, flag)       do { \
+-      if (*total_flags & (test))              \
+-              filter_or |= (flag);            \
+-      else                                    \
+-              filter_nand |= (flag);          \
+-      } while (0)
+-
+-      IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n",
+-                      changed_flags, *total_flags);
+-
+-      CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK);
+-      CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK);
+-      CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK);
+-
+-#undef CHK
+-
+-      mutex_lock(&priv->mutex);
+-
+-      priv->staging_rxon.filter_flags &= ~filter_nand;
+-      priv->staging_rxon.filter_flags |= filter_or;
+-
+-      iwlcore_commit_rxon(priv);
+-
+-      mutex_unlock(&priv->mutex);
+-
+-      /*
+-       * Receiving all multicast frames is always enabled by the
+-       * default flags setup in iwl_connection_init_rx_config()
+-       * since we currently do not support programming multicast
+-       * filters into the device.
+-       */
+-      *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
+-                      FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
+-}
+-EXPORT_SYMBOL(iwl_configure_filter);
+-
+ int iwl_set_hw_params(struct iwl_priv *priv)
+ {
+       priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
+--- a/drivers/net/wireless/iwlwifi/iwl-core.h
++++ b/drivers/net/wireless/iwlwifi/iwl-core.h
+@@ -356,9 +356,6 @@ int iwl_set_decrypted_flag(struct iwl_pr
+                          u32 decrypt_res,
+                          struct ieee80211_rx_status *stats);
+ void iwl_irq_handle_error(struct iwl_priv *priv);
+-void iwl_configure_filter(struct ieee80211_hw *hw,
+-                        unsigned int changed_flags,
+-                        unsigned int *total_flags, u64 multicast);
+ int iwl_set_hw_params(struct iwl_priv *priv);
+ void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif);
+ void iwl_bss_info_changed(struct ieee80211_hw *hw,
+--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
++++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
+@@ -3462,6 +3462,55 @@ static int iwl3945_mac_sta_add(struct ie
+       return 0;
+ }
++
++static void iwl3945_configure_filter(struct ieee80211_hw *hw,
++                                   unsigned int changed_flags,
++                                   unsigned int *total_flags,
++                                   u64 multicast)
++{
++      struct iwl_priv *priv = hw->priv;
++      __le32 filter_or = 0, filter_nand = 0;
++
++#define CHK(test, flag)       do { \
++      if (*total_flags & (test))              \
++              filter_or |= (flag);            \
++      else                                    \
++              filter_nand |= (flag);          \
++      } while (0)
++
++      IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n",
++                      changed_flags, *total_flags);
++
++      CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK);
++      CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK);
++      CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK);
++
++#undef CHK
++
++      mutex_lock(&priv->mutex);
++
++      priv->staging_rxon.filter_flags &= ~filter_nand;
++      priv->staging_rxon.filter_flags |= filter_or;
++
++      /*
++       * Committing directly here breaks for some reason,
++       * but we'll eventually commit the filter flags
++       * change anyway.
++       */
++
++      mutex_unlock(&priv->mutex);
++
++      /*
++       * Receiving all multicast frames is always enabled by the
++       * default flags setup in iwl_connection_init_rx_config()
++       * since we currently do not support programming multicast
++       * filters into the device.
++       */
++      *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
++                      FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
++}
++
++
+ /*****************************************************************************
+  *
+  * sysfs attributes
+@@ -3867,7 +3916,7 @@ static struct ieee80211_ops iwl3945_hw_o
+       .add_interface = iwl_mac_add_interface,
+       .remove_interface = iwl_mac_remove_interface,
+       .config = iwl_mac_config,
+-      .configure_filter = iwl_configure_filter,
++      .configure_filter = iwl3945_configure_filter,
+       .set_key = iwl3945_mac_set_key,
+       .conf_tx = iwl_mac_conf_tx,
+       .reset_tsf = iwl_mac_reset_tsf,
diff --git a/queue-2.6.35/netlink-fix-compat-recvmsg.patch b/queue-2.6.35/netlink-fix-compat-recvmsg.patch
new file mode 100644 (file)
index 0000000..bc339ca
--- /dev/null
@@ -0,0 +1,130 @@
+From 68d6ac6d2740b6a55f3ae92a4e0be6d881904b32 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Sun, 15 Aug 2010 21:20:44 +0000
+Subject: netlink: fix compat recvmsg
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 68d6ac6d2740b6a55f3ae92a4e0be6d881904b32 upstream.
+
+Since
+commit 1dacc76d0014a034b8aca14237c127d7c19d7726
+Author: Johannes Berg <johannes@sipsolutions.net>
+Date:   Wed Jul 1 11:26:02 2009 +0000
+
+    net/compat/wext: send different messages to compat tasks
+
+we had a race condition when setting and then
+restoring frag_list. Eric attempted to fix it,
+but the fix created even worse problems.
+
+However, the original motivation I had when I
+added the code that turned out to be racy is
+no longer clear to me, since we only copy up
+to skb->len to userspace, which doesn't include
+the frag_list length. As a result, not doing
+any frag_list clearing and restoring avoids
+the race condition, while not introducing any
+other problems.
+
+Additionally, while preparing this patch I found
+that since none of the remaining netlink code is
+really aware of the frag_list, we need to use the
+original skb's information for packet information
+and credentials. This fixes, for example, the
+group information received by compat tasks.
+
+Cc: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/netlink/af_netlink.c |   46 ++++++++++++++++------------------------------
+ 1 file changed, 16 insertions(+), 30 deletions(-)
+
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1400,7 +1400,7 @@ static int netlink_recvmsg(struct kiocb
+       struct netlink_sock *nlk = nlk_sk(sk);
+       int noblock = flags&MSG_DONTWAIT;
+       size_t copied;
+-      struct sk_buff *skb, *frag __maybe_unused = NULL;
++      struct sk_buff *skb, *data_skb;
+       int err;
+       if (flags&MSG_OOB)
+@@ -1412,45 +1412,35 @@ static int netlink_recvmsg(struct kiocb
+       if (skb == NULL)
+               goto out;
++      data_skb = skb;
++
+ #ifdef CONFIG_COMPAT_NETLINK_MESSAGES
+       if (unlikely(skb_shinfo(skb)->frag_list)) {
+-              bool need_compat = !!(flags & MSG_CMSG_COMPAT);
+-
+               /*
+-               * If this skb has a frag_list, then here that means that
+-               * we will have to use the frag_list skb for compat tasks
+-               * and the regular skb for non-compat tasks.
++               * If this skb has a frag_list, then here that means that we
++               * will have to use the frag_list skb's data for compat tasks
++               * and the regular skb's data for normal (non-compat) tasks.
+                *
+-               * The skb might (and likely will) be cloned, so we can't
+-               * just reset frag_list and go on with things -- we need to
+-               * keep that. For the compat case that's easy -- simply get
+-               * a reference to the compat skb and free the regular one
+-               * including the frag. For the non-compat case, we need to
+-               * avoid sending the frag to the user -- so assign NULL but
+-               * restore it below before freeing the skb.
++               * If we need to send the compat skb, assign it to the
++               * 'data_skb' variable so that it will be used below for data
++               * copying. We keep 'skb' for everything else, including
++               * freeing both later.
+                */
+-              if (need_compat) {
+-                      struct sk_buff *compskb = skb_shinfo(skb)->frag_list;
+-                      skb_get(compskb);
+-                      kfree_skb(skb);
+-                      skb = compskb;
+-              } else {
+-                      frag = skb_shinfo(skb)->frag_list;
+-                      skb_shinfo(skb)->frag_list = NULL;
+-              }
++              if (flags & MSG_CMSG_COMPAT)
++                      data_skb = skb_shinfo(skb)->frag_list;
+       }
+ #endif
+       msg->msg_namelen = 0;
+-      copied = skb->len;
++      copied = data_skb->len;
+       if (len < copied) {
+               msg->msg_flags |= MSG_TRUNC;
+               copied = len;
+       }
+-      skb_reset_transport_header(skb);
+-      err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
++      skb_reset_transport_header(data_skb);
++      err = skb_copy_datagram_iovec(data_skb, 0, msg->msg_iov, copied);
+       if (msg->msg_name) {
+               struct sockaddr_nl *addr = (struct sockaddr_nl *)msg->msg_name;
+@@ -1470,11 +1460,7 @@ static int netlink_recvmsg(struct kiocb
+       }
+       siocb->scm->creds = *NETLINK_CREDS(skb);
+       if (flags & MSG_TRUNC)
+-              copied = skb->len;
+-
+-#ifdef CONFIG_COMPAT_NETLINK_MESSAGES
+-      skb_shinfo(skb)->frag_list = frag;
+-#endif
++              copied = data_skb->len;
+       skb_free_datagram(sk, skb);
index efb9893f2957a78b9a2a008856104ab0e8b0d6cf..97310cd346fe325220378cde15c7f94fe346ec4b 100644 (file)
@@ -80,3 +80,11 @@ drm-agp-i915-trim-stolen-space-to-32m.patch
 timekeeping-fix-overflow-in-rawtime-tv_nsec-on-32-bit-archs.patch
 time-workaround-gcc-loop-optimization-that-causes-64bit-div-errors.patch
 can-raw-fix-skb_orphan_try-handling.patch
+iwlagn-fix-rts-cts-protection.patch
+dm-separate-device-deletion-from-dm_put.patch
+e1000e-disable-aspm-l1-on-82573.patch
+e1000e-don-t-check-for-alternate-mac-addr-on-parts-that-don-t-support-it.patch
+iwlwifi-fix-3945-filter-flags.patch
+fixes-for-using-make-3.82.patch
+alsa-intel8x0-mute-external-amplifier-by-default-for-thinkpad-x31.patch
+netlink-fix-compat-recvmsg.patch