public inbox for b43-dev@lists.infradead.org
 help / color / mirror / Atom feed
From: ISE Development <isedev@gmail.com>
To: Larry Finger <Larry.Finger@lwfinger.net>
Cc: b43-dev <b43-dev@lists.infradead.org>,
	linux-wireless <linux-wireless@vger.kernel.org>
Subject: BCM4312 / b43 DMA transmission sequence errors
Date: Thu, 14 Mar 2013 14:08:33 +0100	[thread overview]
Message-ID: <4530943.RJ7WpUJOSz@wks001.ise.net> (raw)
In-Reply-To: <51413800.6050300@lwfinger.net>

On Wednesday 13 Mar 2013 21:37:52 Larry Finger wrote:
> On 03/13/2013 08:06 PM, ISE Development wrote:
> 
> >
> > I've hacked the driver to 'skip' one header and data frame if receiving an interrupt for the first slot + 2. It's not pretty and I have literally no idea if it will causes other problems, but it has allowed me to keep the Wifi connection up for a little over 3 hours now (as compared to the 45 seconds previously). It does not appear to be corrupting the data stream (checked by download large signed binaries and verifying the signature) and as far as my limited knowledge can tell, it should not be causing a memory leak.
> >
> > The patch is listed below, for reference. However, I do not claim that it is valid, safe or even reasonsable. It does provide me with much needed relief though.
> >
> > The diff is against the current head of linville/wireless-testing.git (d41d9c7419e3ac9c81841f43bbd7639dd0a5819e).
> >
> 
> I am testing the patch on BCM4312 and other cards.
> 
> Larry
> 

Here's a slighted cleaner version, with comments, in case you are considering integrating it.

diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 38bc5a7..edc759d 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -1489,6 +1489,7 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
        struct b43_dmadesc_meta *meta;
        int slot, firstused;
        bool frame_succeed;
+       int skip;
 
        ring = parse_cookie(dev, status->cookie, &slot);
        if (unlikely(!ring))
@@ -1501,13 +1502,22 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
        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;
+               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;
+               } else {
+                       return;
+               }
        }
 
        ops = ring->ops;
@@ -1522,6 +1532,7 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
                               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));
@@ -1552,7 +1563,18 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
                         * Call back to inform the ieee80211 subsystem about
                         * the status of the transmission.
                         */
-                       frame_succeed = b43_fill_txstatus_report(dev, info, status);
+                       if(!skip)
+                       {
+                               frame_succeed = b43_fill_txstatus_report(dev, info, status);
+                       }
+                       else
+                       {
+                           /* When skipping over a missed TX status report, use a status
+                            * structure which indicates that the frame was not sent
+                            * (frame_count 0) and not acknowledged */
+                               struct b43_txstatus fake = B43_FAKE_TXSTATUS;
+                               frame_succeed = b43_fill_txstatus_report(dev, info, &fake);
+                       }
 #ifdef CONFIG_B43_DEBUG
                        if (frame_succeed)
                                ring->nr_succeed_tx_packets++;
@@ -1580,12 +1602,14 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
                /* 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/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h
index 98d9074..eae730c 100644
--- a/drivers/net/wireless/b43/xmit.h
+++ b/drivers/net/wireless/b43/xmit.h
@@ -218,6 +218,9 @@ struct b43_txstatus {
        u8 acked;               /* Wireless ACK received */
 };
 
+/* This needs to match the b43_txstatus structure above, all zeroed-out */
+#define B43_FAKE_TXSTATUS { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+
 /* txstatus supp_reason values */
 enum {
        B43_TXST_SUPP_NONE,     /* Not suppressed */


-- 
-- isedev

  reply	other threads:[~2013-03-14 13:08 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-13 22:31 BCM4312 / b43 DMA transmission sequence errors ISE Development
2013-03-14  0:22 ` Larry Finger
     [not found]   ` <1476129.oNtxuF3Ght@wks001.ise.net>
2013-03-14  2:37     ` Larry Finger
2013-03-14 13:08       ` ISE Development [this message]
2013-03-14 21:39         ` Chris Vine
2013-03-14 22:39           ` ISE Development

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=4530943.RJ7WpUJOSz@wks001.ise.net \
    --to=isedev@gmail.com \
    --cc=Larry.Finger@lwfinger.net \
    --cc=b43-dev@lists.infradead.org \
    --cc=linux-wireless@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox