--- /dev/null
+From b251412db99ccd4495ce372fec7daee27bf06923 Mon Sep 17 00:00:00 2001
+From: "Iestyn C. Elfick" <isedev@gmail.com>
+Date: Wed, 20 Mar 2013 14:02:31 -0500
+Subject: b43: A fix for DMA transmission sequence errors
+
+From: "Iestyn C. Elfick" <isedev@gmail.com>
+
+commit b251412db99ccd4495ce372fec7daee27bf06923 upstream.
+
+Intermittently, b43 will report "Out of order TX status report on DMA ring".
+When this happens, the driver must be reset before communication can resume.
+The cause of the problem is believed to be an error in the closed-source
+firmware; however, all versions of the firmware are affected.
+
+This change uses the observation that the expected status is always 2 less
+than the observed value, and supplies a fake status report to skip one
+header/data pair.
+
+Not all devices suffer from this problem, but it can occur several times
+per second under heavy load. As each occurence kills the unmodified driver,
+this patch makes if possible for the affected devices to function. The patch
+logs only the first instance of the reset operation to prevent spamming
+the logs.
+
+Tested-by: Chris Vine <chris@cvine.freeserve.co.uk>
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/b43/dma.c | 65 +++++++++++++++++++++++++++++++++--------
+ 1 file changed, 53 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/wireless/b43/dma.c
++++ b/drivers/net/wireless/b43/dma.c
+@@ -1487,8 +1487,12 @@ void b43_dma_handle_txstatus(struct b43_
+ const struct b43_dma_ops *ops;
+ struct b43_dmaring *ring;
+ struct b43_dmadesc_meta *meta;
++ static const struct b43_txstatus fake; /* filled with 0 */
++ const struct b43_txstatus *txstat;
+ int slot, firstused;
+ bool frame_succeed;
++ int skip;
++ static u8 err_out1, err_out2;
+
+ ring = parse_cookie(dev, status->cookie, &slot);
+ if (unlikely(!ring))
+@@ -1501,13 +1505,36 @@ void b43_dma_handle_txstatus(struct b43_
+ firstused = ring->current_slot - ring->used_slots + 1;
+ if (firstused < 0)
+ firstused = ring->nr_slots + firstused;
++
++ skip = 0;
+ if (unlikely(slot != firstused)) {
+ /* This possibly is a firmware bug and will result in
+- * malfunction, memory leaks and/or stall of DMA functionality. */
+- b43dbg(dev->wl, "Out of order TX status report on DMA ring %d. "
+- "Expected %d, but got %d\n",
+- ring->index, firstused, slot);
+- return;
++ * malfunction, memory leaks and/or stall of DMA functionality.
++ */
++ if (slot == next_slot(ring, next_slot(ring, firstused))) {
++ /* If a single header/data pair was missed, skip over
++ * the first two slots in an attempt to recover.
++ */
++ slot = firstused;
++ skip = 2;
++ if (!err_out1) {
++ /* Report the error once. */
++ b43dbg(dev->wl,
++ "Skip on DMA ring %d slot %d.\n",
++ ring->index, slot);
++ err_out1 = 1;
++ }
++ } else {
++ /* More than a single header/data pair were missed.
++ * Report this error once.
++ */
++ if (!err_out2)
++ b43dbg(dev->wl,
++ "Out of order TX status report on DMA ring %d. Expected %d, but got %d\n",
++ ring->index, firstused, slot);
++ err_out2 = 1;
++ return;
++ }
+ }
+
+ ops = ring->ops;
+@@ -1522,11 +1549,13 @@ void b43_dma_handle_txstatus(struct b43_
+ slot, firstused, ring->index);
+ break;
+ }
++
+ if (meta->skb) {
+ struct b43_private_tx_info *priv_info =
+- b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb));
++ b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb));
+
+- unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1);
++ unmap_descbuffer(ring, meta->dmaaddr,
++ meta->skb->len, 1);
+ kfree(priv_info->bouncebuffer);
+ priv_info->bouncebuffer = NULL;
+ } else {
+@@ -1538,8 +1567,9 @@ void b43_dma_handle_txstatus(struct b43_
+ struct ieee80211_tx_info *info;
+
+ if (unlikely(!meta->skb)) {
+- /* This is a scatter-gather fragment of a frame, so
+- * the skb pointer must not be NULL. */
++ /* This is a scatter-gather fragment of a frame,
++ * so the skb pointer must not be NULL.
++ */
+ b43dbg(dev->wl, "TX status unexpected NULL skb "
+ "at slot %d (first=%d) on ring %d\n",
+ slot, firstused, ring->index);
+@@ -1550,9 +1580,18 @@ void b43_dma_handle_txstatus(struct b43_
+
+ /*
+ * Call back to inform the ieee80211 subsystem about
+- * the status of the transmission.
++ * the status of the transmission. When skipping over
++ * a missed TX status report, use a status structure
++ * filled with zeros to indicate that the frame was not
++ * sent (frame_count 0) and not acknowledged
+ */
+- frame_succeed = b43_fill_txstatus_report(dev, info, status);
++ if (unlikely(skip))
++ txstat = &fake;
++ else
++ txstat = status;
++
++ frame_succeed = b43_fill_txstatus_report(dev, info,
++ txstat);
+ #ifdef CONFIG_B43_DEBUG
+ if (frame_succeed)
+ ring->nr_succeed_tx_packets++;
+@@ -1580,12 +1619,14 @@ void b43_dma_handle_txstatus(struct b43_
+ /* Everything unmapped and free'd. So it's not used anymore. */
+ ring->used_slots--;
+
+- if (meta->is_last_fragment) {
++ if (meta->is_last_fragment && !skip) {
+ /* This is the last scatter-gather
+ * fragment of the frame. We are done. */
+ break;
+ }
+ slot = next_slot(ring, slot);
++ if (skip > 0)
++ --skip;
+ }
+ if (ring->stopped) {
+ B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME);
--- /dev/null
+From e67dd874e60529dbd2e8232babb1e23479ba2ffa Mon Sep 17 00:00:00 2001
+From: Rafał Miłecki <zajec5@gmail.com>
+Date: Tue, 19 Mar 2013 07:52:48 +0100
+Subject: b43: N-PHY: increase initial value of "mind" in RSSI calibration
+
+From: Rafał Miłecki <zajec5@gmail.com>
+
+commit e67dd874e60529dbd2e8232babb1e23479ba2ffa upstream.
+
+We're using "mind" variable to find the VCM that got the best polling
+results. For each VCM we calculte "currd" which is compared to the
+"mind". For PHY rev3+ "currd" gets values around 14k-40k. Looking for a
+value smaller than 40 makes no sense, so increase the initial value.
+
+This fixes a regression introduced in 3.4 by commit:
+e0c9a0219a8f542e3946fe972a68aacf8c3f906c
+(my BCM4322 performance dropped from 18,4Mb/s to 9,26Mb/s)
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/b43/phy_n.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/b43/phy_n.c
++++ b/drivers/net/wireless/b43/phy_n.c
+@@ -1615,7 +1615,7 @@ static void b43_nphy_rev3_rssi_cal(struc
+ }
+ for (i = 0; i < 4; i += 2) {
+ s32 curr;
+- s32 mind = 40;
++ s32 mind = 0x100000;
+ s32 minpoll = 249;
+ u8 minvcm = 0;
+ if (2 * core != i)
+@@ -1799,7 +1799,7 @@ static void b43_nphy_rev2_rssi_cal(struc
+ }
+
+ for (i = 0; i < 4; i++) {
+- s32 mind = 40;
++ s32 mind = 0x100000;
+ u8 minvcm = 0;
+ s32 minpoll = 249;
+ s32 curr;
--- /dev/null
+From 2e1253d640eb7f8707d2591c93097c1e9f9c71d5 Mon Sep 17 00:00:00 2001
+From: Rafał Miłecki <zajec5@gmail.com>
+Date: Wed, 27 Mar 2013 08:37:08 +0100
+Subject: b43: N-PHY: use more bits for offset in RSSI calibration
+
+From: Rafał Miłecki <zajec5@gmail.com>
+
+commit 2e1253d640eb7f8707d2591c93097c1e9f9c71d5 upstream.
+
+When calculating "offset" for final RSSI calibration we're using numbers
+bigger than s8 can hold. We have for example:
+offset[j] = 232 - poll_results[j];
+formula. If poll_results[j] is small enough (it usually is) we treat
+number's bit as a sign bit. For example 232 - 1 becomes:
+0xE8 - 0x1 = 0xE7, which is not 231 but -25.
+
+This code was introduced in e0c9a0219a8f542e3946fe972a68aacf8c3f906c
+and caused stability regression on some cards, for ex. BCM4322.
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+
+---
+ drivers/net/wireless/b43/phy_n.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/b43/phy_n.c
++++ b/drivers/net/wireless/b43/phy_n.c
+@@ -1564,7 +1564,7 @@ static void b43_nphy_rev3_rssi_cal(struc
+ u16 clip_off[2] = { 0xFFFF, 0xFFFF };
+
+ u8 vcm_final = 0;
+- s8 offset[4];
++ s32 offset[4];
+ s32 results[8][4] = { };
+ s32 results_min[4] = { };
+ s32 poll_results[4] = { };
+@@ -1732,7 +1732,7 @@ static void b43_nphy_rev2_rssi_cal(struc
+ u8 regs_save_radio[2];
+ u16 regs_save_phy[2];
+
+- s8 offset[4];
++ s32 offset[4];
+ u8 core;
+ u8 rail;
+
--- /dev/null
+From c2a2876e863356b092967ea62bebdb4dd663af80 Mon Sep 17 00:00:00 2001
+From: Joerg Roedel <joro@8bytes.org>
+Date: Tue, 26 Mar 2013 22:48:23 +0100
+Subject: iommu/amd: Make sure dma_ops are set for hotplug devices
+
+From: Joerg Roedel <joro@8bytes.org>
+
+commit c2a2876e863356b092967ea62bebdb4dd663af80 upstream.
+
+There is a bug introduced with commit 27c2127 that causes
+devices which are hot unplugged and then hot-replugged to
+not have per-device dma_ops set. This causes these devices
+to not function correctly. Fixed with this patch.
+
+Reported-by: Andreas Degert <andreas.degert@googlemail.com>
+Signed-off-by: Joerg Roedel <joro@8bytes.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/amd_iommu.c | 20 +++++++++-----------
+ 1 file changed, 9 insertions(+), 11 deletions(-)
+
+--- a/drivers/iommu/amd_iommu.c
++++ b/drivers/iommu/amd_iommu.c
+@@ -2466,18 +2466,16 @@ static int device_change_notifier(struct
+
+ /* allocate a protection domain if a device is added */
+ dma_domain = find_protection_domain(devid);
+- if (dma_domain)
+- goto out;
+- dma_domain = dma_ops_domain_alloc();
+- if (!dma_domain)
+- goto out;
+- dma_domain->target_dev = devid;
++ if (!dma_domain) {
++ dma_domain = dma_ops_domain_alloc();
++ if (!dma_domain)
++ goto out;
++ dma_domain->target_dev = devid;
+
+- spin_lock_irqsave(&iommu_pd_list_lock, flags);
+- list_add_tail(&dma_domain->list, &iommu_pd_list);
+- spin_unlock_irqrestore(&iommu_pd_list_lock, flags);
+-
+- dev_data = get_dev_data(dev);
++ spin_lock_irqsave(&iommu_pd_list_lock, flags);
++ list_add_tail(&dma_domain->list, &iommu_pd_list);
++ spin_unlock_irqrestore(&iommu_pd_list_lock, flags);
++ }
+
+ dev->archdata.dma_ops = &amd_iommu_dma_ops;
+
--- /dev/null
+From cc904c7188c29847817f35e6966fec3014c7479b Mon Sep 17 00:00:00 2001
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Date: Thu, 14 Mar 2013 08:35:06 +0200
+Subject: iwlwifi: fix length check in multi-TB HCMD
+
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+
+commit cc904c7188c29847817f35e6966fec3014c7479b upstream.
+
+As reported by Ben Hutchings, there was a harmless issue in
+the checks being done on the lengths of the TBs while
+building the TFD for a multi-TB host command.
+
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/iwlwifi/pcie/tx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
++++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
+@@ -1242,7 +1242,7 @@ static int iwl_pcie_enqueue_hcmd(struct
+ for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
+ int copy = 0;
+
+- if (!cmd->len)
++ if (!cmd->len[i])
+ continue;
+
+ /* need at least IWL_HCMD_MIN_COPY_SIZE copied */
--- /dev/null
+From 27a737ff7cb062fb9cbceba9b44d60aa74862bfa Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Wed, 6 Mar 2013 23:17:08 +0100
+Subject: mac80211: always synchronize_net() during station removal
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 27a737ff7cb062fb9cbceba9b44d60aa74862bfa upstream.
+
+If there are keys left during station removal, then a
+synchronize_net() will be done (for each key, I have a
+patch to address this for 3.10), otherwise it won't be
+done at all which causes issues because the station
+could be used for TX while it's being removed from the
+driver -- that might confuse the driver.
+
+Fix this by always doing synchronize_net() if no key
+was present any more.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/mac80211/sta_info.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -756,6 +756,7 @@ int __must_check __sta_info_destroy(stru
+ struct ieee80211_local *local;
+ struct ieee80211_sub_if_data *sdata;
+ int ret, i;
++ bool have_key = false;
+
+ might_sleep();
+
+@@ -783,12 +784,19 @@ int __must_check __sta_info_destroy(stru
+ list_del_rcu(&sta->list);
+
+ mutex_lock(&local->key_mtx);
+- for (i = 0; i < NUM_DEFAULT_KEYS; i++)
++ for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
+ __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i]));
+- if (sta->ptk)
++ have_key = true;
++ }
++ if (sta->ptk) {
+ __ieee80211_key_free(key_mtx_dereference(local, sta->ptk));
++ have_key = true;
++ }
+ mutex_unlock(&local->key_mtx);
+
++ if (!have_key)
++ synchronize_net();
++
+ sta->dead = true;
+
+ local->num_sta--;
hid-usbhid-quirk-for-msi-gx680r-led-panel.patch
hid-usbhid-fix-build-problem.patch
rtlwifi-usb-add-missing-freeing-of-skbuff.patch
+iwlwifi-fix-length-check-in-multi-tb-hcmd.patch
+b43-n-phy-increase-initial-value-of-mind-in-rssi-calibration.patch
+b43-a-fix-for-dma-transmission-sequence-errors.patch
+b43-n-phy-use-more-bits-for-offset-in-rssi-calibration.patch
+tg3-fix-length-overflow-in-vpd-firmware-parsing.patch
+mac80211-always-synchronize_net-during-station-removal.patch
+iommu-amd-make-sure-dma_ops-are-set-for-hotplug-devices.patch
--- /dev/null
+From 715230a44310a8cf66fbfb5a46f9a62a9b2de424 Mon Sep 17 00:00:00 2001
+From: Kees Cook <keescook@chromium.org>
+Date: Wed, 27 Mar 2013 06:40:50 +0000
+Subject: tg3: fix length overflow in VPD firmware parsing
+
+From: Kees Cook <keescook@chromium.org>
+
+commit 715230a44310a8cf66fbfb5a46f9a62a9b2de424 upstream.
+
+Commit 184b89044fb6e2a74611dafa69b1dce0d98612c6 ("tg3: Use VPD fw version
+when present") introduced VPD parsing that contained a potential length
+overflow.
+
+Limit the hardware's reported firmware string length (max 255 bytes) to
+stay inside the driver's firmware string length (32 bytes). On overflow,
+truncate the formatted firmware string instead of potentially overwriting
+portions of the tg3 struct.
+
+http://cansecwest.com/slides/2013/PrivateCore%20CSW%202013.pdf
+
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Reported-by: Oded Horovitz <oded@privatecore.com>
+Reported-by: Brad Spengler <spender@grsecurity.net>
+Cc: Matt Carlson <mcarlson@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/broadcom/tg3.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/broadcom/tg3.c
++++ b/drivers/net/ethernet/broadcom/tg3.c
+@@ -14403,8 +14403,11 @@ static void tg3_read_vpd(struct tg3 *tp)
+ if (j + len > block_end)
+ goto partno;
+
+- memcpy(tp->fw_ver, &vpd_data[j], len);
+- strncat(tp->fw_ver, " bc ", vpdlen - len - 1);
++ if (len >= sizeof(tp->fw_ver))
++ len = sizeof(tp->fw_ver) - 1;
++ memset(tp->fw_ver, 0, sizeof(tp->fw_ver));
++ snprintf(tp->fw_ver, sizeof(tp->fw_ver), "%.*s bc ", len,
++ &vpd_data[j]);
+ }
+
+ partno: