[PATCH] bcm43xx: Fix PPC machine checks and match loopback gain specs

The specifications for loopback_gain calculation and for G PHY
initialization have been updated. This patch implements them and
fixes a machine check error that occurs for PPC architecture with a
phy->rev of 1.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by Larry Finger and committed by John W. Linville ec759a2b 81e88006

+32 -25
+32 -25
drivers/net/wireless/bcm43xx/bcm43xx_phy.c
··· 978 { 979 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); 980 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); 981 - u16 backup_phy[15]; 982 u16 backup_radio[3]; 983 u16 backup_bband; 984 u16 i; ··· 989 backup_phy[1] = bcm43xx_phy_read(bcm, 0x0001); 990 backup_phy[2] = bcm43xx_phy_read(bcm, 0x0811); 991 backup_phy[3] = bcm43xx_phy_read(bcm, 0x0812); 992 - backup_phy[4] = bcm43xx_phy_read(bcm, 0x0814); 993 - backup_phy[5] = bcm43xx_phy_read(bcm, 0x0815); 994 backup_phy[6] = bcm43xx_phy_read(bcm, 0x005A); 995 backup_phy[7] = bcm43xx_phy_read(bcm, 0x0059); 996 backup_phy[8] = bcm43xx_phy_read(bcm, 0x0058); ··· 1020 bcm43xx_phy_read(bcm, 0x0811) | 0x0001); 1021 bcm43xx_phy_write(bcm, 0x0812, 1022 bcm43xx_phy_read(bcm, 0x0812) & 0xFFFE); 1023 - bcm43xx_phy_write(bcm, 0x0814, 1024 - bcm43xx_phy_read(bcm, 0x0814) | 0x0001); 1025 - bcm43xx_phy_write(bcm, 0x0815, 1026 - bcm43xx_phy_read(bcm, 0x0815) & 0xFFFE); 1027 - bcm43xx_phy_write(bcm, 0x0814, 1028 - bcm43xx_phy_read(bcm, 0x0814) | 0x0002); 1029 - bcm43xx_phy_write(bcm, 0x0815, 1030 - bcm43xx_phy_read(bcm, 0x0815) & 0xFFFD); 1031 bcm43xx_phy_write(bcm, 0x0811, 1032 bcm43xx_phy_read(bcm, 0x0811) | 0x000C); 1033 bcm43xx_phy_write(bcm, 0x0812, ··· 1052 bcm43xx_phy_read(bcm, 0x000A) 1053 | 0x2000); 1054 } 1055 - bcm43xx_phy_write(bcm, 0x0814, 1056 - bcm43xx_phy_read(bcm, 0x0814) | 0x0004); 1057 - bcm43xx_phy_write(bcm, 0x0815, 1058 - bcm43xx_phy_read(bcm, 0x0815) & 0xFFFB); 1059 bcm43xx_phy_write(bcm, 0x0003, 1060 (bcm43xx_phy_read(bcm, 0x0003) 1061 & 0xFF9F) | 0x0040); ··· 1144 } 1145 } 1146 1147 - bcm43xx_phy_write(bcm, 0x0814, backup_phy[4]); 1148 - bcm43xx_phy_write(bcm, 0x0815, backup_phy[5]); 1149 bcm43xx_phy_write(bcm, 0x005A, backup_phy[6]); 1150 bcm43xx_phy_write(bcm, 0x0059, backup_phy[7]); 1151 bcm43xx_phy_write(bcm, 0x0058, backup_phy[8]); ··· 1196 bcm43xx_phy_write(bcm, 0x0811, 0x0000); 1197 bcm43xx_phy_write(bcm, 0x0015, 0x00C0); 1198 } 1199 - if (phy->rev >= 3) { 1200 bcm43xx_phy_write(bcm, 0x0811, 0x0400); 1201 bcm43xx_phy_write(bcm, 0x0015, 0x00C0); 1202 } 1203 if (phy->rev >= 2 && phy->connected) { 1204 tmp = bcm43xx_phy_read(bcm, 0x0400) & 0xFF; 1205 - if (tmp < 6) { 1206 bcm43xx_phy_write(bcm, 0x04C2, 0x1816); 1207 bcm43xx_phy_write(bcm, 0x04C3, 0x8006); 1208 - if (tmp != 3) { 1209 bcm43xx_phy_write(bcm, 0x04CC, 1210 (bcm43xx_phy_read(bcm, 0x04CC) 1211 & 0x00FF) | 0x1F00); 1212 } 1213 } 1214 - } 1215 - if (phy->rev < 3 && phy->connected) 1216 bcm43xx_phy_write(bcm, 0x047E, 0x0078); 1217 if (radio->revision == 8) { 1218 bcm43xx_phy_write(bcm, 0x0801, bcm43xx_phy_read(bcm, 0x0801) | 0x0080); 1219 bcm43xx_phy_write(bcm, 0x043E, bcm43xx_phy_read(bcm, 0x043E) | 0x0004); ··· 1239 if (phy->rev >= 6) { 1240 bcm43xx_phy_write(bcm, 0x0036, 1241 (bcm43xx_phy_read(bcm, 0x0036) 1242 - & 0xF000) | (radio->txctl2 << 12)); 1243 } 1244 if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) 1245 bcm43xx_phy_write(bcm, 0x002E, 0x8075); ··· 1250 else 1251 bcm43xx_phy_write(bcm, 0x002F, 0x0202); 1252 } 1253 - if (phy->connected) { 1254 bcm43xx_phy_lo_adjust(bcm, 0); 1255 bcm43xx_phy_write(bcm, 0x080F, 0x8078); 1256 } ··· 1264 */ 1265 bcm43xx_nrssi_hw_update(bcm, 0xFFFF); 1266 bcm43xx_calc_nrssi_threshold(bcm); 1267 - } else if (phy->connected) { 1268 if (radio->nrssi[0] == -1000) { 1269 assert(radio->nrssi[1] == -1000); 1270 bcm43xx_calc_nrssi_slope(bcm);
··· 978 { 979 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); 980 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); 981 + u16 backup_phy[15] = {0}; 982 u16 backup_radio[3]; 983 u16 backup_bband; 984 u16 i; ··· 989 backup_phy[1] = bcm43xx_phy_read(bcm, 0x0001); 990 backup_phy[2] = bcm43xx_phy_read(bcm, 0x0811); 991 backup_phy[3] = bcm43xx_phy_read(bcm, 0x0812); 992 + if (phy->rev != 1) { 993 + backup_phy[4] = bcm43xx_phy_read(bcm, 0x0814); 994 + backup_phy[5] = bcm43xx_phy_read(bcm, 0x0815); 995 + } 996 backup_phy[6] = bcm43xx_phy_read(bcm, 0x005A); 997 backup_phy[7] = bcm43xx_phy_read(bcm, 0x0059); 998 backup_phy[8] = bcm43xx_phy_read(bcm, 0x0058); ··· 1018 bcm43xx_phy_read(bcm, 0x0811) | 0x0001); 1019 bcm43xx_phy_write(bcm, 0x0812, 1020 bcm43xx_phy_read(bcm, 0x0812) & 0xFFFE); 1021 + if (phy->rev != 1) { 1022 + bcm43xx_phy_write(bcm, 0x0814, 1023 + bcm43xx_phy_read(bcm, 0x0814) | 0x0001); 1024 + bcm43xx_phy_write(bcm, 0x0815, 1025 + bcm43xx_phy_read(bcm, 0x0815) & 0xFFFE); 1026 + bcm43xx_phy_write(bcm, 0x0814, 1027 + bcm43xx_phy_read(bcm, 0x0814) | 0x0002); 1028 + bcm43xx_phy_write(bcm, 0x0815, 1029 + bcm43xx_phy_read(bcm, 0x0815) & 0xFFFD); 1030 + } 1031 bcm43xx_phy_write(bcm, 0x0811, 1032 bcm43xx_phy_read(bcm, 0x0811) | 0x000C); 1033 bcm43xx_phy_write(bcm, 0x0812, ··· 1048 bcm43xx_phy_read(bcm, 0x000A) 1049 | 0x2000); 1050 } 1051 + if (phy->rev != 1) { 1052 + bcm43xx_phy_write(bcm, 0x0814, 1053 + bcm43xx_phy_read(bcm, 0x0814) | 0x0004); 1054 + bcm43xx_phy_write(bcm, 0x0815, 1055 + bcm43xx_phy_read(bcm, 0x0815) & 0xFFFB); 1056 + } 1057 bcm43xx_phy_write(bcm, 0x0003, 1058 (bcm43xx_phy_read(bcm, 0x0003) 1059 & 0xFF9F) | 0x0040); ··· 1138 } 1139 } 1140 1141 + if (phy->rev != 1) { 1142 + bcm43xx_phy_write(bcm, 0x0814, backup_phy[4]); 1143 + bcm43xx_phy_write(bcm, 0x0815, backup_phy[5]); 1144 + } 1145 bcm43xx_phy_write(bcm, 0x005A, backup_phy[6]); 1146 bcm43xx_phy_write(bcm, 0x0059, backup_phy[7]); 1147 bcm43xx_phy_write(bcm, 0x0058, backup_phy[8]); ··· 1188 bcm43xx_phy_write(bcm, 0x0811, 0x0000); 1189 bcm43xx_phy_write(bcm, 0x0015, 0x00C0); 1190 } 1191 + if (phy->rev > 5) { 1192 bcm43xx_phy_write(bcm, 0x0811, 0x0400); 1193 bcm43xx_phy_write(bcm, 0x0015, 0x00C0); 1194 } 1195 if (phy->rev >= 2 && phy->connected) { 1196 tmp = bcm43xx_phy_read(bcm, 0x0400) & 0xFF; 1197 + if (tmp ==3 || tmp == 5) { 1198 bcm43xx_phy_write(bcm, 0x04C2, 0x1816); 1199 bcm43xx_phy_write(bcm, 0x04C3, 0x8006); 1200 + if (tmp == 5) { 1201 bcm43xx_phy_write(bcm, 0x04CC, 1202 (bcm43xx_phy_read(bcm, 0x04CC) 1203 & 0x00FF) | 0x1F00); 1204 } 1205 } 1206 bcm43xx_phy_write(bcm, 0x047E, 0x0078); 1207 + } 1208 if (radio->revision == 8) { 1209 bcm43xx_phy_write(bcm, 0x0801, bcm43xx_phy_read(bcm, 0x0801) | 0x0080); 1210 bcm43xx_phy_write(bcm, 0x043E, bcm43xx_phy_read(bcm, 0x043E) | 0x0004); ··· 1232 if (phy->rev >= 6) { 1233 bcm43xx_phy_write(bcm, 0x0036, 1234 (bcm43xx_phy_read(bcm, 0x0036) 1235 + & 0x0FFF) | (radio->txctl2 << 12)); 1236 } 1237 if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) 1238 bcm43xx_phy_write(bcm, 0x002E, 0x8075); ··· 1243 else 1244 bcm43xx_phy_write(bcm, 0x002F, 0x0202); 1245 } 1246 + if (phy->connected || phy->rev >= 2) { 1247 bcm43xx_phy_lo_adjust(bcm, 0); 1248 bcm43xx_phy_write(bcm, 0x080F, 0x8078); 1249 } ··· 1257 */ 1258 bcm43xx_nrssi_hw_update(bcm, 0xFFFF); 1259 bcm43xx_calc_nrssi_threshold(bcm); 1260 + } else if (phy->connected || phy->rev >= 2) { 1261 if (radio->nrssi[0] == -1000) { 1262 assert(radio->nrssi[1] == -1000); 1263 bcm43xx_calc_nrssi_slope(bcm);