rpms/kernel/F-12 b43_-Allow-PIO-mode-to-be-selected-at-module-load.patch, NONE, 1.1 b43_-Optimize-PIO-scratchbuffer-usage.patch, NONE, 1.1 b43_-Remove-reset-after-fatal-DMA-error.patch, NONE, 1.1 b43_-fall-back-gracefully-to-PIO-mode-after-fatal-DMA-errors.patch, NONE, 1.1 kernel.spec, 1.2063, 1.2064

John W. Linville linville at fedoraproject.org
Fri Apr 16 14:55:00 UTC 2010


Author: linville

Update of /cvs/pkgs/rpms/kernel/F-12
In directory cvs01.phx2.fedoraproject.org:/tmp/cvs-serv24288

Modified Files:
	kernel.spec 
Added Files:
	b43_-Allow-PIO-mode-to-be-selected-at-module-load.patch 
	b43_-Optimize-PIO-scratchbuffer-usage.patch 
	b43_-Remove-reset-after-fatal-DMA-error.patch 
	b43_-fall-back-gracefully-to-PIO-mode-after-fatal-DMA-errors.patch 
Log Message:
make b43 gracefully switch to PIO mode in event of DMA errors

b43_-Allow-PIO-mode-to-be-selected-at-module-load.patch:
 Kconfig  |   19 ++-----------------
 Makefile |    2 +-
 b43.h    |   13 -------------
 dma.c    |    2 --
 main.c   |    9 ++++++---
 pio.h    |   40 ----------------------------------------
 6 files changed, 9 insertions(+), 76 deletions(-)

--- NEW FILE b43_-Allow-PIO-mode-to-be-selected-at-module-load.patch ---
Back-port of the following upstream commit...

commit b02914af4d7020828ce921a572589dd793517c09
Author: Larry Finger <Larry.Finger at lwfinger.net>
Date:   Thu Dec 10 17:35:01 2009 -0600

    b43: Allow PIO mode to be selected at module load
    
    If userencounter the "Fatal DMA Problem" with a BCM43XX device, and
    still wish to use b43 as the driver, their only option is to rebuild
    the kernel with CONFIG_B43_FORCE_PIO. This patch removes this option and
    allows PIO mode to be selected with a load-time parameter for the module.
    Note that the configuration variable CONFIG_B43_PIO is also removed.
    
    Once the DMA problem with the BCM4312 devices is solved, this patch will
    likely be reverted.
    
    Signed-off-by: Larry Finger <Larry.Finger at lwfinger.net>
    Tested-by: John Daiker <daikerjohn at gmail.com>
    Signed-off-by: John W. Linville <linville at tuxdriver.com>

diff -up linux-2.6.32.noarch/drivers/net/wireless/b43/b43.h.orig linux-2.6.32.noarch/drivers/net/wireless/b43/b43.h
--- linux-2.6.32.noarch/drivers/net/wireless/b43/b43.h.orig	2010-04-12 13:37:58.000000000 -0400
+++ linux-2.6.32.noarch/drivers/net/wireless/b43/b43.h	2010-04-12 13:38:24.000000000 -0400
@@ -824,11 +824,9 @@ struct b43_wl {
 	/* The device LEDs. */
 	struct b43_leds leds;
 
-#ifdef CONFIG_B43_PIO
 	/* Kmalloc'ed scratch space for PIO TX/RX. Protected by wl->mutex. */
 	u8 pio_scratchspace[110] __attribute__((__aligned__(8)));
 	u8 pio_tailspace[4] __attribute__((__aligned__(8)));
-#endif /* CONFIG_B43_PIO */
 };
 
 static inline struct b43_wl *hw_to_b43_wl(struct ieee80211_hw *hw)
@@ -879,20 +877,9 @@ static inline void b43_write32(struct b4
 
 static inline bool b43_using_pio_transfers(struct b43_wldev *dev)
 {
-#ifdef CONFIG_B43_PIO
 	return dev->__using_pio_transfers;
-#else
-	return 0;
-#endif
 }
 
-#ifdef CONFIG_B43_FORCE_PIO
-# define B43_FORCE_PIO	1
-#else
-# define B43_FORCE_PIO	0
-#endif
-
-
 /* Message printing */
 void b43info(struct b43_wl *wl, const char *fmt, ...)
     __attribute__ ((format(printf, 2, 3)));
diff -up linux-2.6.32.noarch/drivers/net/wireless/b43/dma.c.orig linux-2.6.32.noarch/drivers/net/wireless/b43/dma.c
--- linux-2.6.32.noarch/drivers/net/wireless/b43/dma.c.orig	2010-04-12 13:37:58.000000000 -0400
+++ linux-2.6.32.noarch/drivers/net/wireless/b43/dma.c	2010-04-12 13:38:24.000000000 -0400
@@ -1661,7 +1661,6 @@ void b43_dma_tx_resume(struct b43_wldev 
 	b43_power_saving_ctl_bits(dev, 0);
 }
 
-#ifdef CONFIG_B43_PIO
 static void direct_fifo_rx(struct b43_wldev *dev, enum b43_dmatype type,
 			   u16 mmio_base, bool enable)
 {
@@ -1695,4 +1694,3 @@ void b43_dma_direct_fifo_rx(struct b43_w
 	mmio_base = b43_dmacontroller_base(type, engine_index);
 	direct_fifo_rx(dev, type, mmio_base, enable);
 }
-#endif /* CONFIG_B43_PIO */
diff -up linux-2.6.32.noarch/drivers/net/wireless/b43/Kconfig.orig linux-2.6.32.noarch/drivers/net/wireless/b43/Kconfig
--- linux-2.6.32.noarch/drivers/net/wireless/b43/Kconfig.orig	2009-12-02 22:51:21.000000000 -0500
+++ linux-2.6.32.noarch/drivers/net/wireless/b43/Kconfig	2010-04-12 13:38:24.000000000 -0400
@@ -3,6 +3,7 @@ config B43
 	depends on SSB_POSSIBLE && MAC80211 && WLAN_80211 && HAS_DMA
 	select SSB
 	select FW_LOADER
+	select SSB_BLOCKIO
 	---help---
 	  b43 is a driver for the Broadcom 43xx series wireless devices.
 
@@ -78,14 +79,6 @@ config B43_SDIO
 
 	  If unsure, say N.
 
-# Data transfers to the device via PIO
-# This is only needed on PCMCIA and SDIO devices. All others can do DMA properly.
-config B43_PIO
-	bool
-	depends on B43 && (B43_SDIO || B43_PCMCIA || B43_FORCE_PIO)
-	select SSB_BLOCKIO
-	default y
-
 config B43_NPHY
 	bool "Pre IEEE 802.11n support (BROKEN)"
 	depends on B43 && EXPERIMENTAL && BROKEN
@@ -137,12 +130,4 @@ config B43_DEBUG
 	  for production use.
 	  Only say Y, if you are debugging a problem in the b43 driver sourcecode.
 
-config B43_FORCE_PIO
-	bool "Force usage of PIO instead of DMA"
-	depends on B43 && B43_DEBUG
-	---help---
-	  This will disable DMA and always enable PIO instead.
-
-	  Say N!
-	  This is only for debugging the PIO engine code. You do
-	  _NOT_ want to enable this.
+
diff -up linux-2.6.32.noarch/drivers/net/wireless/b43/main.c.orig linux-2.6.32.noarch/drivers/net/wireless/b43/main.c
--- linux-2.6.32.noarch/drivers/net/wireless/b43/main.c.orig	2010-04-12 13:37:58.000000000 -0400
+++ linux-2.6.32.noarch/drivers/net/wireless/b43/main.c	2010-04-12 13:38:24.000000000 -0400
@@ -102,6 +102,9 @@ int b43_modparam_verbose = B43_VERBOSITY
 module_param_named(verbose, b43_modparam_verbose, int, 0644);
 MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug");
 
+static int modparam_pio;
+module_param_named(pio, modparam_pio, int, 0444);
+MODULE_PARM_DESC(pio, "enable(1) / disable(0) PIO mode");
 
 static const struct ssb_device_id b43_ssb_tbl[] = {
 	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5),
@@ -1790,8 +1793,8 @@ static void b43_do_interrupt_thread(stru
 			       dma_reason[4], dma_reason[5]);
 			b43err(dev->wl, "This device does not support DMA "
 			       "on your system. Please use PIO instead.\n");
-			b43err(dev->wl, "CONFIG_B43_FORCE_PIO must be set in "
-			       "your kernel configuration.\n");
+			b43err(dev->wl, "Unload the b43 module and reload "
+			       "with 'pio=1'\n");
 			return;
 		}
 		if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) {
@@ -4358,7 +4361,7 @@ static int b43_wireless_core_init(struct
 
 	if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) ||
 	    (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) ||
-	    B43_FORCE_PIO) {
+	    modparam_pio) {
 		dev->__using_pio_transfers = 1;
 		err = b43_pio_init(dev);
 	} else {
diff -up linux-2.6.32.noarch/drivers/net/wireless/b43/Makefile.orig linux-2.6.32.noarch/drivers/net/wireless/b43/Makefile
--- linux-2.6.32.noarch/drivers/net/wireless/b43/Makefile.orig	2009-12-02 22:51:21.000000000 -0500
+++ linux-2.6.32.noarch/drivers/net/wireless/b43/Makefile	2010-04-12 13:38:24.000000000 -0400
@@ -12,7 +12,7 @@ b43-y				+= xmit.o
 b43-y				+= lo.o
 b43-y				+= wa.o
 b43-y				+= dma.o
-b43-$(CONFIG_B43_PIO)		+= pio.o
+b43-y				+= pio.o
 b43-y				+= rfkill.o
 b43-$(CONFIG_B43_LEDS)		+= leds.o
 b43-$(CONFIG_B43_PCMCIA)	+= pcmcia.o
diff -up linux-2.6.32.noarch/drivers/net/wireless/b43/pio.h.orig linux-2.6.32.noarch/drivers/net/wireless/b43/pio.h
--- linux-2.6.32.noarch/drivers/net/wireless/b43/pio.h.orig	2009-12-02 22:51:21.000000000 -0500
+++ linux-2.6.32.noarch/drivers/net/wireless/b43/pio.h	2010-04-12 13:38:24.000000000 -0400
@@ -55,8 +55,6 @@
 #define B43_PIO_MAX_NR_TXPACKETS	32
 
 
-#ifdef CONFIG_B43_PIO
-
 struct b43_pio_txpacket {
 	/* Pointer to the TX queue we belong to. */
 	struct b43_pio_txqueue *queue;
@@ -169,42 +167,4 @@ void b43_pio_rx(struct b43_pio_rxqueue *
 void b43_pio_tx_suspend(struct b43_wldev *dev);
 void b43_pio_tx_resume(struct b43_wldev *dev);
 
-
-#else /* CONFIG_B43_PIO */
-
-
-static inline int b43_pio_init(struct b43_wldev *dev)
-{
-	return 0;
-}
-static inline void b43_pio_free(struct b43_wldev *dev)
-{
-}
-static inline void b43_pio_stop(struct b43_wldev *dev)
-{
-}
-static inline int b43_pio_tx(struct b43_wldev *dev,
-			     struct sk_buff *skb)
-{
-	return 0;
-}
-static inline void b43_pio_handle_txstatus(struct b43_wldev *dev,
-					   const struct b43_txstatus *status)
-{
-}
-static inline void b43_pio_get_tx_stats(struct b43_wldev *dev,
-					struct ieee80211_tx_queue_stats *stats)
-{
-}
-static inline void b43_pio_rx(struct b43_pio_rxqueue *q)
-{
-}
-static inline void b43_pio_tx_suspend(struct b43_wldev *dev)
-{
-}
-static inline void b43_pio_tx_resume(struct b43_wldev *dev)
-{
-}
-
-#endif /* CONFIG_B43_PIO */
 #endif /* B43_PIO_H_ */

b43_-Optimize-PIO-scratchbuffer-usage.patch:
 b43.h  |   16 ++-----------
 pio.c  |   79 ++++++++++++++++++++++++++++++++++++++---------------------------
 xmit.c |    2 -
 3 files changed, 51 insertions(+), 46 deletions(-)

--- NEW FILE b43_-Optimize-PIO-scratchbuffer-usage.patch ---
commit 88499ab3d8dbbf9c080416952603742666c71262
Author: Michael Buesch <mb at bu3sch.de>
Date:   Fri Oct 9 20:33:32 2009 +0200

    b43: Optimize PIO scratchbuffer usage
    
    This optimizes the PIO scratchbuffer usage.
    
    Signed-off-by: Michael Buesch <mb at bu3sch.de>
    Signed-off-by: John W. Linville <linville at tuxdriver.com>

diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 6607162..65b23f7 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -749,12 +749,6 @@ struct b43_wldev {
 #endif
 };
 
-/*
- * Include goes here to avoid a dependency problem.
- * A better fix would be to integrate xmit.h into b43.h.
- */
-#include "xmit.h"
-
 /* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */
 struct b43_wl {
 	/* Pointer to the active wireless device on this chip */
@@ -830,13 +824,9 @@ struct b43_wl {
 	struct b43_leds leds;
 
 #ifdef CONFIG_B43_PIO
-	/*
-	 * RX/TX header/tail buffers used by the frame transmit functions.
-	 */
-	struct b43_rxhdr_fw4 rxhdr;
-	struct b43_txhdr txhdr;
-	u8 rx_tail[4];
-	u8 tx_tail[4];
+	/* Kmalloc'ed scratch space for PIO TX/RX. Protected by wl->mutex. */
+	u8 pio_scratchspace[110] __attribute__((__aligned__(8)));
+	u8 pio_tailspace[4] __attribute__((__aligned__(8)));
 #endif /* CONFIG_B43_PIO */
 };
 
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index dbbf0d1..3105f23 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -341,12 +341,15 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q,
 			q->mmio_base + B43_PIO_TXDATA,
 			sizeof(u16));
 	if (data_len & 1) {
+		u8 *tail = wl->pio_tailspace;
+		BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 2);
+
 		/* Write the last byte. */
 		ctl &= ~B43_PIO_TXCTL_WRITEHI;
 		b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
-		wl->tx_tail[0] = data[data_len - 1];
-		wl->tx_tail[1] = 0;
-		ssb_block_write(dev->dev, wl->tx_tail, 2,
+		tail[0] = data[data_len - 1];
+		tail[1] = 0;
+		ssb_block_write(dev->dev, tail, 2,
 				q->mmio_base + B43_PIO_TXDATA,
 				sizeof(u16));
 	}
@@ -392,31 +395,31 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q,
 			q->mmio_base + B43_PIO8_TXDATA,
 			sizeof(u32));
 	if (data_len & 3) {
-		wl->tx_tail[3] = 0;
+		u8 *tail = wl->pio_tailspace;
+		BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 4);
+
+		memset(tail, 0, 4);
 		/* Write the last few bytes. */
 		ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 |
 			 B43_PIO8_TXCTL_24_31);
 		switch (data_len & 3) {
 		case 3:
 			ctl |= B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_8_15;
-			wl->tx_tail[0] = data[data_len - 3];
-			wl->tx_tail[1] = data[data_len - 2];
-			wl->tx_tail[2] = data[data_len - 1];
+			tail[0] = data[data_len - 3];
+			tail[1] = data[data_len - 2];
+			tail[2] = data[data_len - 1];
 			break;
 		case 2:
 			ctl |= B43_PIO8_TXCTL_8_15;
-			wl->tx_tail[0] = data[data_len - 2];
-			wl->tx_tail[1] = data[data_len - 1];
-			wl->tx_tail[2] = 0;
+			tail[0] = data[data_len - 2];
+			tail[1] = data[data_len - 1];
 			break;
 		case 1:
-			wl->tx_tail[0] = data[data_len - 1];
-			wl->tx_tail[1] = 0;
-			wl->tx_tail[2] = 0;
+			tail[0] = data[data_len - 1];
 			break;
 		}
 		b43_piotx_write32(q, B43_PIO8_TXCTL, ctl);
-		ssb_block_write(dev->dev, wl->tx_tail, 4,
+		ssb_block_write(dev->dev, tail, 4,
 				q->mmio_base + B43_PIO8_TXDATA,
 				sizeof(u32));
 	}
@@ -455,6 +458,7 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
 	int err;
 	unsigned int hdrlen;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct b43_txhdr *txhdr = (struct b43_txhdr *)wl->pio_scratchspace;
 
 	B43_WARN_ON(list_empty(&q->packets_list));
 	pack = list_entry(q->packets_list.next,
@@ -462,7 +466,9 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
 
 	cookie = generate_cookie(q, pack);
 	hdrlen = b43_txhdr_size(dev);
-	err = b43_generate_txhdr(dev, (u8 *)&wl->txhdr, skb,
+	BUILD_BUG_ON(sizeof(wl->pio_scratchspace) < sizeof(struct b43_txhdr));
+	B43_WARN_ON(sizeof(wl->pio_scratchspace) < hdrlen);
+	err = b43_generate_txhdr(dev, (u8 *)txhdr, skb,
 				 info, cookie);
 	if (err)
 		return err;
@@ -476,9 +482,9 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
 
 	pack->skb = skb;
 	if (q->rev >= 8)
-		pio_tx_frame_4byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen);
+		pio_tx_frame_4byte_queue(pack, (const u8 *)txhdr, hdrlen);
 	else
-		pio_tx_frame_2byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen);
+		pio_tx_frame_2byte_queue(pack, (const u8 *)txhdr, hdrlen);
 
 	/* Remove it from the list of available packet slots.
 	 * It will be put back when we receive the status report. */
@@ -624,8 +630,11 @@ static bool pio_rx_frame(struct b43_pio_rxqueue *q)
 	unsigned int i, padding;
 	struct sk_buff *skb;
 	const char *err_msg = NULL;
+	struct b43_rxhdr_fw4 *rxhdr =
+		(struct b43_rxhdr_fw4 *)wl->pio_scratchspace;
 
-	memset(&wl->rxhdr, 0, sizeof(wl->rxhdr));
+	BUILD_BUG_ON(sizeof(wl->pio_scratchspace) < sizeof(*rxhdr));
+	memset(rxhdr, 0, sizeof(*rxhdr));
 
 	/* Check if we have data and wait for it to get ready. */
 	if (q->rev >= 8) {
@@ -663,16 +672,16 @@ data_ready:
 
 	/* Get the preamble (RX header) */
 	if (q->rev >= 8) {
-		ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr),
+		ssb_block_read(dev->dev, rxhdr, sizeof(*rxhdr),
 			       q->mmio_base + B43_PIO8_RXDATA,
 			       sizeof(u32));
 	} else {
-		ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr),
+		ssb_block_read(dev->dev, rxhdr, sizeof(*rxhdr),
 			       q->mmio_base + B43_PIO_RXDATA,
 			       sizeof(u16));
 	}
 	/* Sanity checks. */
-	len = le16_to_cpu(wl->rxhdr.frame_len);
+	len = le16_to_cpu(rxhdr->frame_len);
 	if (unlikely(len > 0x700)) {
 		err_msg = "len > 0x700";
 		goto rx_error;
@@ -682,7 +691,7 @@ data_ready:
 		goto rx_error;
 	}
 
-	macstat = le32_to_cpu(wl->rxhdr.mac_status);
+	macstat = le32_to_cpu(rxhdr->mac_status);
 	if (macstat & B43_RX_MAC_FCSERR) {
 		if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) {
 			/* Drop frames with failed FCS. */
@@ -707,22 +716,25 @@ data_ready:
 			       q->mmio_base + B43_PIO8_RXDATA,
 			       sizeof(u32));
 		if (len & 3) {
+			u8 *tail = wl->pio_tailspace;
+			BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 4);
+
 			/* Read the last few bytes. */
-			ssb_block_read(dev->dev, wl->rx_tail, 4,
+			ssb_block_read(dev->dev, tail, 4,
 				       q->mmio_base + B43_PIO8_RXDATA,
 				       sizeof(u32));
 			switch (len & 3) {
 			case 3:
-				skb->data[len + padding - 3] = wl->rx_tail[0];
-				skb->data[len + padding - 2] = wl->rx_tail[1];
-				skb->data[len + padding - 1] = wl->rx_tail[2];
+				skb->data[len + padding - 3] = tail[0];
+				skb->data[len + padding - 2] = tail[1];
+				skb->data[len + padding - 1] = tail[2];
 				break;
 			case 2:
-				skb->data[len + padding - 2] = wl->rx_tail[0];
-				skb->data[len + padding - 1] = wl->rx_tail[1];
+				skb->data[len + padding - 2] = tail[0];
+				skb->data[len + padding - 1] = tail[1];
 				break;
 			case 1:
-				skb->data[len + padding - 1] = wl->rx_tail[0];
+				skb->data[len + padding - 1] = tail[0];
 				break;
 			}
 		}
@@ -731,15 +743,18 @@ data_ready:
 			       q->mmio_base + B43_PIO_RXDATA,
 			       sizeof(u16));
 		if (len & 1) {
+			u8 *tail = wl->pio_tailspace;
+			BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 2);
+
 			/* Read the last byte. */
-			ssb_block_read(dev->dev, wl->rx_tail, 2,
+			ssb_block_read(dev->dev, tail, 2,
 				       q->mmio_base + B43_PIO_RXDATA,
 				       sizeof(u16));
-			skb->data[len + padding - 1] = wl->rx_tail[0];
+			skb->data[len + padding - 1] = tail[0];
 		}
 	}
 
-	b43_rx(q->dev, skb, &wl->rxhdr);
+	b43_rx(q->dev, skb, rxhdr);
 
 	return 1;
 
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index f4e9695..51d6897 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -27,7 +27,7 @@
 
 */
 
-#include "b43.h"
+#include "xmit.h"
 #include "phy_common.h"
 #include "dma.h"
 #include "pio.h"

b43_-Remove-reset-after-fatal-DMA-error.patch:
 main.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

--- NEW FILE b43_-Remove-reset-after-fatal-DMA-error.patch ---
commit 214ac9a4ead6cb254451c09d9c8234a76693feb1
Author: Larry Finger <Larry.Finger at lwfinger.net>
Date:   Wed Dec 9 13:25:56 2009 -0600

    b43: Remove reset after fatal DMA error
    
    As shown in Kernel Bugzilla #14761, doing a controller restart after a
    fatal DMA error does not accomplish anything other than consume the CPU
    on an affected system. Accordingly, substitute a meaningful message for
    the restart.
    
    Signed-off-by: Larry Finger <Larry.Finger at lwfinger.net>
    Cc: Stable <stable at vger.kernel.org>        [2.6.32]
    Signed-off-by: John W. Linville <linville at tuxdriver.com>

diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 077480c..19b4eae 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1784,7 +1784,10 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev)
 			       dma_reason[0], dma_reason[1],
 			       dma_reason[2], dma_reason[3],
 			       dma_reason[4], dma_reason[5]);
-			b43_controller_restart(dev, "DMA error");
+			b43err(dev->wl, "This device does not support DMA "
+			       "on your system. Please use PIO instead.\n");
+			b43err(dev->wl, "CONFIG_B43_FORCE_PIO must be set in "
+			       "your kernel configuration.\n");
 			return;
 		}
 		if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) {

b43_-fall-back-gracefully-to-PIO-mode-after-fatal-DMA-errors.patch:
 Kconfig |   19 +++++++++++++++++--
 b43.h   |    7 +++++++
 main.c  |   14 ++++++++------
 3 files changed, 32 insertions(+), 8 deletions(-)

--- NEW FILE b43_-fall-back-gracefully-to-PIO-mode-after-fatal-DMA-errors.patch ---
Back-port of the following upstream commit...

commit 9e3bd9190800e8209b4a3e1d724c35f0738dcad2
Author: Linus Torvalds <torvalds at linux-foundation.org>
Date:   Fri Feb 26 10:34:27 2010 -0800

    b43: fall back gracefully to PIO mode after fatal DMA errors
    
    This makes the b43 driver just automatically fall back to PIO mode when
    DMA doesn't work.
    
    The driver already told the user to do it, so rather than have the user
    reload the module with a new flag, just make the driver do it
    automatically. We keep the message as an indication that something is
    wrong, but now just automatically fall back to the hopefully working PIO
    case.
    
    (Some post-2.6.33 merge fixups by Larry Finger <Larry.Finger at lwfinger.net>
    and yours truly... -- JWL)
    
    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
    Signed-off-by: John W. Linville <linville at tuxdriver.com>

diff -up linux-2.6.32.noarch/drivers/net/wireless/b43/b43.h.orig linux-2.6.32.noarch/drivers/net/wireless/b43/b43.h
--- linux-2.6.32.noarch/drivers/net/wireless/b43/b43.h.orig	2010-04-12 13:38:24.000000000 -0400
+++ linux-2.6.32.noarch/drivers/net/wireless/b43/b43.h	2010-04-12 13:39:48.000000000 -0400
@@ -696,6 +696,7 @@ struct b43_wldev {
 	bool radio_hw_enable;	/* saved state of radio hardware enabled state */
 	bool qos_enabled;		/* TRUE, if QoS is used. */
 	bool hwcrypto_enabled;		/* TRUE, if HW crypto acceleration is enabled. */
+	bool use_pio;			/* TRUE if next init should use PIO */
 
 	/* PHY/Radio device. */
 	struct b43_phy phy;
@@ -880,6 +881,12 @@ static inline bool b43_using_pio_transfe
 	return dev->__using_pio_transfers;
 }
 
+#ifdef CONFIG_B43_FORCE_PIO
+# define B43_PIO_DEFAULT 1
+#else
+# define B43_PIO_DEFAULT 0
+#endif
+
 /* Message printing */
 void b43info(struct b43_wl *wl, const char *fmt, ...)
     __attribute__ ((format(printf, 2, 3)));
diff -up linux-2.6.32.noarch/drivers/net/wireless/b43/Kconfig.orig linux-2.6.32.noarch/drivers/net/wireless/b43/Kconfig
--- linux-2.6.32.noarch/drivers/net/wireless/b43/Kconfig.orig	2010-04-12 13:38:24.000000000 -0400
+++ linux-2.6.32.noarch/drivers/net/wireless/b43/Kconfig	2010-04-12 13:39:48.000000000 -0400
@@ -3,7 +3,6 @@ config B43
 	depends on SSB_POSSIBLE && MAC80211 && WLAN_80211 && HAS_DMA
 	select SSB
 	select FW_LOADER
-	select SSB_BLOCKIO
 	---help---
 	  b43 is a driver for the Broadcom 43xx series wireless devices.
 
@@ -79,6 +78,14 @@ config B43_SDIO
 
 	  If unsure, say N.
 
+#Data transfers to the device via PIO. We want it as a fallback even
+# if we can do DMA.
+config B43_PIO
+	bool
+	depends on B43
+	select SSB_BLOCKIO
+	default y
+
 config B43_NPHY
 	bool "Pre IEEE 802.11n support (BROKEN)"
 	depends on B43 && EXPERIMENTAL && BROKEN
@@ -130,4 +137,12 @@ config B43_DEBUG
 	  for production use.
 	  Only say Y, if you are debugging a problem in the b43 driver sourcecode.
 
-
+config B43_FORCE_PIO
+	bool "Force usage of PIO instead of DMA"
+	depends on B43 && B43_DEBUG
+	---help---
+	  This will disable DMA and always enable PIO instead.
+
+	  Say N!
+	  This is only for debugging the PIO engine code. You do
+	  _NOT_ want to enable this.
diff -up linux-2.6.32.noarch/drivers/net/wireless/b43/main.c.orig linux-2.6.32.noarch/drivers/net/wireless/b43/main.c
--- linux-2.6.32.noarch/drivers/net/wireless/b43/main.c.orig	2010-04-12 13:38:24.000000000 -0400
+++ linux-2.6.32.noarch/drivers/net/wireless/b43/main.c	2010-04-12 13:39:48.000000000 -0400
@@ -102,9 +102,9 @@ int b43_modparam_verbose = B43_VERBOSITY
 module_param_named(verbose, b43_modparam_verbose, int, 0644);
 MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug");
 
-static int modparam_pio;
-module_param_named(pio, modparam_pio, int, 0444);
-MODULE_PARM_DESC(pio, "enable(1) / disable(0) PIO mode");
+int b43_modparam_pio = B43_PIO_DEFAULT;
+module_param_named(pio, b43_modparam_pio, int, 0644);
+MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
 
 static const struct ssb_device_id b43_ssb_tbl[] = {
 	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5),
@@ -1793,8 +1793,9 @@ static void b43_do_interrupt_thread(stru
 			       dma_reason[4], dma_reason[5]);
 			b43err(dev->wl, "This device does not support DMA "
 			       "on your system. Please use PIO instead.\n");
-			b43err(dev->wl, "Unload the b43 module and reload "
-			       "with 'pio=1'\n");
+			/* Fall back to PIO transfers if we get fatal DMA errors! */
+			dev->use_pio = 1;
+			b43_controller_restart(dev, "DMA error");
 			return;
 		}
 		if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) {
@@ -4361,7 +4362,7 @@ static int b43_wireless_core_init(struct
 
 	if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) ||
 	    (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) ||
-	    modparam_pio) {
+	    dev->use_pio) {
 		dev->__using_pio_transfers = 1;
 		err = b43_pio_init(dev);
 	} else {
@@ -4829,6 +4830,7 @@ static int b43_one_core_attach(struct ss
 	if (!wldev)
 		goto out;
 
+	wldev->use_pio = b43_modparam_pio;
 	wldev->dev = dev;
 	wldev->wl = wl;
 	b43_set_status(wldev, B43_STAT_UNINIT);


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-12/kernel.spec,v
retrieving revision 1.2063
retrieving revision 1.2064
diff -u -p -r1.2063 -r1.2064
--- kernel.spec	14 Apr 2010 20:57:26 -0000	1.2063
+++ kernel.spec	16 Apr 2010 14:55:00 -0000	1.2064
@@ -805,6 +805,12 @@ Patch12414: iwlwifi_-Recover-TX-flow-fai
 Patch12415: iwlwifi_-code-cleanup-for-connectivity-recovery.patch
 Patch12416: iwlwifi_-iwl_good_ack_health-only-apply-to-AGN-device.patch
 
+# make b43 gracefully switch to PIO mode in event of DMA errors
+Patch12420: b43_-Optimize-PIO-scratchbuffer-usage.patch
+Patch12421: b43_-Remove-reset-after-fatal-DMA-error.patch
+Patch12422: b43_-Allow-PIO-mode-to-be-selected-at-module-load.patch
+Patch12423: b43_-fall-back-gracefully-to-PIO-mode-after-fatal-DMA-errors.patch
+
 # ==============================================================================
 
 %endif
@@ -1484,6 +1490,12 @@ ApplyPatch iwlwifi_-Recover-TX-flow-fail
 ApplyPatch iwlwifi_-code-cleanup-for-connectivity-recovery.patch
 ApplyPatch iwlwifi_-iwl_good_ack_health-only-apply-to-AGN-device.patch
 
+# make b43 gracefully switch to PIO mode in event of DMA errors
+ApplyPatch b43_-Optimize-PIO-scratchbuffer-usage.patch
+ApplyPatch b43_-Remove-reset-after-fatal-DMA-error.patch
+ApplyPatch b43_-Allow-PIO-mode-to-be-selected-at-module-load.patch
+ApplyPatch b43_-fall-back-gracefully-to-PIO-mode-after-fatal-DMA-errors.patch
+
 # END OF PATCH APPLICATIONS ====================================================
 
 %endif
@@ -2137,6 +2149,12 @@ fi
 # and build.
 
 %changelog
+* Fri Apr 16 2010 John W. Linville <linville at redhat.com> 2.6.32.11-104
+- b43: Optimize PIO scratchbuffer usage
+- b43: Remove reset after fatal DMA error
+- b43: Allow PIO mode to be selected at module load
+- b43: fall back gracefully to PIO mode after fatal DMA errors
+
 * Wed Apr 14 2010 David Woodhouse <David.Woodhouse at intel.com>
 - Fix autoloading of phy modules (#525966)
 



More information about the scm-commits mailing list