Search Linux Wireless

[PATCH] bcm43xx-mac80211: Fix machine checks on PPC with rev 1 PHYs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On PPC architecture with phy->rev == 1, machine checks occur during
initialization of the "Extended G PHY registers". This problem was
also seen on bcm43xx-softmac, and was fixed by conditionally skipping
over certain reads/writes of these registers.  The same solution has been
applied here with testing by David Woodhouse.  Note: These modifications
are not found in the specifications, but are needed for PPC.

Signed-off-by: Larry Finger <Larry.Finger@xxxxxxxxxxxx>
---

John and Michael,

This patch will apply to both the wireless-dev and the mb trees.

Larry

 bcm43xx_phy.c |   50 +++++++++++++++++++++++++++++---------------------
 1 file changed, 29 insertions(+), 21 deletions(-)

Index: wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_phy.c
===================================================================
--- wireless-dev.orig/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_phy.c
+++ wireless-dev/drivers/net/wireless/mac80211/bcm43xx/bcm43xx_phy.c
@@ -1362,7 +1362,7 @@ static void bcm43xx_phy_initb6(struct bc
 static void bcm43xx_calc_loopback_gain(struct bcm43xx_wldev *dev)
 {
 	struct bcm43xx_phy *phy = &dev->phy;
-	u16 backup_phy[16];
+	u16 backup_phy[16] = {0};
 	u16 backup_radio[3];
 	u16 backup_bband;
 	u16 i, j, loop_i_max;
@@ -1373,8 +1373,10 @@ static void bcm43xx_calc_loopback_gain(s
 	backup_phy[1] = bcm43xx_phy_read(dev, BCM43xx_PHY_CCKBBANDCFG);
 	backup_phy[2] = bcm43xx_phy_read(dev, BCM43xx_PHY_RFOVER);
 	backup_phy[3] = bcm43xx_phy_read(dev, BCM43xx_PHY_RFOVERVAL);
-	backup_phy[4] = bcm43xx_phy_read(dev, BCM43xx_PHY_ANALOGOVER);
-	backup_phy[5] = bcm43xx_phy_read(dev, BCM43xx_PHY_ANALOGOVERVAL);
+	if (phy->rev != 1) {
+		backup_phy[4] = bcm43xx_phy_read(dev, BCM43xx_PHY_ANALOGOVER);
+		backup_phy[5] = bcm43xx_phy_read(dev, BCM43xx_PHY_ANALOGOVERVAL);
+	}
 	backup_phy[6] = bcm43xx_phy_read(dev, BCM43xx_PHY_BASE(0x5A));
 	backup_phy[7] = bcm43xx_phy_read(dev, BCM43xx_PHY_BASE(0x59));
 	backup_phy[8] = bcm43xx_phy_read(dev, BCM43xx_PHY_BASE(0x58));
@@ -1402,14 +1404,16 @@ static void bcm43xx_calc_loopback_gain(s
 			  bcm43xx_phy_read(dev, BCM43xx_PHY_RFOVER) | 0x0001);
 	bcm43xx_phy_write(dev, BCM43xx_PHY_RFOVERVAL,
 			  bcm43xx_phy_read(dev, BCM43xx_PHY_RFOVERVAL) & 0xFFFE);
-	bcm43xx_phy_write(dev, BCM43xx_PHY_ANALOGOVER,
-			  bcm43xx_phy_read(dev, BCM43xx_PHY_ANALOGOVER) | 0x0001);
-	bcm43xx_phy_write(dev, BCM43xx_PHY_ANALOGOVERVAL,
-			  bcm43xx_phy_read(dev, BCM43xx_PHY_ANALOGOVERVAL) & 0xFFFE);
-	bcm43xx_phy_write(dev, BCM43xx_PHY_ANALOGOVER,
-			  bcm43xx_phy_read(dev, BCM43xx_PHY_ANALOGOVER) | 0x0002);
-	bcm43xx_phy_write(dev, BCM43xx_PHY_ANALOGOVERVAL,
-			  bcm43xx_phy_read(dev, BCM43xx_PHY_ANALOGOVERVAL) & 0xFFFD);
+	if (phy->rev != 1) {
+		bcm43xx_phy_write(dev, BCM43xx_PHY_ANALOGOVER,
+				  bcm43xx_phy_read(dev, BCM43xx_PHY_ANALOGOVER) | 0x0001);
+		bcm43xx_phy_write(dev, BCM43xx_PHY_ANALOGOVERVAL,
+				  bcm43xx_phy_read(dev, BCM43xx_PHY_ANALOGOVERVAL) & 0xFFFE);
+		bcm43xx_phy_write(dev, BCM43xx_PHY_ANALOGOVER,
+				  bcm43xx_phy_read(dev, BCM43xx_PHY_ANALOGOVER) | 0x0002);
+		bcm43xx_phy_write(dev, BCM43xx_PHY_ANALOGOVERVAL,
+				  bcm43xx_phy_read(dev, BCM43xx_PHY_ANALOGOVERVAL) & 0xFFFD);
+	}
 	bcm43xx_phy_write(dev, BCM43xx_PHY_RFOVER,
 			  bcm43xx_phy_read(dev, BCM43xx_PHY_RFOVER) | 0x000C);
 	bcm43xx_phy_write(dev, BCM43xx_PHY_RFOVER,
@@ -1426,10 +1430,12 @@ static void bcm43xx_calc_loopback_gain(s
 
 	bcm43xx_phy_write(dev, BCM43xx_PHY_BASE(0x0A),
 			  bcm43xx_phy_read(dev, BCM43xx_PHY_BASE(0x0A)) | 0x2000);
-	bcm43xx_phy_write(dev, BCM43xx_PHY_ANALOGOVER,
-			  bcm43xx_phy_read(dev, BCM43xx_PHY_ANALOGOVER) | 0x0004);
-	bcm43xx_phy_write(dev, BCM43xx_PHY_ANALOGOVERVAL,
-			  bcm43xx_phy_read(dev, BCM43xx_PHY_ANALOGOVERVAL) & 0xFFFB);
+	if (phy->rev != 1) {
+		bcm43xx_phy_write(dev, BCM43xx_PHY_ANALOGOVER,
+				  bcm43xx_phy_read(dev, BCM43xx_PHY_ANALOGOVER) | 0x0004);
+		bcm43xx_phy_write(dev, BCM43xx_PHY_ANALOGOVERVAL,
+				  bcm43xx_phy_read(dev, BCM43xx_PHY_ANALOGOVERVAL) & 0xFFFB);
+	}
 	bcm43xx_phy_write(dev, BCM43xx_PHY_BASE(0x03),
 			  (bcm43xx_phy_read(dev, BCM43xx_PHY_BASE(0x03))
 			   & 0xFF9F) | 0x40);
@@ -1522,8 +1528,10 @@ exit_loop1:
 		trsw_rx = 0x18;
 exit_loop2:
 
-	bcm43xx_phy_write(dev, BCM43xx_PHY_ANALOGOVER, backup_phy[4]);
-	bcm43xx_phy_write(dev, BCM43xx_PHY_ANALOGOVERVAL, backup_phy[5]);
+	if (phy->rev != 1) {
+		bcm43xx_phy_write(dev, BCM43xx_PHY_ANALOGOVER, backup_phy[4]);
+		bcm43xx_phy_write(dev, BCM43xx_PHY_ANALOGOVERVAL, backup_phy[5]);
+	}
 	bcm43xx_phy_write(dev, BCM43xx_PHY_BASE(0x5A), backup_phy[6]);
 	bcm43xx_phy_write(dev, BCM43xx_PHY_BASE(0x59), backup_phy[7]);
 	bcm43xx_phy_write(dev, BCM43xx_PHY_BASE(0x58), backup_phy[8]);
@@ -1576,7 +1584,7 @@ static void bcm43xx_phy_initg(struct bcm
 		bcm43xx_phy_write(dev, BCM43xx_PHY_RFOVER, 0x400);
 		bcm43xx_phy_write(dev, BCM43xx_PHY_PGACTL, 0xC0);
 	}
-	if (phy->gmode) {
+	if (phy->gmode && phy->rev >= 2) {
 		tmp = bcm43xx_phy_read(dev, BCM43xx_PHY_VERSION_OFDM);
 		tmp &= BCM43xx_PHYVER_VERSION;
 		if (tmp == 3 || tmp == 5) {
@@ -1635,7 +1643,7 @@ static void bcm43xx_phy_initg(struct bcm
 		else
 			bcm43xx_phy_write(dev, BCM43xx_PHY_BASE(0x2F), 0x202);
 	}
-	if (phy->gmode) {
+	if (phy->gmode && phy->rev != 1) {
 		bcm43xx_lo_adjust(dev);
 		bcm43xx_phy_write(dev, BCM43xx_PHY_LO_MASK, 0x8078);
 	}
@@ -1649,8 +1657,8 @@ static void bcm43xx_phy_initg(struct bcm
 		 */
 		bcm43xx_nrssi_hw_update(dev, 0xFFFF);//FIXME?
 		bcm43xx_calc_nrssi_threshold(dev);
-	} else {
-		if (phy->gmode && phy->nrssi[0] == -1000) {
+	} else if (phy->gmode && phy->rev != 1) {
+		if (phy->nrssi[0] == -1000) {
 			assert(phy->nrssi[1] == -1000);
 			bcm43xx_calc_nrssi_slope(dev);
 		} else
-
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux