--- /dev/null
+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
--- /dev/null
+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);
+
--- /dev/null
+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,
--- /dev/null
+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) {
--- /dev/null
+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
--- /dev/null
+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)) {
--- /dev/null
+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,
--- /dev/null
+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);
+
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