aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/phy_n.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/b43/phy_n.c')
-rw-r--r--drivers/net/wireless/b43/phy_n.c532
1 files changed, 427 insertions, 105 deletions
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index bf5a43855358..108118820b36 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -85,22 +85,11 @@ static inline bool b43_nphy_ipa(struct b43_wldev *dev)
85 (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)); 85 (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ));
86} 86}
87 87
88/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */ 88/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCoreGetState */
89static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev) 89static u8 b43_nphy_get_rx_core_state(struct b43_wldev *dev)
90{ 90{
91 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 91 return (b43_phy_read(dev, B43_NPHY_RFSEQCA) & B43_NPHY_RFSEQCA_RXEN) >>
92 if (dev->phy.rev >= 6) { 92 B43_NPHY_RFSEQCA_RXEN_SHIFT;
93 if (dev->dev->chip_id == 47162)
94 return txpwrctrl_tx_gain_ipa_rev5;
95 return txpwrctrl_tx_gain_ipa_rev6;
96 } else if (dev->phy.rev >= 5) {
97 return txpwrctrl_tx_gain_ipa_rev5;
98 } else {
99 return txpwrctrl_tx_gain_ipa;
100 }
101 } else {
102 return txpwrctrl_tx_gain_ipa_5g;
103 }
104} 93}
105 94
106/************************************************** 95/**************************************************
@@ -229,7 +218,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
229 218
230 reg = (i == 0) ? 219 reg = (i == 0) ?
231 B43_NPHY_RFCTL_INTC1 : B43_NPHY_RFCTL_INTC2; 220 B43_NPHY_RFCTL_INTC1 : B43_NPHY_RFCTL_INTC2;
232 b43_phy_mask(dev, reg, 0xFBFF); 221 b43_phy_set(dev, reg, 0x400);
233 222
234 switch (field) { 223 switch (field) {
235 case 0: 224 case 0:
@@ -245,7 +234,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
245 b43_phy_set(dev, B43_NPHY_RFCTL_CMD, 234 b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
246 B43_NPHY_RFCTL_CMD_START); 235 B43_NPHY_RFCTL_CMD_START);
247 for (j = 0; j < 100; j++) { 236 for (j = 0; j < 100; j++) {
248 if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_START) { 237 if (!(b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_START)) {
249 j = 0; 238 j = 0;
250 break; 239 break;
251 } 240 }
@@ -264,7 +253,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
264 b43_phy_set(dev, B43_NPHY_RFCTL_CMD, 253 b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
265 B43_NPHY_RFCTL_CMD_RXTX); 254 B43_NPHY_RFCTL_CMD_RXTX);
266 for (j = 0; j < 100; j++) { 255 for (j = 0; j < 100; j++) {
267 if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_RXTX) { 256 if (!(b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_RXTX)) {
268 j = 0; 257 j = 0;
269 break; 258 break;
270 } 259 }
@@ -1231,12 +1220,12 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
1231 u16 s[2]; 1220 u16 s[2];
1232 1221
1233 if (dev->phy.rev >= 3) { 1222 if (dev->phy.rev >= 3) {
1234 save_regs_phy[0] = b43_phy_read(dev, 1223 save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
1224 save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
1225 save_regs_phy[2] = b43_phy_read(dev,
1235 B43_NPHY_RFCTL_LUT_TRSW_UP1); 1226 B43_NPHY_RFCTL_LUT_TRSW_UP1);
1236 save_regs_phy[1] = b43_phy_read(dev, 1227 save_regs_phy[3] = b43_phy_read(dev,
1237 B43_NPHY_RFCTL_LUT_TRSW_UP2); 1228 B43_NPHY_RFCTL_LUT_TRSW_UP2);
1238 save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
1239 save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
1240 save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1); 1229 save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1);
1241 save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); 1230 save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
1242 save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0); 1231 save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0);
@@ -1285,12 +1274,12 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
1285 b43_phy_write(dev, B43_NPHY_GPIO_SEL, save_regs_phy[8]); 1274 b43_phy_write(dev, B43_NPHY_GPIO_SEL, save_regs_phy[8]);
1286 1275
1287 if (dev->phy.rev >= 3) { 1276 if (dev->phy.rev >= 3) {
1277 b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]);
1278 b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]);
1288 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 1279 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1,
1289 save_regs_phy[0]); 1280 save_regs_phy[2]);
1290 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 1281 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2,
1291 save_regs_phy[1]); 1282 save_regs_phy[3]);
1292 b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[2]);
1293 b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[3]);
1294 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, save_regs_phy[4]); 1283 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, save_regs_phy[4]);
1295 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]); 1284 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]);
1296 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]); 1285 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]);
@@ -1308,6 +1297,186 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
1308 return out; 1297 return out;
1309} 1298}
1310 1299
1300/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
1301static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
1302{
1303 struct b43_phy_n *nphy = dev->phy.n;
1304
1305 u16 saved_regs_phy_rfctl[2];
1306 u16 saved_regs_phy[13];
1307 u16 regs_to_store[] = {
1308 B43_NPHY_AFECTL_OVER1, B43_NPHY_AFECTL_OVER,
1309 B43_NPHY_AFECTL_C1, B43_NPHY_AFECTL_C2,
1310 B43_NPHY_TXF_40CO_B1S1, B43_NPHY_RFCTL_OVER,
1311 B43_NPHY_TXF_40CO_B1S0, B43_NPHY_TXF_40CO_B32S1,
1312 B43_NPHY_RFCTL_CMD,
1313 B43_NPHY_RFCTL_LUT_TRSW_UP1, B43_NPHY_RFCTL_LUT_TRSW_UP2,
1314 B43_NPHY_RFCTL_RSSIO1, B43_NPHY_RFCTL_RSSIO2
1315 };
1316
1317 u16 class;
1318
1319 u16 clip_state[2];
1320 u16 clip_off[2] = { 0xFFFF, 0xFFFF };
1321
1322 u8 vcm_final = 0;
1323 s8 offset[4];
1324 s32 results[8][4] = { };
1325 s32 results_min[4] = { };
1326 s32 poll_results[4] = { };
1327
1328 u16 *rssical_radio_regs = NULL;
1329 u16 *rssical_phy_regs = NULL;
1330
1331 u16 r; /* routing */
1332 u8 rx_core_state;
1333 u8 core, i, j;
1334
1335 class = b43_nphy_classifier(dev, 0, 0);
1336 b43_nphy_classifier(dev, 7, 4);
1337 b43_nphy_read_clip_detection(dev, clip_state);
1338 b43_nphy_write_clip_detection(dev, clip_off);
1339
1340 saved_regs_phy_rfctl[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
1341 saved_regs_phy_rfctl[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
1342 for (i = 0; i < ARRAY_SIZE(regs_to_store); i++)
1343 saved_regs_phy[i] = b43_phy_read(dev, regs_to_store[i]);
1344
1345 b43_nphy_rf_control_intc_override(dev, 0, 0, 7);
1346 b43_nphy_rf_control_intc_override(dev, 1, 1, 7);
1347 b43_nphy_rf_control_override(dev, 0x1, 0, 0, false);
1348 b43_nphy_rf_control_override(dev, 0x2, 1, 0, false);
1349 b43_nphy_rf_control_override(dev, 0x80, 1, 0, false);
1350 b43_nphy_rf_control_override(dev, 0x40, 1, 0, false);
1351
1352 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
1353 b43_nphy_rf_control_override(dev, 0x20, 0, 0, false);
1354 b43_nphy_rf_control_override(dev, 0x10, 1, 0, false);
1355 } else {
1356 b43_nphy_rf_control_override(dev, 0x10, 0, 0, false);
1357 b43_nphy_rf_control_override(dev, 0x20, 1, 0, false);
1358 }
1359
1360 rx_core_state = b43_nphy_get_rx_core_state(dev);
1361 for (core = 0; core < 2; core++) {
1362 if (!(rx_core_state & (1 << core)))
1363 continue;
1364 r = core ? B2056_RX1 : B2056_RX0;
1365 b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 0, 2);
1366 b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 1, 2);
1367 for (i = 0; i < 8; i++) {
1368 b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3,
1369 i << 2);
1370 b43_nphy_poll_rssi(dev, 2, results[i], 8);
1371 }
1372 for (i = 0; i < 4; i++) {
1373 s32 curr;
1374 s32 mind = 40;
1375 s32 minpoll = 249;
1376 u8 minvcm = 0;
1377 if (2 * core != i)
1378 continue;
1379 for (j = 0; j < 8; j++) {
1380 curr = results[j][i] * results[j][i] +
1381 results[j][i + 1] * results[j][i];
1382 if (curr < mind) {
1383 mind = curr;
1384 minvcm = j;
1385 }
1386 if (results[j][i] < minpoll)
1387 minpoll = results[j][i];
1388 }
1389 vcm_final = minvcm;
1390 results_min[i] = minpoll;
1391 }
1392 b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3,
1393 vcm_final << 2);
1394 for (i = 0; i < 4; i++) {
1395 if (core != i / 2)
1396 continue;
1397 offset[i] = -results[vcm_final][i];
1398 if (offset[i] < 0)
1399 offset[i] = -((abs(offset[i]) + 4) / 8);
1400 else
1401 offset[i] = (offset[i] + 4) / 8;
1402 if (results_min[i] == 248)
1403 offset[i] = -32;
1404 b43_nphy_scale_offset_rssi(dev, 0, offset[i],
1405 (i / 2 == 0) ? 1 : 2,
1406 (i % 2 == 0) ? 0 : 1,
1407 2);
1408 }
1409 }
1410 for (core = 0; core < 2; core++) {
1411 if (!(rx_core_state & (1 << core)))
1412 continue;
1413 for (i = 0; i < 2; i++) {
1414 b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 0, i);
1415 b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 1, i);
1416 b43_nphy_poll_rssi(dev, i, poll_results, 8);
1417 for (j = 0; j < 4; j++) {
1418 if (j / 2 == core)
1419 offset[j] = 232 - poll_results[j];
1420 if (offset[j] < 0)
1421 offset[j] = -(abs(offset[j] + 4) / 8);
1422 else
1423 offset[j] = (offset[j] + 4) / 8;
1424 b43_nphy_scale_offset_rssi(dev, 0,
1425 offset[2 * core], core + 1, j % 2, i);
1426 }
1427 }
1428 }
1429
1430 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, saved_regs_phy_rfctl[0]);
1431 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, saved_regs_phy_rfctl[1]);
1432
1433 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
1434
1435 b43_phy_set(dev, B43_NPHY_TXF_40CO_B1S1, 0x1);
1436 b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_START);
1437 b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1, ~0x1);
1438
1439 b43_phy_set(dev, B43_NPHY_RFCTL_OVER, 0x1);
1440 b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_RXTX);
1441 b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1, ~0x1);
1442
1443 for (i = 0; i < ARRAY_SIZE(regs_to_store); i++)
1444 b43_phy_write(dev, regs_to_store[i], saved_regs_phy[i]);
1445
1446 /* Store for future configuration */
1447 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
1448 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G;
1449 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G;
1450 } else {
1451 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G;
1452 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
1453 }
1454 rssical_radio_regs[0] = b43_radio_read(dev, 0x602B);
1455 rssical_radio_regs[0] = b43_radio_read(dev, 0x702B);
1456 rssical_phy_regs[0] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_Z);
1457 rssical_phy_regs[1] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z);
1458 rssical_phy_regs[2] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_Z);
1459 rssical_phy_regs[3] = b43_phy_read(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z);
1460 rssical_phy_regs[4] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_X);
1461 rssical_phy_regs[5] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_X);
1462 rssical_phy_regs[6] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_X);
1463 rssical_phy_regs[7] = b43_phy_read(dev, B43_NPHY_RSSIMC_1Q_RSSI_X);
1464 rssical_phy_regs[8] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_Y);
1465 rssical_phy_regs[9] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y);
1466 rssical_phy_regs[10] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_Y);
1467 rssical_phy_regs[11] = b43_phy_read(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y);
1468
1469 /* Remember for which channel we store configuration */
1470 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
1471 nphy->rssical_chanspec_2G.center_freq = dev->phy.channel_freq;
1472 else
1473 nphy->rssical_chanspec_5G.center_freq = dev->phy.channel_freq;
1474
1475 /* End of calibration, restore configuration */
1476 b43_nphy_classifier(dev, 7, class);
1477 b43_nphy_write_clip_detection(dev, clip_state);
1478}
1479
1311/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */ 1480/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */
1312static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) 1481static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
1313{ 1482{
@@ -1472,12 +1641,6 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
1472 b43_nphy_reset_cca(dev); 1641 b43_nphy_reset_cca(dev);
1473} 1642}
1474 1643
1475/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
1476static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
1477{
1478 /* TODO */
1479}
1480
1481/* 1644/*
1482 * RSSI Calibration 1645 * RSSI Calibration
1483 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal 1646 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal
@@ -2229,27 +2392,12 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
2229 */ 2392 */
2230 2393
2231 for (i = 0; i < 2; i++) { 2394 for (i = 0; i < 2; i++) {
2232 if (dev->phy.rev >= 3) { 2395 txgain = *(b43_nphy_get_tx_gain_table(dev) + txpi[i]);
2233 if (b43_nphy_ipa(dev)) { 2396
2234 txgain = *(b43_nphy_get_ipa_gain_table(dev) + 2397 if (dev->phy.rev >= 3)
2235 txpi[i]);
2236 } else if (b43_current_band(dev->wl) ==
2237 IEEE80211_BAND_5GHZ) {
2238 /* FIXME: use 5GHz tables */
2239 txgain =
2240 b43_ntab_tx_gain_rev3plus_2ghz[txpi[i]];
2241 } else {
2242 if (dev->phy.rev >= 5 &&
2243 sprom->fem.ghz5.extpa_gain == 3)
2244 ; /* FIXME: 5GHz_txgain_HiPwrEPA */
2245 txgain =
2246 b43_ntab_tx_gain_rev3plus_2ghz[txpi[i]];
2247 }
2248 radio_gain = (txgain >> 16) & 0x1FFFF; 2398 radio_gain = (txgain >> 16) & 0x1FFFF;
2249 } else { 2399 else
2250 txgain = b43_ntab_tx_gain_rev0_1_2[txpi[i]];
2251 radio_gain = (txgain >> 16) & 0x1FFF; 2400 radio_gain = (txgain >> 16) & 0x1FFF;
2252 }
2253 2401
2254 if (dev->phy.rev >= 7) 2402 if (dev->phy.rev >= 7)
2255 dac_gain = (txgain >> 8) & 0x7; 2403 dac_gain = (txgain >> 8) & 0x7;
@@ -2420,55 +2568,252 @@ static void b43_nphy_tx_power_ctl_idle_tssi(struct b43_wldev *dev)
2420 nphy->pwr_ctl_info[1].idle_tssi_2g = (tmp >> 8) & 0xFF; 2568 nphy->pwr_ctl_info[1].idle_tssi_2g = (tmp >> 8) & 0xFF;
2421} 2569}
2422 2570
2423static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev) 2571/* http://bcm-v4.sipsolutions.net/PHY/N/TxPwrLimitToTbl */
2572static void b43_nphy_tx_prepare_adjusted_power_table(struct b43_wldev *dev)
2424{ 2573{
2425 struct b43_phy *phy = &dev->phy; 2574 struct b43_phy_n *nphy = dev->phy.n;
2426 2575
2427 const u32 *table = NULL; 2576 u8 idx, delta;
2428#if 0 2577 u8 i, stf_mode;
2429 TODO: b43_ntab_papd_pga_gain_delta_ipa_2*
2430 u32 rfpwr_offset;
2431 u8 pga_gain;
2432 int i;
2433#endif
2434 2578
2435 if (phy->rev >= 3) { 2579 for (i = 0; i < 4; i++)
2436 if (b43_nphy_ipa(dev)) { 2580 nphy->adj_pwr_tbl[i] = nphy->tx_power_offset[i];
2437 table = b43_nphy_get_ipa_gain_table(dev); 2581
2582 for (stf_mode = 0; stf_mode < 4; stf_mode++) {
2583 delta = 0;
2584 switch (stf_mode) {
2585 case 0:
2586 if (dev->phy.is_40mhz && dev->phy.rev >= 5) {
2587 idx = 68;
2588 } else {
2589 delta = 1;
2590 idx = dev->phy.is_40mhz ? 52 : 4;
2591 }
2592 break;
2593 case 1:
2594 idx = dev->phy.is_40mhz ? 76 : 28;
2595 break;
2596 case 2:
2597 idx = dev->phy.is_40mhz ? 84 : 36;
2598 break;
2599 case 3:
2600 idx = dev->phy.is_40mhz ? 92 : 44;
2601 break;
2602 }
2603
2604 for (i = 0; i < 20; i++) {
2605 nphy->adj_pwr_tbl[4 + 4 * i + stf_mode] =
2606 nphy->tx_power_offset[idx];
2607 if (i == 0)
2608 idx += delta;
2609 if (i == 14)
2610 idx += 1 - delta;
2611 if (i == 3 || i == 4 || i == 7 || i == 8 || i == 11 ||
2612 i == 13)
2613 idx += 1;
2614 }
2615 }
2616}
2617
2618/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlSetup */
2619static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev)
2620{
2621 struct b43_phy_n *nphy = dev->phy.n;
2622 struct ssb_sprom *sprom = dev->dev->bus_sprom;
2623
2624 s16 a1[2], b0[2], b1[2];
2625 u8 idle[2];
2626 s8 target[2];
2627 s32 num, den, pwr;
2628 u32 regval[64];
2629
2630 u16 freq = dev->phy.channel_freq;
2631 u16 tmp;
2632 u16 r; /* routing */
2633 u8 i, c;
2634
2635 if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) {
2636 b43_maskset32(dev, B43_MMIO_MACCTL, ~0, 0x200000);
2637 b43_read32(dev, B43_MMIO_MACCTL);
2638 udelay(1);
2639 }
2640
2641 if (nphy->hang_avoid)
2642 b43_nphy_stay_in_carrier_search(dev, true);
2643
2644 b43_phy_set(dev, B43_NPHY_TSSIMODE, B43_NPHY_TSSIMODE_EN);
2645 if (dev->phy.rev >= 3)
2646 b43_phy_mask(dev, B43_NPHY_TXPCTL_CMD,
2647 ~B43_NPHY_TXPCTL_CMD_PCTLEN & 0xFFFF);
2648 else
2649 b43_phy_set(dev, B43_NPHY_TXPCTL_CMD,
2650 B43_NPHY_TXPCTL_CMD_PCTLEN);
2651
2652 if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12)
2653 b43_maskset32(dev, B43_MMIO_MACCTL, ~0x200000, 0);
2654
2655 if (sprom->revision < 4) {
2656 idle[0] = nphy->pwr_ctl_info[0].idle_tssi_2g;
2657 idle[1] = nphy->pwr_ctl_info[1].idle_tssi_2g;
2658 target[0] = target[1] = 52;
2659 a1[0] = a1[1] = -424;
2660 b0[0] = b0[1] = 5612;
2661 b1[0] = b1[1] = -1393;
2662 } else {
2663 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2664 for (c = 0; c < 2; c++) {
2665 idle[c] = nphy->pwr_ctl_info[c].idle_tssi_2g;
2666 target[c] = sprom->core_pwr_info[c].maxpwr_2g;
2667 a1[c] = sprom->core_pwr_info[c].pa_2g[0];
2668 b0[c] = sprom->core_pwr_info[c].pa_2g[1];
2669 b1[c] = sprom->core_pwr_info[c].pa_2g[2];
2670 }
2671 } else if (freq >= 4900 && freq < 5100) {
2672 for (c = 0; c < 2; c++) {
2673 idle[c] = nphy->pwr_ctl_info[c].idle_tssi_5g;
2674 target[c] = sprom->core_pwr_info[c].maxpwr_5gl;
2675 a1[c] = sprom->core_pwr_info[c].pa_5gl[0];
2676 b0[c] = sprom->core_pwr_info[c].pa_5gl[1];
2677 b1[c] = sprom->core_pwr_info[c].pa_5gl[2];
2678 }
2679 } else if (freq >= 5100 && freq < 5500) {
2680 for (c = 0; c < 2; c++) {
2681 idle[c] = nphy->pwr_ctl_info[c].idle_tssi_5g;
2682 target[c] = sprom->core_pwr_info[c].maxpwr_5g;
2683 a1[c] = sprom->core_pwr_info[c].pa_5g[0];
2684 b0[c] = sprom->core_pwr_info[c].pa_5g[1];
2685 b1[c] = sprom->core_pwr_info[c].pa_5g[2];
2686 }
2687 } else if (freq >= 5500) {
2688 for (c = 0; c < 2; c++) {
2689 idle[c] = nphy->pwr_ctl_info[c].idle_tssi_5g;
2690 target[c] = sprom->core_pwr_info[c].maxpwr_5gh;
2691 a1[c] = sprom->core_pwr_info[c].pa_5gh[0];
2692 b0[c] = sprom->core_pwr_info[c].pa_5gh[1];
2693 b1[c] = sprom->core_pwr_info[c].pa_5gh[2];
2694 }
2438 } else { 2695 } else {
2439 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { 2696 idle[0] = nphy->pwr_ctl_info[0].idle_tssi_5g;
2440 if (phy->rev == 3) 2697 idle[1] = nphy->pwr_ctl_info[1].idle_tssi_5g;
2441 table = b43_ntab_tx_gain_rev3_5ghz; 2698 target[0] = target[1] = 52;
2442 if (phy->rev == 4) 2699 a1[0] = a1[1] = -424;
2443 table = b43_ntab_tx_gain_rev4_5ghz; 2700 b0[0] = b0[1] = 5612;
2444 else 2701 b1[0] = b1[1] = -1393;
2445 table = b43_ntab_tx_gain_rev5plus_5ghz; 2702 }
2703 }
2704 /* target[0] = target[1] = nphy->tx_power_max; */
2705
2706 if (dev->phy.rev >= 3) {
2707 if (sprom->fem.ghz2.tssipos)
2708 b43_phy_set(dev, B43_NPHY_TXPCTL_ITSSI, 0x4000);
2709 if (dev->phy.rev >= 7) {
2710 for (c = 0; c < 2; c++) {
2711 r = c ? 0x190 : 0x170;
2712 if (b43_nphy_ipa(dev))
2713 b43_radio_write(dev, r + 0x9, (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) ? 0xE : 0xC);
2714 }
2715 } else {
2716 if (b43_nphy_ipa(dev)) {
2717 tmp = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? 0xC : 0xE;
2718 b43_radio_write(dev,
2719 B2056_TX0 | B2056_TX_TX_SSI_MUX, tmp);
2720 b43_radio_write(dev,
2721 B2056_TX1 | B2056_TX_TX_SSI_MUX, tmp);
2446 } else { 2722 } else {
2447 table = b43_ntab_tx_gain_rev3plus_2ghz; 2723 b43_radio_write(dev,
2724 B2056_TX0 | B2056_TX_TX_SSI_MUX, 0x11);
2725 b43_radio_write(dev,
2726 B2056_TX1 | B2056_TX_TX_SSI_MUX, 0x11);
2448 } 2727 }
2449 } 2728 }
2729 }
2730
2731 if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) {
2732 b43_maskset32(dev, B43_MMIO_MACCTL, ~0, 0x200000);
2733 b43_read32(dev, B43_MMIO_MACCTL);
2734 udelay(1);
2735 }
2736
2737 if (dev->phy.rev >= 7) {
2738 b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
2739 ~B43_NPHY_TXPCTL_CMD_INIT, 0x19);
2740 b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT,
2741 ~B43_NPHY_TXPCTL_INIT_PIDXI1, 0x19);
2450 } else { 2742 } else {
2451 table = b43_ntab_tx_gain_rev0_1_2; 2743 b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
2744 ~B43_NPHY_TXPCTL_CMD_INIT, 0x40);
2745 if (dev->phy.rev > 1)
2746 b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT,
2747 ~B43_NPHY_TXPCTL_INIT_PIDXI1, 0x40);
2748 }
2749
2750 if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12)
2751 b43_maskset32(dev, B43_MMIO_MACCTL, ~0x200000, 0);
2752
2753 b43_phy_write(dev, B43_NPHY_TXPCTL_N,
2754 0xF0 << B43_NPHY_TXPCTL_N_TSSID_SHIFT |
2755 3 << B43_NPHY_TXPCTL_N_NPTIL2_SHIFT);
2756 b43_phy_write(dev, B43_NPHY_TXPCTL_ITSSI,
2757 idle[0] << B43_NPHY_TXPCTL_ITSSI_0_SHIFT |
2758 idle[1] << B43_NPHY_TXPCTL_ITSSI_1_SHIFT |
2759 B43_NPHY_TXPCTL_ITSSI_BINF);
2760 b43_phy_write(dev, B43_NPHY_TXPCTL_TPWR,
2761 target[0] << B43_NPHY_TXPCTL_TPWR_0_SHIFT |
2762 target[1] << B43_NPHY_TXPCTL_TPWR_1_SHIFT);
2763
2764 for (c = 0; c < 2; c++) {
2765 for (i = 0; i < 64; i++) {
2766 num = 8 * (16 * b0[c] + b1[c] * i);
2767 den = 32768 + a1[c] * i;
2768 pwr = max((4 * num + den / 2) / den, -8);
2769 if (dev->phy.rev < 3 && (i <= (31 - idle[c] + 1)))
2770 pwr = max(pwr, target[c] + 1);
2771 regval[i] = pwr;
2772 }
2773 b43_ntab_write_bulk(dev, B43_NTAB32(26 + c, 0), 64, regval);
2452 } 2774 }
2775
2776 b43_nphy_tx_prepare_adjusted_power_table(dev);
2777 /*
2778 b43_ntab_write_bulk(dev, B43_NTAB16(26, 64), 84, nphy->adj_pwr_tbl);
2779 b43_ntab_write_bulk(dev, B43_NTAB16(27, 64), 84, nphy->adj_pwr_tbl);
2780 */
2781
2782 if (nphy->hang_avoid)
2783 b43_nphy_stay_in_carrier_search(dev, false);
2784}
2785
2786static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev)
2787{
2788 struct b43_phy *phy = &dev->phy;
2789
2790 const u32 *table = NULL;
2791 u32 rfpwr_offset;
2792 u8 pga_gain;
2793 int i;
2794
2795 table = b43_nphy_get_tx_gain_table(dev);
2453 b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, table); 2796 b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, table);
2454 b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, table); 2797 b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, table);
2455 2798
2456 if (phy->rev >= 3) { 2799 if (phy->rev >= 3) {
2457#if 0 2800#if 0
2458 nphy->gmval = (table[0] >> 16) & 0x7000; 2801 nphy->gmval = (table[0] >> 16) & 0x7000;
2802#endif
2459 2803
2460 for (i = 0; i < 128; i++) { 2804 for (i = 0; i < 128; i++) {
2461 pga_gain = (table[i] >> 24) & 0xF; 2805 pga_gain = (table[i] >> 24) & 0xF;
2462 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) 2806 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
2463 rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain]; 2807 rfpwr_offset =
2808 b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain];
2464 else 2809 else
2465 rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_5g[pga_gain]; 2810 rfpwr_offset =
2811 0; /* FIXME */
2466 b43_ntab_write(dev, B43_NTAB32(26, 576 + i), 2812 b43_ntab_write(dev, B43_NTAB32(26, 576 + i),
2467 rfpwr_offset); 2813 rfpwr_offset);
2468 b43_ntab_write(dev, B43_NTAB32(27, 576 + i), 2814 b43_ntab_write(dev, B43_NTAB32(27, 576 + i),
2469 rfpwr_offset); 2815 rfpwr_offset);
2470 } 2816 }
2471#endif
2472 } 2817 }
2473} 2818}
2474 2819
@@ -3139,32 +3484,13 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
3139 B43_NPHY_TXPCTL_STAT_BIDX_SHIFT; 3484 B43_NPHY_TXPCTL_STAT_BIDX_SHIFT;
3140 3485
3141 for (i = 0; i < 2; ++i) { 3486 for (i = 0; i < 2; ++i) {
3487 table = b43_nphy_get_tx_gain_table(dev);
3142 if (dev->phy.rev >= 3) { 3488 if (dev->phy.rev >= 3) {
3143 enum ieee80211_band band =
3144 b43_current_band(dev->wl);
3145
3146 if (b43_nphy_ipa(dev)) {
3147 table = b43_nphy_get_ipa_gain_table(dev);
3148 } else {
3149 if (band == IEEE80211_BAND_5GHZ) {
3150 if (dev->phy.rev == 3)
3151 table = b43_ntab_tx_gain_rev3_5ghz;
3152 else if (dev->phy.rev == 4)
3153 table = b43_ntab_tx_gain_rev4_5ghz;
3154 else
3155 table = b43_ntab_tx_gain_rev5plus_5ghz;
3156 } else {
3157 table = b43_ntab_tx_gain_rev3plus_2ghz;
3158 }
3159 }
3160
3161 target.ipa[i] = (table[index[i]] >> 16) & 0xF; 3489 target.ipa[i] = (table[index[i]] >> 16) & 0xF;
3162 target.pad[i] = (table[index[i]] >> 20) & 0xF; 3490 target.pad[i] = (table[index[i]] >> 20) & 0xF;
3163 target.pga[i] = (table[index[i]] >> 24) & 0xF; 3491 target.pga[i] = (table[index[i]] >> 24) & 0xF;
3164 target.txgm[i] = (table[index[i]] >> 28) & 0xF; 3492 target.txgm[i] = (table[index[i]] >> 28) & 0xF;
3165 } else { 3493 } else {
3166 table = b43_ntab_tx_gain_rev0_1_2;
3167
3168 target.ipa[i] = (table[index[i]] >> 16) & 0x3; 3494 target.ipa[i] = (table[index[i]] >> 16) & 0x3;
3169 target.pad[i] = (table[index[i]] >> 18) & 0x3; 3495 target.pad[i] = (table[index[i]] >> 18) & 0x3;
3170 target.pga[i] = (table[index[i]] >> 20) & 0x7; 3496 target.pga[i] = (table[index[i]] >> 20) & 0x7;
@@ -3968,13 +4294,10 @@ static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init)
3968#endif 4294#endif
3969 } 4295 }
3970 4296
3971 b43_write32(dev, B43_MMIO_MACCTL, 4297 b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0);
3972 b43_read32(dev, B43_MMIO_MACCTL) & 4298 b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, 0xFC00);
3973 ~B43_MACCTL_GPOUTSMSK); 4299 b43_maskset16(dev, B43_MMIO_GPIO_CONTROL, (~0xFC00 & 0xFFFF),
3974 b43_write16(dev, B43_MMIO_GPIO_MASK, 4300 0);
3975 b43_read16(dev, B43_MMIO_GPIO_MASK) | 0xFC00);
3976 b43_write16(dev, B43_MMIO_GPIO_CONTROL,
3977 b43_read16(dev, B43_MMIO_GPIO_CONTROL) & ~0xFC00);
3978 4301
3979 if (init) { 4302 if (init) {
3980 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); 4303 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
@@ -4110,7 +4433,7 @@ int b43_phy_initn(struct b43_wldev *dev)
4110 b43_nphy_tx_power_ctrl(dev, false); 4433 b43_nphy_tx_power_ctrl(dev, false);
4111 b43_nphy_tx_power_fix(dev); 4434 b43_nphy_tx_power_fix(dev);
4112 b43_nphy_tx_power_ctl_idle_tssi(dev); 4435 b43_nphy_tx_power_ctl_idle_tssi(dev);
4113 /* TODO N PHY TX Power Control Setup */ 4436 b43_nphy_tx_power_ctl_setup(dev);
4114 b43_nphy_tx_gain_table_upload(dev); 4437 b43_nphy_tx_gain_table_upload(dev);
4115 4438
4116 if (nphy->phyrxchain != 3) 4439 if (nphy->phyrxchain != 3)
@@ -4530,8 +4853,7 @@ static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
4530{ 4853{
4531 check_phyreg(dev, reg); 4854 check_phyreg(dev, reg);
4532 b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); 4855 b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
4533 b43_write16(dev, B43_MMIO_PHY_DATA, 4856 b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set);
4534 (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
4535} 4857}
4536 4858
4537static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg) 4859static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)