brcmsmac: Fix I/O functions for MIPS and for big-endian architectures

svn path=/dists/sid/linux-2.6/; revision=18356
This commit is contained in:
Ben Hutchings 2011-12-05 16:05:06 +00:00
parent 619c99e343
commit 893f0879fa
7 changed files with 400 additions and 0 deletions

1
debian/changelog vendored
View File

@ -10,6 +10,7 @@ linux-2.6 (3.1.4-2) UNRELEASED; urgency=low
* USB: EHCI: fix HUB TT scheduling issue with iso transfer (Closes: #651015)
* [x86] Enable MEMTEST (Closes: #613321, #646361)
- If bad RAM is detected, WARN and recommend a more thorough test
* brcmsmac: Fix I/O functions for MIPS and for big-endian architectures
-- Bastian Blank <waldi@debian.org> Thu, 01 Dec 2011 13:17:34 +0100

View File

@ -0,0 +1,67 @@
From: Roland Vossen <rvossen@broadcom.com>
Date: Mon, 8 Aug 2011 15:58:22 +0200
Subject: [PATCH 1/5] staging: brcm80211: fixed build issue for big endian
platforms
commit 98ff86e37d1d1c3ebcaa124dfa9a900eb0e1fa77 upstream.
Driver now builds for big endian mips platform, possibly also for other
big endian platforms. A change was made to the R_REG and W_REG macro's.
These macro's perform an xor (^) operation for endianess swap purposes.
Gcc complained because an xor operation is not allowed on a pointer type.
Fixed this by casting the pointer to an unsigned long.
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/staging/brcm80211/brcmsmac/dma.h | 1 +
drivers/staging/brcm80211/brcmsmac/types.h | 8 ++++----
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/brcm80211/brcmsmac/dma.h b/drivers/staging/brcm80211/brcmsmac/dma.h
index 3ff109f..334f2eb 100644
--- a/drivers/staging/brcm80211/brcmsmac/dma.h
+++ b/drivers/staging/brcm80211/brcmsmac/dma.h
@@ -17,6 +17,7 @@
#ifndef _BRCM_DMA_H_
#define _BRCM_DMA_H_
+#include <linux/delay.h>
#include "types.h" /* forward structure declarations */
/* DMA structure:
diff --git a/drivers/staging/brcm80211/brcmsmac/types.h b/drivers/staging/brcm80211/brcmsmac/types.h
index e0880a0..ab97718 100644
--- a/drivers/staging/brcm80211/brcmsmac/types.h
+++ b/drivers/staging/brcm80211/brcmsmac/types.h
@@ -305,11 +305,11 @@ do { \
switch (sizeof(*(r))) { \
case sizeof(u8): \
__osl_v = \
- readb((u8 *)((r)^3)); \
+ readb((u8 *)((unsigned long)(r)^3)); \
break; \
case sizeof(u16): \
__osl_v = \
- readw((u16 *)((r)^2)); \
+ readw((u16 *)((unsigned long)(r)^2)); \
break; \
case sizeof(u32): \
__osl_v = readl((u32 *)(r)); \
@@ -322,10 +322,10 @@ do { \
switch (sizeof(*(r))) { \
case sizeof(u8): \
writeb((u8)(v), \
- (u8 *)((r)^3)); break; \
+ (u8 *)((unsigned long)(r)^3)); break; \
case sizeof(u16): \
writew((u16)(v), \
- (u16 *)((r)^2)); break; \
+ (u16 *)((unsigned long)(r)^2)); break; \
case sizeof(u32): \
writel((u32)(v), \
(u32 *)(r)); break; \
--
1.7.7.3

View File

@ -0,0 +1,137 @@
From: Roland Vossen <rvossen@broadcom.com>
Date: Mon, 8 Aug 2011 15:58:49 +0200
Subject: [PATCH 2/5] staging: brcm80211: simplified register access macro's in
softmac
commit b60987a15628046259be17471fd80ba92cf35ed2 upstream.
Code cleanup. Removed MIPS specific 'sync' instruction since this is not
required for the chips that this driver supports. MIPS specific macro's
were now the same as non-MIPS register access macro's and thus have been
deleted. Also added comment that makes clearer what the benefit of these
macro's is. Unified big and little end register access macro's.
Reported-by: Dan Carpenter <error27@gmail.com>
Reported-by: Julian Calaby <julian.calaby@gmail.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/staging/brcm80211/brcmsmac/types.h | 81 ++++++++++------------------
1 files changed, 29 insertions(+), 52 deletions(-)
diff --git a/drivers/staging/brcm80211/brcmsmac/types.h b/drivers/staging/brcm80211/brcmsmac/types.h
index 360795f..16a1c6a 100644
--- a/drivers/staging/brcm80211/brcmsmac/types.h
+++ b/drivers/staging/brcm80211/brcmsmac/types.h
@@ -320,60 +320,38 @@ do { \
#define WL_ERROR_ON() (brcm_msg_level & LOG_ERROR_VAL)
-/* register access macros */
+/*
+ * Register access macros.
+ *
+ * These macro's take a pointer to the address to read as one of their
+ * arguments. The macro itself deduces the size of the IO transaction (u8, u16
+ * or u32). Advantage of this approach in combination with using a struct to
+ * define the registers in a register block, is that access size and access
+ * location are defined in only one spot. This reduces the risk of the
+ * programmer trying to use an unsupported transaction size on a register.
+ *
+ * For big endian operation, a byte swap has to be done. Eg, when attempting
+ * to read byte address 0, byte 3 should be read. This is accomplished
+ * using an xor ('^') operator.
+ */
+
#ifndef __BIG_ENDIAN
-#ifndef __mips__
-#define R_REG(r) \
- ({\
- sizeof(*(r)) == sizeof(u8) ? \
- readb((u8 *)(r)) : \
- sizeof(*(r)) == sizeof(u16) ? readw((u16 *)(r)) : \
- readl((u32 *)(r)); \
- })
-#else /* __mips__ */
-#define R_REG(r) \
- ({ \
- __typeof(*(r)) __osl_v; \
- __asm__ __volatile__("sync"); \
- switch (sizeof(*(r))) { \
- case sizeof(u8): \
- __osl_v = readb((u8 *)(r)); \
- break; \
- case sizeof(u16): \
- __osl_v = readw((u16 *)(r)); \
- break; \
- case sizeof(u32): \
- __osl_v = \
- readl((u32 *)(r)); \
- break; \
- } \
- __asm__ __volatile__("sync"); \
- __osl_v; \
- })
-#endif /* __mips__ */
+#define SWP2(r) (r)
+#define SWP3(r) (r)
+#else
+#define SWP2(r) ((unsigned long)(r)^2)
+#define SWP3(r) ((unsigned long)(r)^3)
+#endif /* __BIG_ENDIAN */
-#define W_REG(r, v) do { \
- switch (sizeof(*(r))) { \
- case sizeof(u8): \
- writeb((u8)(v), (u8 *)(r)); break; \
- case sizeof(u16): \
- writew((u16)(v), (u16 *)(r)); break; \
- case sizeof(u32): \
- writel((u32)(v), (u32 *)(r)); break; \
- }; \
- } while (0)
-#else /* __BIG_ENDIAN */
#define R_REG(r) \
({ \
__typeof(*(r)) __osl_v; \
switch (sizeof(*(r))) { \
case sizeof(u8): \
- __osl_v = \
- readb((u8 *)((unsigned long)(r)^3)); \
+ __osl_v = readb((u8 *)(SWP3(r))); \
break; \
case sizeof(u16): \
- __osl_v = \
- readw((u16 *)((unsigned long)(r)^2)); \
+ __osl_v = readw((u16 *)(SWP2(r))); \
break; \
case sizeof(u32): \
__osl_v = readl((u32 *)(r)); \
@@ -385,17 +363,16 @@ do { \
#define W_REG(r, v) do { \
switch (sizeof(*(r))) { \
case sizeof(u8): \
- writeb((u8)(v), \
- (u8 *)((unsigned long)(r)^3)); break; \
+ writeb((u8)(v), (u8 *)(SWP3(r))); \
+ break; \
case sizeof(u16): \
- writew((u16)(v), \
- (u16 *)((unsigned long)(r)^2)); break; \
+ writew((u16)(v), (u16 *)(SWP2(r))); \
+ break; \
case sizeof(u32): \
- writel((u32)(v), \
- (u32 *)(r)); break; \
+ writel((u32)(v), (u32 *)(r)); \
+ break; \
} \
} while (0)
-#endif /* __BIG_ENDIAN */
#ifdef __mips__
/*
--
1.7.7.3

View File

@ -0,0 +1,71 @@
From: Henry Ptasinski <henryp@broadcom.com>
Date: Mon, 15 Aug 2011 15:34:22 +0200
Subject: [PATCH 3/5] staging: brcm80211: Remove swaps in R_REG and W_REG macros
commit ba1fff7f705ed15e9d5a5922614aa4a259e9f8bc upstream.
Swapping the addresses is unnecessary, since the swaps are handled by the
underlying platform code (i.e. readb() etc. handle any necessary swapping).
Tested on Mac G5 PPC and BCM63281.
Signed-off-by: Henry Ptasinski <henryp@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Tested-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/staging/brcm80211/brcmsmac/types.h | 19 ++++---------------
1 files changed, 4 insertions(+), 15 deletions(-)
diff --git a/drivers/staging/brcm80211/brcmsmac/types.h b/drivers/staging/brcm80211/brcmsmac/types.h
index c0d41cc..ad874a7 100644
--- a/drivers/staging/brcm80211/brcmsmac/types.h
+++ b/drivers/staging/brcm80211/brcmsmac/types.h
@@ -329,28 +329,17 @@ do { \
* location are defined in only one spot. This reduces the risk of the
* programmer trying to use an unsupported transaction size on a register.
*
- * For big endian operation, a byte swap has to be done. Eg, when attempting
- * to read byte address 0, byte 3 should be read. This is accomplished
- * using an xor ('^') operator.
*/
-#ifndef __BIG_ENDIAN
-#define SWP2(r) (r)
-#define SWP3(r) (r)
-#else
-#define SWP2(r) ((unsigned long)(r)^2)
-#define SWP3(r) ((unsigned long)(r)^3)
-#endif /* __BIG_ENDIAN */
-
#define R_REG(r) \
({ \
__typeof(*(r)) __osl_v; \
switch (sizeof(*(r))) { \
case sizeof(u8): \
- __osl_v = readb((u8 *)(SWP3(r))); \
+ __osl_v = readb((u8 *)(r)); \
break; \
case sizeof(u16): \
- __osl_v = readw((u16 *)(SWP2(r))); \
+ __osl_v = readw((u16 *)(r)); \
break; \
case sizeof(u32): \
__osl_v = readl((u32 *)(r)); \
@@ -362,10 +351,10 @@ do { \
#define W_REG(r, v) do { \
switch (sizeof(*(r))) { \
case sizeof(u8): \
- writeb((u8)(v), (u8 *)(SWP3(r))); \
+ writeb((u8)(v), (u8 *)(r)); \
break; \
case sizeof(u16): \
- writew((u16)(v), (u16 *)(SWP2(r))); \
+ writew((u16)(v), (u16 *)(r)); \
break; \
case sizeof(u32): \
writel((u32)(v), (u32 *)(r)); \
--
1.7.7.3

View File

@ -0,0 +1,62 @@
From: Arend van Spriel <arend@broadcom.com>
Date: Mon, 15 Aug 2011 15:34:25 +0200
Subject: [PATCH 4/5] staging: brcm80211: restrict register access method for
bcm47xx
commit 3bd8ef6799524fd48044a83aab38da57d9a98dbc upstream.
The driver contained conditional code for resolving issue with
dma transaction reordering. This code was conditionalized using
__mips__ macro, but it actually is specific to bcm47xx chips.
This patch replaces it for the more speficic CONFIG_BCM47XX macro.
Tested on BCM63281.
Reviewed-by: Henry Ptasinski <henryp@broadcom.com>
Reviewed-by: Roland Vossen <rvossen@broadcom.com>
Tested-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/staging/brcm80211/brcmsmac/phy/phy_cmn.c | 2 +-
drivers/staging/brcm80211/brcmsmac/types.h | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_cmn.c b/drivers/staging/brcm80211/brcmsmac/phy/phy_cmn.c
index c00178d..448afae 100644
--- a/drivers/staging/brcm80211/brcmsmac/phy/phy_cmn.c
+++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_cmn.c
@@ -380,7 +380,7 @@ void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
regs = pi->regs;
-#ifdef __mips__
+#ifdef CONFIG_BCM47XX
W_REG_FLUSH(&regs->phyregaddr, addr);
W_REG(&regs->phyregdata, val);
if (addr == 0x72)
diff --git a/drivers/staging/brcm80211/brcmsmac/types.h b/drivers/staging/brcm80211/brcmsmac/types.h
index ad874a7..d44db56 100644
--- a/drivers/staging/brcm80211/brcmsmac/types.h
+++ b/drivers/staging/brcm80211/brcmsmac/types.h
@@ -362,7 +362,7 @@ do { \
} \
} while (0)
-#ifdef __mips__
+#ifdef CONFIG_BCM47XX
/*
* bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder
* transactions. As a fix, a read after write is performed on certain places
@@ -371,7 +371,7 @@ do { \
#define W_REG_FLUSH(r, v) ({ W_REG((r), (v)); (void)R_REG(r); })
#else
#define W_REG_FLUSH(r, v) W_REG((r), (v))
-#endif /* __mips__ */
+#endif /* CONFIG_BCM47XX */
#define AND_REG(r, v) W_REG((r), R_REG(r) & (v))
#define OR_REG(r, v) W_REG((r), R_REG(r) | (v))
--
1.7.7.3

View File

@ -0,0 +1,56 @@
From: Arend van Spriel <arend@broadcom.com>
Date: Mon, 15 Aug 2011 15:34:26 +0200
Subject: [PATCH 5/5] staging: brcm80211: restrict MIPS dma bug workaround to
BCM47XX
commit adf27befdc79a9403bfba82ee84f02a47bcd546c upstream.
The inline function dma_spin_for_len() was defined for MIPS platforms
but the problem only occurs with dma of the PCI core in bcm47xx chips.
This patch restricts the function further to BCM47XX platforms only.
Tested on BCM63281.
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Henry Ptasinski <henryp@broadcom.com>
Reviewed-by: Roland Vossen <rvossen@broadcom.com>
Tested-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/staging/brcm80211/brcmsmac/dma.h | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/brcm80211/brcmsmac/dma.h b/drivers/staging/brcm80211/brcmsmac/dma.h
index 134402c..2ce59638 100644
--- a/drivers/staging/brcm80211/brcmsmac/dma.h
+++ b/drivers/staging/brcm80211/brcmsmac/dma.h
@@ -100,21 +100,21 @@ void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)
(void *pkt, void *arg_a), void *arg_a);
/*
- * DMA(Bug) on some chips seems to declare that the packet is ready, but the
- * packet length is not updated yet (by DMA) on the expected time.
+ * DMA(Bug) on bcm47xx chips seems to declare that the packet is ready, but
+ * the packet length is not updated yet (by DMA) on the expected time.
* Workaround is to hold processor till DMA updates the length, and stay off
* the bus to allow DMA update the length in buffer
*/
static inline void dma_spin_for_len(uint len, struct sk_buff *head)
{
-#if defined(__mips__)
+#if defined(CONFIG_BCM47XX)
if (!len) {
while (!(len = *(u16 *) KSEG1ADDR(head->data)))
udelay(1);
*(u16 *) (head->data) = cpu_to_le16((u16) len);
}
-#endif /* defined(__mips__) */
+#endif /* defined(CONFIG_BCM47XX) */
}
#endif /* _BRCM_DMA_H_ */
--
1.7.7.3

View File

@ -83,3 +83,9 @@
+ bugfix/all/USB-EHCI-fix-HUB-TT-scheduling-issue-with-iso-transf.patch
+ bugfix/all/EHCI-Fix-a-regression-in-the-ISO-scheduler.patch
+ debian/x86-memtest-WARN-if-bad-RAM-found.patch
+ bugfix/all/0001-staging-brcm80211-fixed-build-issue-for-big-endian-p.patch
+ bugfix/all/0002-staging-brcm80211-simplified-register-access-macro-s.patch
+ bugfix/all/0003-staging-brcm80211-Remove-swaps-in-R_REG-and-W_REG-ma.patch
+ bugfix/all/0004-staging-brcm80211-restrict-register-access-method-fo.patch
+ bugfix/all/0005-staging-brcm80211-restrict-MIPS-dma-bug-workaround-t.patch