aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2011-12-17 07:57:25 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-12-19 14:40:49 -0500
commit5ecab603c75efafaa2604725efe0afc3da4bd55b (patch)
treeaef8288287bf3cf1ca8a203cff9feae57396ee51 /drivers/net/wireless/b43
parent647120956e4e9a2151c42f4d3eead20c7f7be869 (diff)
b43: N-PHY: reorder functions: move RSSI calibration
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> Acked-by: Larry Finger <Larry.Finger@lwfinger.net> 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.c600
1 files changed, 300 insertions, 300 deletions
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 620d278c59c2..f027909a4b34 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -1193,6 +1193,306 @@ static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
1193 b43_nphy_rev2_rssi_select(dev, code, type); 1193 b43_nphy_rev2_rssi_select(dev, code, type);
1194} 1194}
1195 1195
1196/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */
1197static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, u8 type, u8 *buf)
1198{
1199 int i;
1200 for (i = 0; i < 2; i++) {
1201 if (type == 2) {
1202 if (i == 0) {
1203 b43_radio_maskset(dev, B2055_C1_B0NB_RSSIVCM,
1204 0xFC, buf[0]);
1205 b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5,
1206 0xFC, buf[1]);
1207 } else {
1208 b43_radio_maskset(dev, B2055_C2_B0NB_RSSIVCM,
1209 0xFC, buf[2 * i]);
1210 b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5,
1211 0xFC, buf[2 * i + 1]);
1212 }
1213 } else {
1214 if (i == 0)
1215 b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5,
1216 0xF3, buf[0] << 2);
1217 else
1218 b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5,
1219 0xF3, buf[2 * i + 1] << 2);
1220 }
1221 }
1222}
1223
1224/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PollRssi */
1225static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
1226 u8 nsamp)
1227{
1228 int i;
1229 int out;
1230 u16 save_regs_phy[9];
1231 u16 s[2];
1232
1233 if (dev->phy.rev >= 3) {
1234 save_regs_phy[0] = b43_phy_read(dev,
1235 B43_NPHY_RFCTL_LUT_TRSW_UP1);
1236 save_regs_phy[1] = b43_phy_read(dev,
1237 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);
1241 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);
1243 save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1);
1244 save_regs_phy[8] = 0;
1245 } else {
1246 save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
1247 save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
1248 save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
1249 save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_RFCTL_CMD);
1250 save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER);
1251 save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1);
1252 save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2);
1253 save_regs_phy[7] = 0;
1254 save_regs_phy[8] = 0;
1255 }
1256
1257 b43_nphy_rssi_select(dev, 5, type);
1258
1259 if (dev->phy.rev < 2) {
1260 save_regs_phy[8] = b43_phy_read(dev, B43_NPHY_GPIO_SEL);
1261 b43_phy_write(dev, B43_NPHY_GPIO_SEL, 5);
1262 }
1263
1264 for (i = 0; i < 4; i++)
1265 buf[i] = 0;
1266
1267 for (i = 0; i < nsamp; i++) {
1268 if (dev->phy.rev < 2) {
1269 s[0] = b43_phy_read(dev, B43_NPHY_GPIO_LOOUT);
1270 s[1] = b43_phy_read(dev, B43_NPHY_GPIO_HIOUT);
1271 } else {
1272 s[0] = b43_phy_read(dev, B43_NPHY_RSSI1);
1273 s[1] = b43_phy_read(dev, B43_NPHY_RSSI2);
1274 }
1275
1276 buf[0] += ((s8)((s[0] & 0x3F) << 2)) >> 2;
1277 buf[1] += ((s8)(((s[0] >> 8) & 0x3F) << 2)) >> 2;
1278 buf[2] += ((s8)((s[1] & 0x3F) << 2)) >> 2;
1279 buf[3] += ((s8)(((s[1] >> 8) & 0x3F) << 2)) >> 2;
1280 }
1281 out = (buf[0] & 0xFF) << 24 | (buf[1] & 0xFF) << 16 |
1282 (buf[2] & 0xFF) << 8 | (buf[3] & 0xFF);
1283
1284 if (dev->phy.rev < 2)
1285 b43_phy_write(dev, B43_NPHY_GPIO_SEL, save_regs_phy[8]);
1286
1287 if (dev->phy.rev >= 3) {
1288 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1,
1289 save_regs_phy[0]);
1290 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2,
1291 save_regs_phy[1]);
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]);
1295 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]);
1297 b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, save_regs_phy[7]);
1298 } else {
1299 b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]);
1300 b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]);
1301 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[2]);
1302 b43_phy_write(dev, B43_NPHY_RFCTL_CMD, save_regs_phy[3]);
1303 b43_phy_write(dev, B43_NPHY_RFCTL_OVER, save_regs_phy[4]);
1304 b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO1, save_regs_phy[5]);
1305 b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO2, save_regs_phy[6]);
1306 }
1307
1308 return out;
1309}
1310
1311/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */
1312static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
1313{
1314 int i, j;
1315 u8 state[4];
1316 u8 code, val;
1317 u16 class, override;
1318 u8 regs_save_radio[2];
1319 u16 regs_save_phy[2];
1320
1321 s8 offset[4];
1322 u8 core;
1323 u8 rail;
1324
1325 u16 clip_state[2];
1326 u16 clip_off[2] = { 0xFFFF, 0xFFFF };
1327 s32 results_min[4] = { };
1328 u8 vcm_final[4] = { };
1329 s32 results[4][4] = { };
1330 s32 miniq[4][2] = { };
1331
1332 if (type == 2) {
1333 code = 0;
1334 val = 6;
1335 } else if (type < 2) {
1336 code = 25;
1337 val = 4;
1338 } else {
1339 B43_WARN_ON(1);
1340 return;
1341 }
1342
1343 class = b43_nphy_classifier(dev, 0, 0);
1344 b43_nphy_classifier(dev, 7, 4);
1345 b43_nphy_read_clip_detection(dev, clip_state);
1346 b43_nphy_write_clip_detection(dev, clip_off);
1347
1348 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
1349 override = 0x140;
1350 else
1351 override = 0x110;
1352
1353 regs_save_phy[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
1354 regs_save_radio[0] = b43_radio_read16(dev, B2055_C1_PD_RXTX);
1355 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, override);
1356 b43_radio_write16(dev, B2055_C1_PD_RXTX, val);
1357
1358 regs_save_phy[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
1359 regs_save_radio[1] = b43_radio_read16(dev, B2055_C2_PD_RXTX);
1360 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, override);
1361 b43_radio_write16(dev, B2055_C2_PD_RXTX, val);
1362
1363 state[0] = b43_radio_read16(dev, B2055_C1_PD_RSSIMISC) & 0x07;
1364 state[1] = b43_radio_read16(dev, B2055_C2_PD_RSSIMISC) & 0x07;
1365 b43_radio_mask(dev, B2055_C1_PD_RSSIMISC, 0xF8);
1366 b43_radio_mask(dev, B2055_C2_PD_RSSIMISC, 0xF8);
1367 state[2] = b43_radio_read16(dev, B2055_C1_SP_RSSI) & 0x07;
1368 state[3] = b43_radio_read16(dev, B2055_C2_SP_RSSI) & 0x07;
1369
1370 b43_nphy_rssi_select(dev, 5, type);
1371 b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 0, type);
1372 b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 1, type);
1373
1374 for (i = 0; i < 4; i++) {
1375 u8 tmp[4];
1376 for (j = 0; j < 4; j++)
1377 tmp[j] = i;
1378 if (type != 1)
1379 b43_nphy_set_rssi_2055_vcm(dev, type, tmp);
1380 b43_nphy_poll_rssi(dev, type, results[i], 8);
1381 if (type < 2)
1382 for (j = 0; j < 2; j++)
1383 miniq[i][j] = min(results[i][2 * j],
1384 results[i][2 * j + 1]);
1385 }
1386
1387 for (i = 0; i < 4; i++) {
1388 s32 mind = 40;
1389 u8 minvcm = 0;
1390 s32 minpoll = 249;
1391 s32 curr;
1392 for (j = 0; j < 4; j++) {
1393 if (type == 2)
1394 curr = abs(results[j][i]);
1395 else
1396 curr = abs(miniq[j][i / 2] - code * 8);
1397
1398 if (curr < mind) {
1399 mind = curr;
1400 minvcm = j;
1401 }
1402
1403 if (results[j][i] < minpoll)
1404 minpoll = results[j][i];
1405 }
1406 results_min[i] = minpoll;
1407 vcm_final[i] = minvcm;
1408 }
1409
1410 if (type != 1)
1411 b43_nphy_set_rssi_2055_vcm(dev, type, vcm_final);
1412
1413 for (i = 0; i < 4; i++) {
1414 offset[i] = (code * 8) - results[vcm_final[i]][i];
1415
1416 if (offset[i] < 0)
1417 offset[i] = -((abs(offset[i]) + 4) / 8);
1418 else
1419 offset[i] = (offset[i] + 4) / 8;
1420
1421 if (results_min[i] == 248)
1422 offset[i] = code - 32;
1423
1424 core = (i / 2) ? 2 : 1;
1425 rail = (i % 2) ? 1 : 0;
1426
1427 b43_nphy_scale_offset_rssi(dev, 0, offset[i], core, rail,
1428 type);
1429 }
1430
1431 b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[0]);
1432 b43_radio_maskset(dev, B2055_C2_PD_RSSIMISC, 0xF8, state[1]);
1433
1434 switch (state[2]) {
1435 case 1:
1436 b43_nphy_rssi_select(dev, 1, 2);
1437 break;
1438 case 4:
1439 b43_nphy_rssi_select(dev, 1, 0);
1440 break;
1441 case 2:
1442 b43_nphy_rssi_select(dev, 1, 1);
1443 break;
1444 default:
1445 b43_nphy_rssi_select(dev, 1, 1);
1446 break;
1447 }
1448
1449 switch (state[3]) {
1450 case 1:
1451 b43_nphy_rssi_select(dev, 2, 2);
1452 break;
1453 case 4:
1454 b43_nphy_rssi_select(dev, 2, 0);
1455 break;
1456 default:
1457 b43_nphy_rssi_select(dev, 2, 1);
1458 break;
1459 }
1460
1461 b43_nphy_rssi_select(dev, 0, type);
1462
1463 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs_save_phy[0]);
1464 b43_radio_write16(dev, B2055_C1_PD_RXTX, regs_save_radio[0]);
1465 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs_save_phy[1]);
1466 b43_radio_write16(dev, B2055_C2_PD_RXTX, regs_save_radio[1]);
1467
1468 b43_nphy_classifier(dev, 7, class);
1469 b43_nphy_write_clip_detection(dev, clip_state);
1470 /* Specs don't say about reset here, but it makes wl and b43 dumps
1471 identical, it really seems wl performs this */
1472 b43_nphy_reset_cca(dev);
1473}
1474
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/*
1482 * RSSI Calibration
1483 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal
1484 */
1485static void b43_nphy_rssi_cal(struct b43_wldev *dev)
1486{
1487 if (dev->phy.rev >= 3) {
1488 b43_nphy_rev3_rssi_cal(dev);
1489 } else {
1490 b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Z);
1491 b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_X);
1492 b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Y);
1493 }
1494}
1495
1196/************************************************** 1496/**************************************************
1197 * Workarounds 1497 * Workarounds
1198 **************************************************/ 1498 **************************************************/
@@ -2539,306 +2839,6 @@ static void b43_nphy_bphy_init(struct b43_wldev *dev)
2539 b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668); 2839 b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668);
2540} 2840}
2541 2841
2542/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */
2543static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, u8 type, u8 *buf)
2544{
2545 int i;
2546 for (i = 0; i < 2; i++) {
2547 if (type == 2) {
2548 if (i == 0) {
2549 b43_radio_maskset(dev, B2055_C1_B0NB_RSSIVCM,
2550 0xFC, buf[0]);
2551 b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5,
2552 0xFC, buf[1]);
2553 } else {
2554 b43_radio_maskset(dev, B2055_C2_B0NB_RSSIVCM,
2555 0xFC, buf[2 * i]);
2556 b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5,
2557 0xFC, buf[2 * i + 1]);
2558 }
2559 } else {
2560 if (i == 0)
2561 b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5,
2562 0xF3, buf[0] << 2);
2563 else
2564 b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5,
2565 0xF3, buf[2 * i + 1] << 2);
2566 }
2567 }
2568}
2569
2570/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PollRssi */
2571static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
2572 u8 nsamp)
2573{
2574 int i;
2575 int out;
2576 u16 save_regs_phy[9];
2577 u16 s[2];
2578
2579 if (dev->phy.rev >= 3) {
2580 save_regs_phy[0] = b43_phy_read(dev,
2581 B43_NPHY_RFCTL_LUT_TRSW_UP1);
2582 save_regs_phy[1] = b43_phy_read(dev,
2583 B43_NPHY_RFCTL_LUT_TRSW_UP2);
2584 save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
2585 save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
2586 save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1);
2587 save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
2588 save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0);
2589 save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1);
2590 save_regs_phy[8] = 0;
2591 } else {
2592 save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
2593 save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
2594 save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
2595 save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_RFCTL_CMD);
2596 save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER);
2597 save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1);
2598 save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2);
2599 save_regs_phy[7] = 0;
2600 save_regs_phy[8] = 0;
2601 }
2602
2603 b43_nphy_rssi_select(dev, 5, type);
2604
2605 if (dev->phy.rev < 2) {
2606 save_regs_phy[8] = b43_phy_read(dev, B43_NPHY_GPIO_SEL);
2607 b43_phy_write(dev, B43_NPHY_GPIO_SEL, 5);
2608 }
2609
2610 for (i = 0; i < 4; i++)
2611 buf[i] = 0;
2612
2613 for (i = 0; i < nsamp; i++) {
2614 if (dev->phy.rev < 2) {
2615 s[0] = b43_phy_read(dev, B43_NPHY_GPIO_LOOUT);
2616 s[1] = b43_phy_read(dev, B43_NPHY_GPIO_HIOUT);
2617 } else {
2618 s[0] = b43_phy_read(dev, B43_NPHY_RSSI1);
2619 s[1] = b43_phy_read(dev, B43_NPHY_RSSI2);
2620 }
2621
2622 buf[0] += ((s8)((s[0] & 0x3F) << 2)) >> 2;
2623 buf[1] += ((s8)(((s[0] >> 8) & 0x3F) << 2)) >> 2;
2624 buf[2] += ((s8)((s[1] & 0x3F) << 2)) >> 2;
2625 buf[3] += ((s8)(((s[1] >> 8) & 0x3F) << 2)) >> 2;
2626 }
2627 out = (buf[0] & 0xFF) << 24 | (buf[1] & 0xFF) << 16 |
2628 (buf[2] & 0xFF) << 8 | (buf[3] & 0xFF);
2629
2630 if (dev->phy.rev < 2)
2631 b43_phy_write(dev, B43_NPHY_GPIO_SEL, save_regs_phy[8]);
2632
2633 if (dev->phy.rev >= 3) {
2634 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1,
2635 save_regs_phy[0]);
2636 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2,
2637 save_regs_phy[1]);
2638 b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[2]);
2639 b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[3]);
2640 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, save_regs_phy[4]);
2641 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]);
2642 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]);
2643 b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, save_regs_phy[7]);
2644 } else {
2645 b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]);
2646 b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]);
2647 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[2]);
2648 b43_phy_write(dev, B43_NPHY_RFCTL_CMD, save_regs_phy[3]);
2649 b43_phy_write(dev, B43_NPHY_RFCTL_OVER, save_regs_phy[4]);
2650 b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO1, save_regs_phy[5]);
2651 b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO2, save_regs_phy[6]);
2652 }
2653
2654 return out;
2655}
2656
2657/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */
2658static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
2659{
2660 int i, j;
2661 u8 state[4];
2662 u8 code, val;
2663 u16 class, override;
2664 u8 regs_save_radio[2];
2665 u16 regs_save_phy[2];
2666
2667 s8 offset[4];
2668 u8 core;
2669 u8 rail;
2670
2671 u16 clip_state[2];
2672 u16 clip_off[2] = { 0xFFFF, 0xFFFF };
2673 s32 results_min[4] = { };
2674 u8 vcm_final[4] = { };
2675 s32 results[4][4] = { };
2676 s32 miniq[4][2] = { };
2677
2678 if (type == 2) {
2679 code = 0;
2680 val = 6;
2681 } else if (type < 2) {
2682 code = 25;
2683 val = 4;
2684 } else {
2685 B43_WARN_ON(1);
2686 return;
2687 }
2688
2689 class = b43_nphy_classifier(dev, 0, 0);
2690 b43_nphy_classifier(dev, 7, 4);
2691 b43_nphy_read_clip_detection(dev, clip_state);
2692 b43_nphy_write_clip_detection(dev, clip_off);
2693
2694 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
2695 override = 0x140;
2696 else
2697 override = 0x110;
2698
2699 regs_save_phy[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
2700 regs_save_radio[0] = b43_radio_read16(dev, B2055_C1_PD_RXTX);
2701 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, override);
2702 b43_radio_write16(dev, B2055_C1_PD_RXTX, val);
2703
2704 regs_save_phy[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
2705 regs_save_radio[1] = b43_radio_read16(dev, B2055_C2_PD_RXTX);
2706 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, override);
2707 b43_radio_write16(dev, B2055_C2_PD_RXTX, val);
2708
2709 state[0] = b43_radio_read16(dev, B2055_C1_PD_RSSIMISC) & 0x07;
2710 state[1] = b43_radio_read16(dev, B2055_C2_PD_RSSIMISC) & 0x07;
2711 b43_radio_mask(dev, B2055_C1_PD_RSSIMISC, 0xF8);
2712 b43_radio_mask(dev, B2055_C2_PD_RSSIMISC, 0xF8);
2713 state[2] = b43_radio_read16(dev, B2055_C1_SP_RSSI) & 0x07;
2714 state[3] = b43_radio_read16(dev, B2055_C2_SP_RSSI) & 0x07;
2715
2716 b43_nphy_rssi_select(dev, 5, type);
2717 b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 0, type);
2718 b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 1, type);
2719
2720 for (i = 0; i < 4; i++) {
2721 u8 tmp[4];
2722 for (j = 0; j < 4; j++)
2723 tmp[j] = i;
2724 if (type != 1)
2725 b43_nphy_set_rssi_2055_vcm(dev, type, tmp);
2726 b43_nphy_poll_rssi(dev, type, results[i], 8);
2727 if (type < 2)
2728 for (j = 0; j < 2; j++)
2729 miniq[i][j] = min(results[i][2 * j],
2730 results[i][2 * j + 1]);
2731 }
2732
2733 for (i = 0; i < 4; i++) {
2734 s32 mind = 40;
2735 u8 minvcm = 0;
2736 s32 minpoll = 249;
2737 s32 curr;
2738 for (j = 0; j < 4; j++) {
2739 if (type == 2)
2740 curr = abs(results[j][i]);
2741 else
2742 curr = abs(miniq[j][i / 2] - code * 8);
2743
2744 if (curr < mind) {
2745 mind = curr;
2746 minvcm = j;
2747 }
2748
2749 if (results[j][i] < minpoll)
2750 minpoll = results[j][i];
2751 }
2752 results_min[i] = minpoll;
2753 vcm_final[i] = minvcm;
2754 }
2755
2756 if (type != 1)
2757 b43_nphy_set_rssi_2055_vcm(dev, type, vcm_final);
2758
2759 for (i = 0; i < 4; i++) {
2760 offset[i] = (code * 8) - results[vcm_final[i]][i];
2761
2762 if (offset[i] < 0)
2763 offset[i] = -((abs(offset[i]) + 4) / 8);
2764 else
2765 offset[i] = (offset[i] + 4) / 8;
2766
2767 if (results_min[i] == 248)
2768 offset[i] = code - 32;
2769
2770 core = (i / 2) ? 2 : 1;
2771 rail = (i % 2) ? 1 : 0;
2772
2773 b43_nphy_scale_offset_rssi(dev, 0, offset[i], core, rail,
2774 type);
2775 }
2776
2777 b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[0]);
2778 b43_radio_maskset(dev, B2055_C2_PD_RSSIMISC, 0xF8, state[1]);
2779
2780 switch (state[2]) {
2781 case 1:
2782 b43_nphy_rssi_select(dev, 1, 2);
2783 break;
2784 case 4:
2785 b43_nphy_rssi_select(dev, 1, 0);
2786 break;
2787 case 2:
2788 b43_nphy_rssi_select(dev, 1, 1);
2789 break;
2790 default:
2791 b43_nphy_rssi_select(dev, 1, 1);
2792 break;
2793 }
2794
2795 switch (state[3]) {
2796 case 1:
2797 b43_nphy_rssi_select(dev, 2, 2);
2798 break;
2799 case 4:
2800 b43_nphy_rssi_select(dev, 2, 0);
2801 break;
2802 default:
2803 b43_nphy_rssi_select(dev, 2, 1);
2804 break;
2805 }
2806
2807 b43_nphy_rssi_select(dev, 0, type);
2808
2809 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs_save_phy[0]);
2810 b43_radio_write16(dev, B2055_C1_PD_RXTX, regs_save_radio[0]);
2811 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs_save_phy[1]);
2812 b43_radio_write16(dev, B2055_C2_PD_RXTX, regs_save_radio[1]);
2813
2814 b43_nphy_classifier(dev, 7, class);
2815 b43_nphy_write_clip_detection(dev, clip_state);
2816 /* Specs don't say about reset here, but it makes wl and b43 dumps
2817 identical, it really seems wl performs this */
2818 b43_nphy_reset_cca(dev);
2819}
2820
2821/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
2822static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
2823{
2824 /* TODO */
2825}
2826
2827/*
2828 * RSSI Calibration
2829 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal
2830 */
2831static void b43_nphy_rssi_cal(struct b43_wldev *dev)
2832{
2833 if (dev->phy.rev >= 3) {
2834 b43_nphy_rev3_rssi_cal(dev);
2835 } else {
2836 b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Z);
2837 b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_X);
2838 b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Y);
2839 }
2840}
2841
2842/* 2842/*
2843 * Restore RSSI Calibration 2843 * Restore RSSI Calibration
2844 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreRssiCal 2844 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreRssiCal