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
_______________________________________________
b43-dev mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/b43-dev