In b43, the variable gmode merely indicates whether the given core
has a GPHY or a BPHY. In b43legacy, this is always true; however,
on a BCM4306/2 it must be set only when the PHY is connected to the
ssb backplane, otherwise, reads of the PHY registers are invalid.
For x86 architecture, these read failures cause no problems; however,
on the ppc architecture, they cause a machine check. This patch has been
tested on an i386 platform using special code to detect these invalid
reads, and on two different Powerbooks.
 
Signed-off-by: Larry Finger <[EMAIL PROTECTED]>
---

John,

This patch fixes a problem with the Fedora Rawhide kernel reported by David
Woodhouse on the bcm43xx mailing list and by Will Woods at 
https://bugzilla.redhat.com/show_bug.cgi?id=233011.

Larry

 drivers/net/wireless/b43legacy/main.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Index: wireless-dev/drivers/net/wireless/b43legacy/main.c
===================================================================
--- wireless-dev.orig/drivers/net/wireless/b43legacy/main.c
+++ wireless-dev/drivers/net/wireless/b43legacy/main.c
@@ -738,8 +738,11 @@ void b43legacy_wireless_core_reset(struc
 
        macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
        macctl &= ~B43legacy_MACCTL_GMODE;
-       if (flags & B43legacy_TMSLOW_GMODE)
+       if (flags & B43legacy_TMSLOW_GMODE) {
                macctl |= B43legacy_MACCTL_GMODE;
+               dev->phy.gmode = 1;
+       } else
+               dev->phy.gmode = 0;
        macctl |= B43legacy_MACCTL_IHR_ENABLED;
        b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
 }
@@ -3424,7 +3427,6 @@ static int b43legacy_wireless_core_attac
        int err;
        int have_bphy = 0;
        int have_gphy = 0;
-       u32 tmp;
 
        /* Do NOT do any device initialization here.
         * Do it in wireless_core_init() instead.
@@ -3456,9 +3458,7 @@ static int b43legacy_wireless_core_attac
        if (err)
                goto err_powerdown;
 
-       dev->phy.gmode = (have_gphy || have_bphy);
-       tmp = dev->phy.gmode ? B43legacy_TMSLOW_GMODE : 0;
-       b43legacy_wireless_core_reset(dev, tmp);
+       b43legacy_wireless_core_reset(dev, B43legacy_TMSLOW_GMODE);
 
        err = b43legacy_phy_versioning(dev);
        if (err)
@@ -3482,9 +3482,7 @@ static int b43legacy_wireless_core_attac
                        B43legacy_BUG_ON(1);
                }
        }
-       dev->phy.gmode = (have_gphy || have_bphy);
-       tmp = dev->phy.gmode ? B43legacy_TMSLOW_GMODE : 0;
-       b43legacy_wireless_core_reset(dev, tmp);
+       b43legacy_wireless_core_reset(dev, B43legacy_TMSLOW_GMODE);
 
        err = b43legacy_validate_chipaccess(dev);
        if (err)
Index: wireless-dev/drivers/net/wireless/b43legacy/b43legacy.h
===================================================================
--- wireless-dev.orig/drivers/net/wireless/b43legacy/b43legacy.h
+++ wireless-dev/drivers/net/wireless/b43legacy/b43legacy.h
@@ -389,7 +389,7 @@ struct b43legacy_lopair {
 struct b43legacy_phy {
        /* Possible PHYMODEs on this PHY */
        u8 possible_phymodes;
-       /* GMODE bit enabled? */
+       /* True if PHY connected to ssb backplane */
        bool gmode;
        /* Possible ieee80211 subsystem hwmodes for this PHY.
         * Which mode is selected, depends on thr GMODE enabled bit */
Index: wireless-dev/drivers/net/wireless/b43legacy/xmit.c
===================================================================
--- wireless-dev.orig/drivers/net/wireless/b43legacy/xmit.c
+++ wireless-dev/drivers/net/wireless/b43legacy/xmit.c
@@ -49,8 +49,8 @@ static u8 b43legacy_plcp_get_bitrate_cck
        case 0x6E:
                return B43legacy_CCK_RATE_11MB;
        }
-       B43legacy_BUG_ON(1);
-       return 0;
+       printk(KERN_INFO "b43legacy: Invalid CCK bitrate of 0x%X\n", 
plcp->raw[0]);
+       return B43legacy_CCK_RATE_1MB;
 }
 
 /* Extract the bitrate out of an OFDM PLCP header. */
@@ -74,8 +74,8 @@ static u8 b43legacy_plcp_get_bitrate_ofd
        case 0xC:
                return B43legacy_OFDM_RATE_54MB;
        }
-       B43legacy_BUG_ON(1);
-       return 0;
+       printk(KERN_INFO "b43legacy: Invalid OFDM bitrate of 0x%X\n", 
plcp->raw[0] & 0xF);
+       return B43legacy_OFDM_RATE_6MB;
 }
 
 u8 b43legacy_plcp_get_ratecode_cck(const u8 bitrate)
@@ -90,8 +90,8 @@ u8 b43legacy_plcp_get_ratecode_cck(const
        case B43legacy_CCK_RATE_11MB:
                return 0x6E;
        }
-       B43legacy_BUG_ON(1);
-       return 0;
+       printk(KERN_INFO "b43legacy: Invalid CCK ratecode of 0x%X\n", bitrate);
+       return 0x0A;
 }
 
 u8 b43legacy_plcp_get_ratecode_ofdm(const u8 bitrate)
@@ -114,8 +114,8 @@ u8 b43legacy_plcp_get_ratecode_ofdm(cons
        case B43legacy_OFDM_RATE_54MB:
                return 0xC;
        }
-       B43legacy_BUG_ON(1);
-       return 0;
+       printk(KERN_INFO "b43legacy: Invalid OFDM ratecode of 0x%X\n", bitrate);
+       return 0x0B;
 }
 
 void b43legacy_generate_plcp_hdr(struct b43legacy_plcp_hdr4 *plcp,
_______________________________________________
Bcm43xx-dev mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/bcm43xx-dev

Reply via email to