From: Larry Finger <Larry.Finger@lwfinger.net>
To: Michael Buesch <mb@bu3sch.de>, zajec5@gmail.com
Cc: isedev@gmail.com, b43-dev@lists.infradead.org,
linux-wireless@vger.kernel.org
Subject: [RFC/RFT] b43: A fix for DMA transmission sequence errors
Date: Thu, 14 Mar 2013 13:46:19 -0500 [thread overview]
Message-ID: <51421afb.xUa3KbaBuvmUk4RG%Larry.Finger@lwfinger.net> (raw)
From: Iestyn C. Elfick <isedev@gmail.com>
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.
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Stable <stable@vger.kernel.org>
---
Although this is a hack, it seems to work for the OP. It should not cause any
ill effects on any device that does not have the problem.
It does need a lot more testing, particularly on systems prone to the out-of-order
status report problem.
If anyone can think of a cleaner, less intrusive solution, please let us know.
Thanks,
Larry
---
Index: wireless-testing-rebased/drivers/net/wireless/b43/dma.c
===================================================================
--- wireless-testing-rebased.orig/drivers/net/wireless/b43/dma.c
+++ wireless-testing-rebased/drivers/net/wireless/b43/dma.c
@@ -1487,8 +1487,11 @@ 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;
ring = parse_cookie(dev, status->cookie, &slot);
if (unlikely(!ring))
@@ -1501,13 +1504,26 @@ 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. */
+ * 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;
+ if (slot == firstused + 2) {
+ /* If a single header/data pair was missed, skip over
+ * the first two slots in an attempt to recover.
+ */
+ slot = firstused;
+ skip = 2;
+ b43dbg(dev->wl, "Skip on DMA ring %d slot %d.\n",
+ ring->index, slot);
+ } else {
+ return;
+ }
}
ops = ring->ops;
@@ -1522,11 +1538,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 +1556,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 +1569,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 = status;
+ else
+ txstat = &fake;
+
+ frame_succeed = b43_fill_txstatus_report(dev, info,
+ txstat);
#ifdef CONFIG_B43_DEBUG
if (frame_succeed)
ring->nr_succeed_tx_packets++;
@@ -1580,12 +1608,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);
next reply other threads:[~2013-03-14 18:46 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-14 18:46 Larry Finger [this message]
2013-03-14 18:55 ` [RFC/RFT] b43: A fix for DMA transmission sequence errors Michael Büsch
2013-03-14 18:55 ` Michael Büsch
2013-03-14 20:17 ` Rafał Miłecki
2013-03-14 20:17 ` Rafał Miłecki
2013-03-15 6:37 ` Rafał Miłecki
2013-03-15 6:37 ` Rafał Miłecki
2013-03-15 16:48 ` Larry Finger
2013-03-15 16:48 ` Larry Finger
2013-03-20 11:26 ` ISE Development
2013-03-20 11:26 ` ISE Development
2013-03-20 13:43 ` Chris Vine
2013-03-20 13:43 ` Chris Vine
2013-03-20 14:53 ` Larry Finger
2013-03-20 14:53 ` Larry Finger
2013-03-20 15:04 ` ISE Development
2013-03-20 15:04 ` ISE Development
2013-03-20 16:10 ` Chris Vine
2013-03-20 16:10 ` Chris Vine
2013-03-15 0:09 ` ISE Development
2013-03-15 0:09 ` ISE Development
2013-03-15 2:07 ` Larry Finger
2013-03-15 2:07 ` Larry Finger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=51421afb.xUa3KbaBuvmUk4RG%Larry.Finger@lwfinger.net \
--to=larry.finger@lwfinger.net \
--cc=b43-dev@lists.infradead.org \
--cc=isedev@gmail.com \
--cc=linux-wireless@vger.kernel.org \
--cc=mb@bu3sch.de \
--cc=zajec5@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.