From: Greg Kroah-Hartman Date: Mon, 1 Apr 2013 21:21:54 +0000 (-0700) Subject: 3.0-stable patches X-Git-Tag: v3.8.6~46 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6f07a1805c7a75b103ee0e9c23b3b0dac339dfd9;p=thirdparty%2Fkernel%2Fstable-queue.git 3.0-stable patches added patches: b43-a-fix-for-dma-transmission-sequence-errors.patch --- diff --git a/queue-3.0/b43-a-fix-for-dma-transmission-sequence-errors.patch b/queue-3.0/b43-a-fix-for-dma-transmission-sequence-errors.patch new file mode 100644 index 00000000000..5f9f36415f1 --- /dev/null +++ b/queue-3.0/b43-a-fix-for-dma-transmission-sequence-errors.patch @@ -0,0 +1,155 @@ +From b251412db99ccd4495ce372fec7daee27bf06923 Mon Sep 17 00:00:00 2001 +From: "Iestyn C. Elfick" +Date: Wed, 20 Mar 2013 14:02:31 -0500 +Subject: b43: A fix for DMA transmission sequence errors + +From: "Iestyn C. Elfick" + +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 +Signed-off-by: Larry Finger +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -1390,8 +1390,12 @@ void b43_dma_handle_txstatus(struct b43_ + struct b43_dmaring *ring; + struct b43_dmadesc_generic *desc; + 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)) +@@ -1404,13 +1408,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; +@@ -1424,11 +1451,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 { +@@ -1440,8 +1469,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); +@@ -1452,9 +1482,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++; +@@ -1482,12 +1521,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); diff --git a/queue-3.0/series b/queue-3.0/series index 24f41db5d8b..74d461aef5e 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -5,3 +5,4 @@ bluetooth-add-support-for-dell_2.patch staging-comedi-s626-fix-continuous-acquisition.patch sysfs-fix-race-between-readdir-and-lseek.patch sysfs-handle-failure-path-correctly-for-readdir.patch +b43-a-fix-for-dma-transmission-sequence-errors.patch