aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2012-01-04 19:05:30 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-01-24 14:06:06 -0500
commite0c9a0219a8f542e3946fe972a68aacf8c3f906c (patch)
tree37382a9122e5ed5b48029e2ced3a34dfd78df23b /drivers/net/wireless/b43
parent3eb1fa7e0021bc03be1bf7f68b1913d959e29512 (diff)
b43: N-PHY: implement RSSI calibration for rev3+
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43')
-rw-r--r--drivers/net/wireless/b43/phy_n.c193
1 files changed, 187 insertions, 6 deletions
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index f6ac18139b10..945aa5267d09 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -85,6 +85,13 @@ 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/RxCoreGetState */
89static u8 b43_nphy_get_rx_core_state(struct b43_wldev *dev)
90{
91 return (b43_phy_read(dev, B43_NPHY_RFSEQCA) & B43_NPHY_RFSEQCA_RXEN) >>
92 B43_NPHY_RFSEQCA_RXEN_SHIFT;
93}
94
88/************************************************** 95/**************************************************
89 * RF (just without b43_nphy_rf_control_intc_override) 96 * RF (just without b43_nphy_rf_control_intc_override)
90 **************************************************/ 97 **************************************************/
@@ -1290,6 +1297,186 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
1290 return out; 1297 return out;
1291} 1298}
1292 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
1293/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */ 1480/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */
1294static 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)
1295{ 1482{
@@ -1454,12 +1641,6 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
1454 b43_nphy_reset_cca(dev); 1641 b43_nphy_reset_cca(dev);
1455} 1642}
1456 1643
1457/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
1458static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
1459{
1460 /* TODO */
1461}
1462
1463/* 1644/*
1464 * RSSI Calibration 1645 * RSSI Calibration
1465 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal 1646 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal