aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211
diff options
context:
space:
mode:
authorPiotr Haber <phaber@broadcom.com>2012-11-28 15:44:10 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-11-30 14:00:22 -0500
commitb6fc28a158076ca2764edc9a6d1e1402f56e1c0c (patch)
treebc16f0e7ad7a595cb5ea34bcee491b25fd593565 /drivers/net/wireless/brcm80211
parentb83576341664957978e125f5f5db2f15496980b1 (diff)
brcmsmac: support 4313iPA
Add support for 4313 iPA variant. It is a variant of already supported 4313 ePA and needs some PHY changes to work properly. Reviewed-by: Arend Van Spriel <arend@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Reviewed-by: Hante Meuleman <meuleman@broadcom.com> Signed-off-by: Piotr Haber <phaber@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/brcm80211')
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c369
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c64
2 files changed, 271 insertions, 162 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
index 18d37645e2cd..606b534347bc 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
@@ -1137,8 +1137,9 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
1137 gain0_15 = ((biq1 & 0xf) << 12) | 1137 gain0_15 = ((biq1 & 0xf) << 12) |
1138 ((tia & 0xf) << 8) | 1138 ((tia & 0xf) << 8) |
1139 ((lna2 & 0x3) << 6) | 1139 ((lna2 & 0x3) << 6) |
1140 ((lna2 & 1140 ((lna2 & 0x3) << 4) |
1141 0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0); 1141 ((lna1 & 0x3) << 2) |
1142 ((lna1 & 0x3) << 0);
1142 1143
1143 mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0); 1144 mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
1144 mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0); 1145 mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
@@ -1156,6 +1157,8 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
1156 } 1157 }
1157 1158
1158 mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0); 1159 mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0);
1160 mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
1161 mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3);
1159 1162
1160} 1163}
1161 1164
@@ -1328,6 +1331,43 @@ static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples)
1328 return (iq_est.i_pwr + iq_est.q_pwr) / nsamples; 1331 return (iq_est.i_pwr + iq_est.q_pwr) / nsamples;
1329} 1332}
1330 1333
1334static bool wlc_lcnphy_rx_iq_cal_gain(struct brcms_phy *pi, u16 biq1_gain,
1335 u16 tia_gain, u16 lna2_gain)
1336{
1337 u32 i_thresh_l, q_thresh_l;
1338 u32 i_thresh_h, q_thresh_h;
1339 struct lcnphy_iq_est iq_est_h, iq_est_l;
1340
1341 wlc_lcnphy_set_rx_gain_by_distribution(pi, 0, 0, 0, biq1_gain, tia_gain,
1342 lna2_gain, 0);
1343
1344 wlc_lcnphy_rx_gain_override_enable(pi, true);
1345 wlc_lcnphy_start_tx_tone(pi, 2000, (40 >> 1), 0);
1346 usleep_range(500, 500);
1347 write_radio_reg(pi, RADIO_2064_REG112, 0);
1348 if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_l))
1349 return false;
1350
1351 wlc_lcnphy_start_tx_tone(pi, 2000, 40, 0);
1352 usleep_range(500, 500);
1353 write_radio_reg(pi, RADIO_2064_REG112, 0);
1354 if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_h))
1355 return false;
1356
1357 i_thresh_l = (iq_est_l.i_pwr << 1);
1358 i_thresh_h = (iq_est_l.i_pwr << 2) + iq_est_l.i_pwr;
1359
1360 q_thresh_l = (iq_est_l.q_pwr << 1);
1361 q_thresh_h = (iq_est_l.q_pwr << 2) + iq_est_l.q_pwr;
1362 if ((iq_est_h.i_pwr > i_thresh_l) &&
1363 (iq_est_h.i_pwr < i_thresh_h) &&
1364 (iq_est_h.q_pwr > q_thresh_l) &&
1365 (iq_est_h.q_pwr < q_thresh_h))
1366 return true;
1367
1368 return false;
1369}
1370
1331static bool 1371static bool
1332wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi, 1372wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
1333 const struct lcnphy_rx_iqcomp *iqcomp, 1373 const struct lcnphy_rx_iqcomp *iqcomp,
@@ -1342,8 +1382,8 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
1342 RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old, 1382 RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old,
1343 rfoverride3_old, rfoverride3val_old, rfoverride4_old, 1383 rfoverride3_old, rfoverride3val_old, rfoverride4_old,
1344 rfoverride4val_old, afectrlovr_old, afectrlovrval_old; 1384 rfoverride4val_old, afectrlovr_old, afectrlovrval_old;
1345 int tia_gain; 1385 int tia_gain, lna2_gain, biq1_gain;
1346 u32 received_power, rx_pwr_threshold; 1386 bool set_gain;
1347 u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl; 1387 u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl;
1348 u16 values_to_save[11]; 1388 u16 values_to_save[11];
1349 s16 *ptr; 1389 s16 *ptr;
@@ -1368,126 +1408,134 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
1368 goto cal_done; 1408 goto cal_done;
1369 } 1409 }
1370 1410
1371 if (module == 1) { 1411 WARN_ON(module != 1);
1412 tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
1413 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
1372 1414
1373 tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); 1415 for (i = 0; i < 11; i++)
1374 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); 1416 values_to_save[i] =
1417 read_radio_reg(pi, rxiq_cal_rf_reg[i]);
1418 Core1TxControl_old = read_phy_reg(pi, 0x631);
1419
1420 or_phy_reg(pi, 0x631, 0x0015);
1421
1422 RFOverride0_old = read_phy_reg(pi, 0x44c);
1423 RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
1424 rfoverride2_old = read_phy_reg(pi, 0x4b0);
1425 rfoverride2val_old = read_phy_reg(pi, 0x4b1);
1426 rfoverride3_old = read_phy_reg(pi, 0x4f9);
1427 rfoverride3val_old = read_phy_reg(pi, 0x4fa);
1428 rfoverride4_old = read_phy_reg(pi, 0x938);
1429 rfoverride4val_old = read_phy_reg(pi, 0x939);
1430 afectrlovr_old = read_phy_reg(pi, 0x43b);
1431 afectrlovrval_old = read_phy_reg(pi, 0x43c);
1432 old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
1433 old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
1375 1434
1376 for (i = 0; i < 11; i++) 1435 tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
1377 values_to_save[i] = 1436 if (tx_gain_override_old) {
1378 read_radio_reg(pi, rxiq_cal_rf_reg[i]); 1437 wlc_lcnphy_get_tx_gain(pi, &old_gains);
1379 Core1TxControl_old = read_phy_reg(pi, 0x631); 1438 tx_gain_index_old = pi_lcn->lcnphy_current_index;
1380 1439 }
1381 or_phy_reg(pi, 0x631, 0x0015);
1382
1383 RFOverride0_old = read_phy_reg(pi, 0x44c);
1384 RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
1385 rfoverride2_old = read_phy_reg(pi, 0x4b0);
1386 rfoverride2val_old = read_phy_reg(pi, 0x4b1);
1387 rfoverride3_old = read_phy_reg(pi, 0x4f9);
1388 rfoverride3val_old = read_phy_reg(pi, 0x4fa);
1389 rfoverride4_old = read_phy_reg(pi, 0x938);
1390 rfoverride4val_old = read_phy_reg(pi, 0x939);
1391 afectrlovr_old = read_phy_reg(pi, 0x43b);
1392 afectrlovrval_old = read_phy_reg(pi, 0x43c);
1393 old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
1394 old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
1395
1396 tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
1397 if (tx_gain_override_old) {
1398 wlc_lcnphy_get_tx_gain(pi, &old_gains);
1399 tx_gain_index_old = pi_lcn->lcnphy_current_index;
1400 }
1401 1440
1402 wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx); 1441 wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
1403 1442
1404 mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0); 1443 mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
1405 mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0); 1444 mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
1406 1445
1407 mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1); 1446 mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
1408 mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1); 1447 mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
1409 1448
1410 write_radio_reg(pi, RADIO_2064_REG116, 0x06); 1449 write_radio_reg(pi, RADIO_2064_REG116, 0x06);
1411 write_radio_reg(pi, RADIO_2064_REG12C, 0x07); 1450 write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
1412 write_radio_reg(pi, RADIO_2064_REG06A, 0xd3); 1451 write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
1413 write_radio_reg(pi, RADIO_2064_REG098, 0x03); 1452 write_radio_reg(pi, RADIO_2064_REG098, 0x03);
1414 write_radio_reg(pi, RADIO_2064_REG00B, 0x7); 1453 write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
1415 mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4); 1454 mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
1416 write_radio_reg(pi, RADIO_2064_REG01D, 0x01); 1455 write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
1417 write_radio_reg(pi, RADIO_2064_REG114, 0x01); 1456 write_radio_reg(pi, RADIO_2064_REG114, 0x01);
1418 write_radio_reg(pi, RADIO_2064_REG02E, 0x10); 1457 write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
1419 write_radio_reg(pi, RADIO_2064_REG12A, 0x08); 1458 write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
1420 1459
1421 mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0); 1460 mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
1422 mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0); 1461 mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
1423 mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1); 1462 mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
1424 mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1); 1463 mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
1425 mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2); 1464 mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
1426 mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2); 1465 mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
1427 mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3); 1466 mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
1428 mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3); 1467 mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
1429 mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5); 1468 mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
1430 mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5); 1469 mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
1431
1432 mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
1433 mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
1434
1435 wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0);
1436 write_phy_reg(pi, 0x6da, 0xffff);
1437 or_phy_reg(pi, 0x6db, 0x3);
1438 wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
1439 wlc_lcnphy_rx_gain_override_enable(pi, true);
1440
1441 tia_gain = 8;
1442 rx_pwr_threshold = 950;
1443 while (tia_gain > 0) {
1444 tia_gain -= 1;
1445 wlc_lcnphy_set_rx_gain_by_distribution(pi,
1446 0, 0, 2, 2,
1447 (u16)
1448 tia_gain, 1, 0);
1449 udelay(500);
1450 1470
1451 received_power = 1471 mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
1452 wlc_lcnphy_measure_digital_power(pi, 2000); 1472 mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
1453 if (received_power < rx_pwr_threshold) 1473
1454 break; 1474 write_phy_reg(pi, 0x6da, 0xffff);
1475 or_phy_reg(pi, 0x6db, 0x3);
1476
1477 wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
1478 set_gain = false;
1479
1480 lna2_gain = 3;
1481 while ((lna2_gain >= 0) && !set_gain) {
1482 tia_gain = 4;
1483
1484 while ((tia_gain >= 0) && !set_gain) {
1485 biq1_gain = 6;
1486
1487 while ((biq1_gain >= 0) && !set_gain) {
1488 set_gain = wlc_lcnphy_rx_iq_cal_gain(pi,
1489 (u16)
1490 biq1_gain,
1491 (u16)
1492 tia_gain,
1493 (u16)
1494 lna2_gain);
1495 biq1_gain -= 1;
1496 }
1497 tia_gain -= 1;
1455 } 1498 }
1456 result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff); 1499 lna2_gain -= 1;
1500 }
1457 1501
1458 wlc_lcnphy_stop_tx_tone(pi); 1502 if (set_gain)
1503 result = wlc_lcnphy_calc_rx_iq_comp(pi, 1024);
1504 else
1505 result = false;
1459 1506
1460 write_phy_reg(pi, 0x631, Core1TxControl_old); 1507 wlc_lcnphy_stop_tx_tone(pi);
1461 1508
1462 write_phy_reg(pi, 0x44c, RFOverrideVal0_old); 1509 write_phy_reg(pi, 0x631, Core1TxControl_old);
1463 write_phy_reg(pi, 0x44d, RFOverrideVal0_old); 1510
1464 write_phy_reg(pi, 0x4b0, rfoverride2_old); 1511 write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
1465 write_phy_reg(pi, 0x4b1, rfoverride2val_old); 1512 write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
1466 write_phy_reg(pi, 0x4f9, rfoverride3_old); 1513 write_phy_reg(pi, 0x4b0, rfoverride2_old);
1467 write_phy_reg(pi, 0x4fa, rfoverride3val_old); 1514 write_phy_reg(pi, 0x4b1, rfoverride2val_old);
1468 write_phy_reg(pi, 0x938, rfoverride4_old); 1515 write_phy_reg(pi, 0x4f9, rfoverride3_old);
1469 write_phy_reg(pi, 0x939, rfoverride4val_old); 1516 write_phy_reg(pi, 0x4fa, rfoverride3val_old);
1470 write_phy_reg(pi, 0x43b, afectrlovr_old); 1517 write_phy_reg(pi, 0x938, rfoverride4_old);
1471 write_phy_reg(pi, 0x43c, afectrlovrval_old); 1518 write_phy_reg(pi, 0x939, rfoverride4val_old);
1472 write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl); 1519 write_phy_reg(pi, 0x43b, afectrlovr_old);
1473 write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl); 1520 write_phy_reg(pi, 0x43c, afectrlovrval_old);
1521 write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
1522 write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
1474 1523
1475 wlc_lcnphy_clear_trsw_override(pi); 1524 wlc_lcnphy_clear_trsw_override(pi);
1476 1525
1477 mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2); 1526 mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
1478 1527
1479 for (i = 0; i < 11; i++) 1528 for (i = 0; i < 11; i++)
1480 write_radio_reg(pi, rxiq_cal_rf_reg[i], 1529 write_radio_reg(pi, rxiq_cal_rf_reg[i],
1481 values_to_save[i]); 1530 values_to_save[i]);
1482 1531
1483 if (tx_gain_override_old) 1532 if (tx_gain_override_old)
1484 wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old); 1533 wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
1485 else 1534 else
1486 wlc_lcnphy_disable_tx_gain_override(pi); 1535 wlc_lcnphy_disable_tx_gain_override(pi);
1487 1536
1488 wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl); 1537 wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
1489 wlc_lcnphy_rx_gain_override_enable(pi, false); 1538 wlc_lcnphy_rx_gain_override_enable(pi, false);
1490 }
1491 1539
1492cal_done: 1540cal_done:
1493 kfree(ptr); 1541 kfree(ptr);
@@ -1781,6 +1829,17 @@ wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel)
1781 write_radio_reg(pi, RADIO_2064_REG038, 3); 1829 write_radio_reg(pi, RADIO_2064_REG038, 3);
1782 write_radio_reg(pi, RADIO_2064_REG091, 7); 1830 write_radio_reg(pi, RADIO_2064_REG091, 7);
1783 } 1831 }
1832
1833 if (!(pi->sh->boardflags & BFL_FEM)) {
1834 u8 reg038[14] = {0xd, 0xe, 0xd, 0xd, 0xd, 0xc,
1835 0xa, 0xb, 0xb, 0x3, 0x3, 0x2, 0x0, 0x0};
1836
1837 write_radio_reg(pi, RADIO_2064_REG02A, 0xf);
1838 write_radio_reg(pi, RADIO_2064_REG091, 0x3);
1839 write_radio_reg(pi, RADIO_2064_REG038, 0x3);
1840
1841 write_radio_reg(pi, RADIO_2064_REG038, reg038[channel - 1]);
1842 }
1784} 1843}
1785 1844
1786static int 1845static int
@@ -1975,6 +2034,16 @@ wlc_lcnphy_set_tssi_mux(struct brcms_phy *pi, enum lcnphy_tssi_mode pos)
1975 } else { 2034 } else {
1976 mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1); 2035 mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1);
1977 mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8); 2036 mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
2037 mod_radio_reg(pi, RADIO_2064_REG028, 0x1, 0x0);
2038 mod_radio_reg(pi, RADIO_2064_REG11A, 0x4, 1<<2);
2039 mod_radio_reg(pi, RADIO_2064_REG036, 0x10, 0x0);
2040 mod_radio_reg(pi, RADIO_2064_REG11A, 0x10, 1<<4);
2041 mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0);
2042 mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x77);
2043 mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0xe<<1);
2044 mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1<<7);
2045 mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 1<<1);
2046 mod_radio_reg(pi, RADIO_2064_REG029, 0xf0, 0<<4);
1978 } 2047 }
1979 } else { 2048 } else {
1980 mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2); 2049 mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2);
@@ -2061,12 +2130,14 @@ static void wlc_lcnphy_pwrctrl_rssiparams(struct brcms_phy *pi)
2061 (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12)); 2130 (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
2062 2131
2063 mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5)); 2132 mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5));
2133 mod_radio_reg(pi, RADIO_2064_REG07C, (1 << 0), (1 << 0));
2064} 2134}
2065 2135
2066static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi) 2136static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
2067{ 2137{
2068 struct phytbl_info tab; 2138 struct phytbl_info tab;
2069 u32 rfseq, ind; 2139 u32 rfseq, ind;
2140 u8 tssi_sel;
2070 2141
2071 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; 2142 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
2072 tab.tbl_width = 32; 2143 tab.tbl_width = 32;
@@ -2088,7 +2159,13 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
2088 2159
2089 mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4); 2160 mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4);
2090 2161
2091 wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT); 2162 if (pi->sh->boardflags & BFL_FEM) {
2163 tssi_sel = 0x1;
2164 wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
2165 } else {
2166 tssi_sel = 0xe;
2167 wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_POST_PA);
2168 }
2092 mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14); 2169 mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
2093 2170
2094 mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15); 2171 mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15);
@@ -2124,9 +2201,10 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
2124 mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0); 2201 mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0);
2125 2202
2126 if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { 2203 if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
2127 mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe); 2204 mod_radio_reg(pi, RADIO_2064_REG028, 0xf, tssi_sel);
2128 mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4); 2205 mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
2129 } else { 2206 } else {
2207 mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, tssi_sel << 1);
2130 mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1); 2208 mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
2131 mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3); 2209 mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3);
2132 } 2210 }
@@ -2173,6 +2251,10 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
2173 2251
2174 mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8); 2252 mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8);
2175 2253
2254 mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x0);
2255 mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0);
2256 mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
2257
2176 wlc_lcnphy_pwrctrl_rssiparams(pi); 2258 wlc_lcnphy_pwrctrl_rssiparams(pi);
2177} 2259}
2178 2260
@@ -2791,6 +2873,8 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
2791 read_radio_reg(pi, RADIO_2064_REG007) & 1; 2873 read_radio_reg(pi, RADIO_2064_REG007) & 1;
2792 u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10; 2874 u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10;
2793 u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4; 2875 u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4;
2876 u8 SAVE_bbmult = wlc_lcnphy_get_bbmult(pi);
2877
2794 idleTssi = read_phy_reg(pi, 0x4ab); 2878 idleTssi = read_phy_reg(pi, 0x4ab);
2795 suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) & 2879 suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
2796 MCTL_EN_MAC)); 2880 MCTL_EN_MAC));
@@ -2808,6 +2892,12 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
2808 mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4); 2892 mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4);
2809 mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2); 2893 mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2);
2810 wlc_lcnphy_tssi_setup(pi); 2894 wlc_lcnphy_tssi_setup(pi);
2895
2896 mod_phy_reg(pi, 0x4d7, (0x1 << 0), (1 << 0));
2897 mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1 << 6));
2898
2899 wlc_lcnphy_set_bbmult(pi, 0x0);
2900
2811 wlc_phy_do_dummy_tx(pi, true, OFF); 2901 wlc_phy_do_dummy_tx(pi, true, OFF);
2812 idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0)) 2902 idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
2813 >> 0); 2903 >> 0);
@@ -2829,6 +2919,7 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
2829 2919
2830 mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12); 2920 mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12);
2831 2921
2922 wlc_lcnphy_set_bbmult(pi, SAVE_bbmult);
2832 wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old); 2923 wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old);
2833 wlc_lcnphy_set_tx_gain(pi, &old_gains); 2924 wlc_lcnphy_set_tx_gain(pi, &old_gains);
2834 wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl); 2925 wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
@@ -3042,6 +3133,11 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi)
3042 wlc_lcnphy_write_table(pi, &tab); 3133 wlc_lcnphy_write_table(pi, &tab);
3043 tab.tbl_offset++; 3134 tab.tbl_offset++;
3044 } 3135 }
3136 mod_phy_reg(pi, 0x4d0, (0x1 << 0), (0) << 0);
3137 mod_phy_reg(pi, 0x4d3, (0xff << 0), (0) << 0);
3138 mod_phy_reg(pi, 0x4d3, (0xff << 8), (0) << 8);
3139 mod_phy_reg(pi, 0x4d0, (0x1 << 4), (0) << 4);
3140 mod_phy_reg(pi, 0x4d0, (0x1 << 2), (0) << 2);
3045 3141
3046 mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7); 3142 mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7);
3047 3143
@@ -3843,7 +3939,6 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
3843 target_gains.pad_gain = 21; 3939 target_gains.pad_gain = 21;
3844 target_gains.dac_gain = 0; 3940 target_gains.dac_gain = 0;
3845 wlc_lcnphy_set_tx_gain(pi, &target_gains); 3941 wlc_lcnphy_set_tx_gain(pi, &target_gains);
3846 wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
3847 3942
3848 if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) { 3943 if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) {
3849 3944
@@ -3854,6 +3949,7 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
3854 lcnphy_recal ? LCNPHY_CAL_RECAL : 3949 lcnphy_recal ? LCNPHY_CAL_RECAL :
3855 LCNPHY_CAL_FULL), false); 3950 LCNPHY_CAL_FULL), false);
3856 } else { 3951 } else {
3952 wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
3857 wlc_lcnphy_tx_iqlo_soft_cal_full(pi); 3953 wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
3858 } 3954 }
3859 3955
@@ -4278,17 +4374,22 @@ wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi,
4278 if (CHSPEC_IS5G(pi->radio_chanspec)) 4374 if (CHSPEC_IS5G(pi->radio_chanspec))
4279 pa_gain = 0x70; 4375 pa_gain = 0x70;
4280 else 4376 else
4281 pa_gain = 0x70; 4377 pa_gain = 0x60;
4282 4378
4283 if (pi->sh->boardflags & BFL_FEM) 4379 if (pi->sh->boardflags & BFL_FEM)
4284 pa_gain = 0x10; 4380 pa_gain = 0x10;
4381
4285 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; 4382 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
4286 tab.tbl_width = 32; 4383 tab.tbl_width = 32;
4287 tab.tbl_len = 1; 4384 tab.tbl_len = 1;
4288 tab.tbl_ptr = &val; 4385 tab.tbl_ptr = &val;
4289 4386
4290 for (j = 0; j < 128; j++) { 4387 for (j = 0; j < 128; j++) {
4291 gm_gain = gain_table[j].gm; 4388 if (pi->sh->boardflags & BFL_FEM)
4389 gm_gain = gain_table[j].gm;
4390 else
4391 gm_gain = 15;
4392
4292 val = (((u32) pa_gain << 24) | 4393 val = (((u32) pa_gain << 24) |
4293 (gain_table[j].pad << 16) | 4394 (gain_table[j].pad << 16) |
4294 (gain_table[j].pga << 8) | gm_gain); 4395 (gain_table[j].pga << 8) | gm_gain);
@@ -4499,7 +4600,10 @@ static void wlc_radio_2064_init(struct brcms_phy *pi)
4499 4600
4500 write_phy_reg(pi, 0x4ea, 0x4688); 4601 write_phy_reg(pi, 0x4ea, 0x4688);
4501 4602
4502 mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0); 4603 if (pi->sh->boardflags & BFL_FEM)
4604 mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
4605 else
4606 mod_phy_reg(pi, 0x4eb, (0x7 << 0), 3 << 0);
4503 4607
4504 mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6); 4608 mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6);
4505 4609
@@ -4510,6 +4614,13 @@ static void wlc_radio_2064_init(struct brcms_phy *pi)
4510 wlc_lcnphy_rcal(pi); 4614 wlc_lcnphy_rcal(pi);
4511 4615
4512 wlc_lcnphy_rc_cal(pi); 4616 wlc_lcnphy_rc_cal(pi);
4617
4618 if (!(pi->sh->boardflags & BFL_FEM)) {
4619 write_radio_reg(pi, RADIO_2064_REG032, 0x6f);
4620 write_radio_reg(pi, RADIO_2064_REG033, 0x19);
4621 write_radio_reg(pi, RADIO_2064_REG039, 0xe);
4622 }
4623
4513} 4624}
4514 4625
4515static void wlc_lcnphy_radio_init(struct brcms_phy *pi) 4626static void wlc_lcnphy_radio_init(struct brcms_phy *pi)
@@ -4539,22 +4650,20 @@ static void wlc_lcnphy_tbl_init(struct brcms_phy *pi)
4539 wlc_lcnphy_write_table(pi, &tab); 4650 wlc_lcnphy_write_table(pi, &tab);
4540 } 4651 }
4541 4652
4542 tab.tbl_id = LCNPHY_TBL_ID_RFSEQ; 4653 if (!(pi->sh->boardflags & BFL_FEM)) {
4543 tab.tbl_width = 16; 4654 tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
4544 tab.tbl_ptr = &val; 4655 tab.tbl_width = 16;
4545 tab.tbl_len = 1; 4656 tab.tbl_ptr = &val;
4546 4657 tab.tbl_len = 1;
4547 val = 114;
4548 tab.tbl_offset = 0;
4549 wlc_lcnphy_write_table(pi, &tab);
4550 4658
4551 val = 130; 4659 val = 150;
4552 tab.tbl_offset = 1; 4660 tab.tbl_offset = 0;
4553 wlc_lcnphy_write_table(pi, &tab); 4661 wlc_lcnphy_write_table(pi, &tab);
4554 4662
4555 val = 6; 4663 val = 220;
4556 tab.tbl_offset = 8; 4664 tab.tbl_offset = 1;
4557 wlc_lcnphy_write_table(pi, &tab); 4665 wlc_lcnphy_write_table(pi, &tab);
4666 }
4558 4667
4559 if (CHSPEC_IS2G(pi->radio_chanspec)) { 4668 if (CHSPEC_IS2G(pi->radio_chanspec)) {
4560 if (pi->sh->boardflags & BFL_FEM) 4669 if (pi->sh->boardflags & BFL_FEM)
@@ -4946,6 +5055,7 @@ void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec)
4946 wlc_lcnphy_load_tx_iir_filter(pi, true, 3); 5055 wlc_lcnphy_load_tx_iir_filter(pi, true, 3);
4947 5056
4948 mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3); 5057 mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
5058 wlc_lcnphy_tssi_setup(pi);
4949} 5059}
4950 5060
4951void wlc_phy_detach_lcnphy(struct brcms_phy *pi) 5061void wlc_phy_detach_lcnphy(struct brcms_phy *pi)
@@ -4984,8 +5094,7 @@ bool wlc_phy_attach_lcnphy(struct brcms_phy *pi)
4984 if (!wlc_phy_txpwr_srom_read_lcnphy(pi)) 5094 if (!wlc_phy_txpwr_srom_read_lcnphy(pi))
4985 return false; 5095 return false;
4986 5096
4987 if ((pi->sh->boardflags & BFL_FEM) && 5097 if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
4988 (LCNREV_IS(pi->pubpi.phy_rev, 1))) {
4989 if (pi_lcn->lcnphy_tempsense_option == 3) { 5098 if (pi_lcn->lcnphy_tempsense_option == 3) {
4990 pi->hwpwrctrl = true; 5099 pi->hwpwrctrl = true;
4991 pi->hwpwrctrl_capable = true; 5100 pi->hwpwrctrl_capable = true;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
index 622c01ca72c5..b7e95acc2084 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
@@ -1992,70 +1992,70 @@ static const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = {
1992}; 1992};
1993 1993
1994static const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = { 1994static const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = {
1995 0x000a,
1996 0x0009, 1995 0x0009,
1997 0x0006,
1998 0x0005,
1999 0x000a, 1996 0x000a,
2000 0x0009,
2001 0x0006,
2002 0x0005, 1997 0x0005,
2003 0x000a,
2004 0x0009,
2005 0x0006, 1998 0x0006,
2006 0x0005,
2007 0x000a,
2008 0x0009, 1999 0x0009,
2009 0x0006,
2010 0x0005,
2011 0x000a, 2000 0x000a,
2012 0x0009,
2013 0x0006,
2014 0x0005, 2001 0x0005,
2015 0x000a,
2016 0x0009,
2017 0x0006, 2002 0x0006,
2018 0x0005,
2019 0x000a,
2020 0x0009, 2003 0x0009,
2021 0x0006,
2022 0x0005,
2023 0x000a, 2004 0x000a,
2024 0x0009,
2025 0x0006,
2026 0x0005, 2005 0x0005,
2027 0x000a,
2028 0x0009,
2029 0x0006, 2006 0x0006,
2030 0x0005,
2031 0x000a,
2032 0x0009, 2007 0x0009,
2033 0x0006,
2034 0x0005,
2035 0x000a, 2008 0x000a,
2036 0x0009,
2037 0x0006,
2038 0x0005, 2009 0x0005,
2039 0x000a,
2040 0x0009,
2041 0x0006, 2010 0x0006,
2042 0x0005, 2011 0x0009,
2043 0x000a, 2012 0x000a,
2013 0x0005,
2014 0x0006,
2044 0x0009, 2015 0x0009,
2016 0x000a,
2017 0x0005,
2045 0x0006, 2018 0x0006,
2019 0x0009,
2020 0x000a,
2046 0x0005, 2021 0x0005,
2022 0x0006,
2023 0x0009,
2047 0x000a, 2024 0x000a,
2025 0x0005,
2026 0x0006,
2048 0x0009, 2027 0x0009,
2028 0x000a,
2029 0x0005,
2049 0x0006, 2030 0x0006,
2031 0x0009,
2032 0x000a,
2050 0x0005, 2033 0x0005,
2034 0x0006,
2035 0x0009,
2051 0x000a, 2036 0x000a,
2037 0x0005,
2038 0x0006,
2052 0x0009, 2039 0x0009,
2040 0x000a,
2041 0x0005,
2053 0x0006, 2042 0x0006,
2043 0x0009,
2044 0x000a,
2054 0x0005, 2045 0x0005,
2046 0x0006,
2047 0x0009,
2055 0x000a, 2048 0x000a,
2049 0x0005,
2050 0x0006,
2056 0x0009, 2051 0x0009,
2052 0x000a,
2053 0x0005,
2057 0x0006, 2054 0x0006,
2055 0x0009,
2056 0x000a,
2058 0x0005, 2057 0x0005,
2058 0x0006,
2059}; 2059};
2060 2060
2061static const u16 dot11lcn_sw_ctrl_tbl_rev0[] = { 2061static const u16 dot11lcn_sw_ctrl_tbl_rev0[] = {