aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorGábor Stefanik <netrolller.3d@gmail.com>2009-10-25 11:26:36 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-10-30 16:49:18 -0400
commit2c0d6100da3ee9b0f0cc46add9bb8a8161299a92 (patch)
tree8b7cd7c6cfb7c1370070a3f44f186c02417d9fbd /drivers/net
parent29906f6a427d2004a515ebbcdc7b28bae8f6c19c (diff)
b43: LP-PHY: Begin implementing calibration & software RFKILL support
This implements the following calibration functions: -Set TX IQCC -Set TX Power by Index -PR41573 workaround (incomplete, needs PHY reset) -Calc RX IQ Comp -PHY Cordic -Run Samples -Start/Stop TX Tone -part of PAPD Cal TX Power -RX I/Q Calibration -The basic structure of the periodic calibration wrapper Software RFKILL (required by calibration) is also implemented in this round. Signed-off-by: Gábor Stefanik <netrolller.3d@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/b43/phy_lp.c783
-rw-r--r--drivers/net/wireless/b43/phy_lp.h11
2 files changed, 658 insertions, 136 deletions
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index c6987b147af4..3e046ec1ff86 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -67,6 +67,7 @@ static void b43_lpphy_op_prepare_structs(struct b43_wldev *dev)
67 struct b43_phy_lp *lpphy = phy->lp; 67 struct b43_phy_lp *lpphy = phy->lp;
68 68
69 memset(lpphy, 0, sizeof(*lpphy)); 69 memset(lpphy, 0, sizeof(*lpphy));
70 lpphy->antenna = B43_ANTENNA_DEFAULT;
70 71
71 //TODO 72 //TODO
72} 73}
@@ -379,8 +380,6 @@ static void lpphy_save_dig_flt_state(struct b43_wldev *dev)
379 } 380 }
380} 381}
381 382
382/* lpphy_restore_dig_flt_state is unused but kept as a reference */
383#if 0
384static void lpphy_restore_dig_flt_state(struct b43_wldev *dev) 383static void lpphy_restore_dig_flt_state(struct b43_wldev *dev)
385{ 384{
386 static const u16 addr[] = { 385 static const u16 addr[] = {
@@ -401,7 +400,6 @@ static void lpphy_restore_dig_flt_state(struct b43_wldev *dev)
401 for (i = 0; i < ARRAY_SIZE(addr); i++) 400 for (i = 0; i < ARRAY_SIZE(addr); i++)
402 b43_phy_write(dev, addr[i], lpphy->dig_flt_state[i]); 401 b43_phy_write(dev, addr[i], lpphy->dig_flt_state[i]);
403} 402}
404#endif
405 403
406static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) 404static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
407{ 405{
@@ -754,11 +752,17 @@ static void lpphy_clear_deaf(struct b43_wldev *dev, bool user)
754 } 752 }
755} 753}
756 754
755static void lpphy_set_trsw_over(struct b43_wldev *dev, bool tx, bool rx)
756{
757 u16 trsw = (tx << 1) | rx;
758 b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFC, trsw);
759 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x3);
760}
761
757static void lpphy_disable_crs(struct b43_wldev *dev, bool user) 762static void lpphy_disable_crs(struct b43_wldev *dev, bool user)
758{ 763{
759 lpphy_set_deaf(dev, user); 764 lpphy_set_deaf(dev, user);
760 b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFC, 0x1); 765 lpphy_set_trsw_over(dev, false, true);
761 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x3);
762 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFB); 766 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFB);
763 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x4); 767 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x4);
764 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFF7); 768 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFF7);
@@ -793,6 +797,60 @@ static void lpphy_restore_crs(struct b43_wldev *dev, bool user)
793 797
794struct lpphy_tx_gains { u16 gm, pga, pad, dac; }; 798struct lpphy_tx_gains { u16 gm, pga, pad, dac; };
795 799
800static void lpphy_disable_rx_gain_override(struct b43_wldev *dev)
801{
802 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFFE);
803 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFEF);
804 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFBF);
805 if (dev->phy.rev >= 2) {
806 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF);
807 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
808 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFBFF);
809 b43_phy_mask(dev, B43_PHY_OFDM(0xE5), 0xFFF7);
810 }
811 } else {
812 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFDFF);
813 }
814}
815
816static void lpphy_enable_rx_gain_override(struct b43_wldev *dev)
817{
818 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1);
819 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x10);
820 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x40);
821 if (dev->phy.rev >= 2) {
822 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x100);
823 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
824 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x400);
825 b43_phy_set(dev, B43_PHY_OFDM(0xE5), 0x8);
826 }
827 } else {
828 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x200);
829 }
830}
831
832static void lpphy_disable_tx_gain_override(struct b43_wldev *dev)
833{
834 if (dev->phy.rev < 2)
835 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF);
836 else {
837 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFF7F);
838 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xBFFF);
839 }
840 b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVR, 0xFFBF);
841}
842
843static void lpphy_enable_tx_gain_override(struct b43_wldev *dev)
844{
845 if (dev->phy.rev < 2)
846 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x100);
847 else {
848 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x80);
849 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x4000);
850 }
851 b43_phy_set(dev, B43_LPPHY_AFE_CTL_OVR, 0x40);
852}
853
796static struct lpphy_tx_gains lpphy_get_tx_gains(struct b43_wldev *dev) 854static struct lpphy_tx_gains lpphy_get_tx_gains(struct b43_wldev *dev)
797{ 855{
798 struct lpphy_tx_gains gains; 856 struct lpphy_tx_gains gains;
@@ -822,6 +880,17 @@ static void lpphy_set_dac_gain(struct b43_wldev *dev, u16 dac)
822 b43_phy_maskset(dev, B43_LPPHY_AFE_DAC_CTL, 0xF000, ctl); 880 b43_phy_maskset(dev, B43_LPPHY_AFE_DAC_CTL, 0xF000, ctl);
823} 881}
824 882
883static u16 lpphy_get_pa_gain(struct b43_wldev *dev)
884{
885 return b43_phy_read(dev, B43_PHY_OFDM(0xFB)) & 0x7F;
886}
887
888static void lpphy_set_pa_gain(struct b43_wldev *dev, u16 gain)
889{
890 b43_phy_maskset(dev, B43_PHY_OFDM(0xFB), 0xE03F, gain << 6);
891 b43_phy_maskset(dev, B43_PHY_OFDM(0xFD), 0x80FF, gain << 8);
892}
893
825static void lpphy_set_tx_gains(struct b43_wldev *dev, 894static void lpphy_set_tx_gains(struct b43_wldev *dev,
826 struct lpphy_tx_gains gains) 895 struct lpphy_tx_gains gains)
827{ 896{
@@ -832,25 +901,22 @@ static void lpphy_set_tx_gains(struct b43_wldev *dev,
832 b43_phy_maskset(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL, 901 b43_phy_maskset(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL,
833 0xF800, rf_gain); 902 0xF800, rf_gain);
834 } else { 903 } else {
835 pa_gain = b43_phy_read(dev, B43_PHY_OFDM(0xFB)) & 0x1FC0; 904 pa_gain = lpphy_get_pa_gain(dev);
836 pa_gain <<= 2;
837 b43_phy_write(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL, 905 b43_phy_write(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL,
838 (gains.pga << 8) | gains.gm); 906 (gains.pga << 8) | gains.gm);
907 /*
908 * SPEC FIXME The spec calls for (pa_gain << 8) here, but that
909 * conflicts with the spec for set_pa_gain! Vendor driver bug?
910 */
839 b43_phy_maskset(dev, B43_PHY_OFDM(0xFB), 911 b43_phy_maskset(dev, B43_PHY_OFDM(0xFB),
840 0x8000, gains.pad | pa_gain); 912 0x8000, gains.pad | (pa_gain << 6));
841 b43_phy_write(dev, B43_PHY_OFDM(0xFC), 913 b43_phy_write(dev, B43_PHY_OFDM(0xFC),
842 (gains.pga << 8) | gains.gm); 914 (gains.pga << 8) | gains.gm);
843 b43_phy_maskset(dev, B43_PHY_OFDM(0xFD), 915 b43_phy_maskset(dev, B43_PHY_OFDM(0xFD),
844 0x8000, gains.pad | pa_gain); 916 0x8000, gains.pad | (pa_gain << 8));
845 } 917 }
846 lpphy_set_dac_gain(dev, gains.dac); 918 lpphy_set_dac_gain(dev, gains.dac);
847 if (dev->phy.rev < 2) { 919 lpphy_enable_tx_gain_override(dev);
848 b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF, 1 << 8);
849 } else {
850 b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFF7F, 1 << 7);
851 b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xBFFF, 1 << 14);
852 }
853 b43_phy_maskset(dev, B43_LPPHY_AFE_CTL_OVR, 0xFFBF, 1 << 6);
854} 920}
855 921
856static void lpphy_rev0_1_set_rx_gain(struct b43_wldev *dev, u32 gain) 922static void lpphy_rev0_1_set_rx_gain(struct b43_wldev *dev, u32 gain)
@@ -890,41 +956,6 @@ static void lpphy_rev2plus_set_rx_gain(struct b43_wldev *dev, u32 gain)
890 } 956 }
891} 957}
892 958
893/* lpphy_disable_rx_gain_override is unused but kept as a reference */
894#if 0
895static void lpphy_disable_rx_gain_override(struct b43_wldev *dev)
896{
897 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFFE);
898 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFEF);
899 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFBF);
900 if (dev->phy.rev >= 2) {
901 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF);
902 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
903 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFBFF);
904 b43_phy_mask(dev, B43_PHY_OFDM(0xE5), 0xFFF7);
905 }
906 } else {
907 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFDFF);
908 }
909}
910#endif
911
912static void lpphy_enable_rx_gain_override(struct b43_wldev *dev)
913{
914 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1);
915 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x10);
916 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x40);
917 if (dev->phy.rev >= 2) {
918 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x100);
919 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
920 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x400);
921 b43_phy_set(dev, B43_PHY_OFDM(0xE5), 0x8);
922 }
923 } else {
924 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x200);
925 }
926}
927
928static void lpphy_set_rx_gain(struct b43_wldev *dev, u32 gain) 959static void lpphy_set_rx_gain(struct b43_wldev *dev, u32 gain)
929{ 960{
930 if (dev->phy.rev < 2) 961 if (dev->phy.rev < 2)
@@ -1009,8 +1040,7 @@ static int lpphy_loopback(struct b43_wldev *dev)
1009 1040
1010 memset(&iq_est, 0, sizeof(iq_est)); 1041 memset(&iq_est, 0, sizeof(iq_est));
1011 1042
1012 b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFC, 0x3); 1043 lpphy_set_trsw_over(dev, true, true);
1013 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x3);
1014 b43_phy_set(dev, B43_LPPHY_AFE_CTL_OVR, 1); 1044 b43_phy_set(dev, B43_LPPHY_AFE_CTL_OVR, 1);
1015 b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0xFFFE); 1045 b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0xFFFE);
1016 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x800); 1046 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x800);
@@ -1132,7 +1162,7 @@ static void lpphy_set_tx_power_control(struct b43_wldev *dev,
1132 b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_NNUM, 1162 b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_NNUM,
1133 0x8FFF, ((u16)lpphy->tssi_npt << 16)); 1163 0x8FFF, ((u16)lpphy->tssi_npt << 16));
1134 //TODO Set "TSSI Transmit Count" variable to total transmitted frame count 1164 //TODO Set "TSSI Transmit Count" variable to total transmitted frame count
1135 //TODO Disable TX gain override 1165 lpphy_disable_tx_gain_override(dev);
1136 lpphy->tx_pwr_idx_over = -1; 1166 lpphy->tx_pwr_idx_over = -1;
1137 } 1167 }
1138 } 1168 }
@@ -1318,15 +1348,73 @@ static void lpphy_calibrate_rc(struct b43_wldev *dev)
1318 } 1348 }
1319} 1349}
1320 1350
1351static void b43_lpphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna)
1352{
1353 if (dev->phy.rev >= 2)
1354 return; // rev2+ doesn't support antenna diversity
1355
1356 if (B43_WARN_ON(antenna > B43_ANTENNA_AUTO1))
1357 return;
1358
1359 b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_ANTDIVHELP);
1360
1361 b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFFFD, antenna & 0x2);
1362 b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFFFE, antenna & 0x1);
1363
1364 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_ANTDIVHELP);
1365
1366 dev->phy.lp->antenna = antenna;
1367}
1368
1369static void lpphy_set_tx_iqcc(struct b43_wldev *dev, u16 a, u16 b)
1370{
1371 u16 tmp[2];
1372
1373 tmp[0] = a;
1374 tmp[1] = b;
1375 b43_lptab_write_bulk(dev, B43_LPTAB16(0, 80), 2, tmp);
1376}
1377
1321static void lpphy_set_tx_power_by_index(struct b43_wldev *dev, u8 index) 1378static void lpphy_set_tx_power_by_index(struct b43_wldev *dev, u8 index)
1322{ 1379{
1323 struct b43_phy_lp *lpphy = dev->phy.lp; 1380 struct b43_phy_lp *lpphy = dev->phy.lp;
1381 struct lpphy_tx_gains gains;
1382 u32 iq_comp, tx_gain, coeff, rf_power;
1324 1383
1325 lpphy->tx_pwr_idx_over = index; 1384 lpphy->tx_pwr_idx_over = index;
1385 lpphy_read_tx_pctl_mode_from_hardware(dev);
1326 if (lpphy->txpctl_mode != B43_LPPHY_TXPCTL_OFF) 1386 if (lpphy->txpctl_mode != B43_LPPHY_TXPCTL_OFF)
1327 lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_SW); 1387 lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_SW);
1328 1388 if (dev->phy.rev >= 2) {
1329 //TODO 1389 iq_comp = b43_lptab_read(dev, B43_LPTAB32(7, index + 320));
1390 tx_gain = b43_lptab_read(dev, B43_LPTAB32(7, index + 192));
1391 gains.pad = (tx_gain >> 16) & 0xFF;
1392 gains.gm = tx_gain & 0xFF;
1393 gains.pga = (tx_gain >> 8) & 0xFF;
1394 gains.dac = (iq_comp >> 28) & 0xFF;
1395 lpphy_set_tx_gains(dev, gains);
1396 } else {
1397 iq_comp = b43_lptab_read(dev, B43_LPTAB32(10, index + 320));
1398 tx_gain = b43_lptab_read(dev, B43_LPTAB32(10, index + 192));
1399 b43_phy_maskset(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL,
1400 0xF800, (tx_gain >> 4) & 0x7FFF);
1401 lpphy_set_dac_gain(dev, tx_gain & 0x7);
1402 lpphy_set_pa_gain(dev, (tx_gain >> 24) & 0x7F);
1403 }
1404 lpphy_set_bb_mult(dev, (iq_comp >> 20) & 0xFF);
1405 lpphy_set_tx_iqcc(dev, (iq_comp >> 10) & 0x3FF, iq_comp & 0x3FF);
1406 if (dev->phy.rev >= 2) {
1407 coeff = b43_lptab_read(dev, B43_LPTAB32(7, index + 448));
1408 } else {
1409 coeff = b43_lptab_read(dev, B43_LPTAB32(10, index + 448));
1410 }
1411 b43_lptab_write(dev, B43_LPTAB16(0, 85), coeff & 0xFFFF);
1412 if (dev->phy.rev >= 2) {
1413 rf_power = b43_lptab_read(dev, B43_LPTAB32(7, index + 576));
1414 b43_phy_maskset(dev, B43_LPPHY_RF_PWR_OVERRIDE, 0xFF00,
1415 rf_power & 0xFFFF);//SPEC FIXME mask & set != 0
1416 }
1417 lpphy_enable_tx_gain_override(dev);
1330} 1418}
1331 1419
1332static void lpphy_btcoex_override(struct b43_wldev *dev) 1420static void lpphy_btcoex_override(struct b43_wldev *dev)
@@ -1335,58 +1423,45 @@ static void lpphy_btcoex_override(struct b43_wldev *dev)
1335 b43_write16(dev, B43_MMIO_BTCOEX_TXCTL, 0xFF); 1423 b43_write16(dev, B43_MMIO_BTCOEX_TXCTL, 0xFF);
1336} 1424}
1337 1425
1338static void lpphy_pr41573_workaround(struct b43_wldev *dev) 1426static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev,
1427 bool blocked)
1339{ 1428{
1340 struct b43_phy_lp *lpphy = dev->phy.lp; 1429 //TODO check MAC control register
1341 u32 *saved_tab; 1430 if (blocked) {
1342 const unsigned int saved_tab_size = 256; 1431 if (dev->phy.rev >= 2) {
1343 enum b43_lpphy_txpctl_mode txpctl_mode; 1432 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0x83FF);
1344 s8 tx_pwr_idx_over; 1433 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1F00);
1345 u16 tssi_npt, tssi_idx; 1434 b43_phy_mask(dev, B43_LPPHY_AFE_DDFS, 0x80FF);
1346 1435 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2_VAL, 0xDFFF);
1347 saved_tab = kcalloc(saved_tab_size, sizeof(saved_tab[0]), GFP_KERNEL); 1436 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x0808);
1348 if (!saved_tab) { 1437 } else {
1349 b43err(dev->wl, "PR41573 failed. Out of memory!\n"); 1438 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xE0FF);
1350 return; 1439 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1F00);
1351 } 1440 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2_VAL, 0xFCFF);
1352 1441 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x0018);
1353 lpphy_read_tx_pctl_mode_from_hardware(dev); 1442 }
1354 txpctl_mode = lpphy->txpctl_mode;
1355 tx_pwr_idx_over = lpphy->tx_pwr_idx_over;
1356 tssi_npt = lpphy->tssi_npt;
1357 tssi_idx = lpphy->tssi_idx;
1358
1359 if (dev->phy.rev < 2) {
1360 b43_lptab_read_bulk(dev, B43_LPTAB32(10, 0x140),
1361 saved_tab_size, saved_tab);
1362 } else { 1443 } else {
1363 b43_lptab_read_bulk(dev, B43_LPTAB32(7, 0x140), 1444 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xE0FF);
1364 saved_tab_size, saved_tab); 1445 if (dev->phy.rev >= 2)
1446 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xF7F7);
1447 else
1448 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFFE7);
1365 } 1449 }
1366 //TODO
1367
1368 kfree(saved_tab);
1369} 1450}
1370 1451
1371static void lpphy_calibration(struct b43_wldev *dev) 1452/* This was previously called lpphy_japan_filter */
1453static void lpphy_set_analog_filter(struct b43_wldev *dev, int channel)
1372{ 1454{
1373 struct b43_phy_lp *lpphy = dev->phy.lp; 1455 struct b43_phy_lp *lpphy = dev->phy.lp;
1374 enum b43_lpphy_txpctl_mode saved_pctl_mode; 1456 u16 tmp = (channel == 14); //SPEC FIXME check japanwidefilter!
1375
1376 b43_mac_suspend(dev);
1377
1378 lpphy_btcoex_override(dev);
1379 lpphy_read_tx_pctl_mode_from_hardware(dev);
1380 saved_pctl_mode = lpphy->txpctl_mode;
1381 lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF);
1382 //TODO Perform transmit power table I/Q LO calibration
1383 if ((dev->phy.rev == 0) && (saved_pctl_mode != B43_LPPHY_TXPCTL_OFF))
1384 lpphy_pr41573_workaround(dev);
1385 //TODO If a full calibration has not been performed on this channel yet, perform PAPD TX-power calibration
1386 lpphy_set_tx_power_control(dev, saved_pctl_mode);
1387 //TODO Perform I/Q calibration with a single control value set
1388 1457
1389 b43_mac_enable(dev); 1458 if (dev->phy.rev < 2) { //SPEC FIXME Isn't this rev0/1-specific?
1459 b43_phy_maskset(dev, B43_LPPHY_LP_PHY_CTL, 0xFCFF, tmp << 9);
1460 if ((dev->phy.rev == 1) && (lpphy->rc_cap))
1461 lpphy_set_rc_cap(dev);
1462 } else {
1463 b43_radio_write(dev, B2063_TX_BB_SP3, 0x3F);
1464 }
1390} 1465}
1391 1466
1392static void lpphy_set_tssi_mux(struct b43_wldev *dev, enum tssi_mux_mode mode) 1467static void lpphy_set_tssi_mux(struct b43_wldev *dev, enum tssi_mux_mode mode)
@@ -1495,6 +1570,473 @@ static void lpphy_tx_pctl_init(struct b43_wldev *dev)
1495 } 1570 }
1496} 1571}
1497 1572
1573static void lpphy_pr41573_workaround(struct b43_wldev *dev)
1574{
1575 struct b43_phy_lp *lpphy = dev->phy.lp;
1576 u32 *saved_tab;
1577 const unsigned int saved_tab_size = 256;
1578 enum b43_lpphy_txpctl_mode txpctl_mode;
1579 s8 tx_pwr_idx_over;
1580 u16 tssi_npt, tssi_idx;
1581
1582 saved_tab = kcalloc(saved_tab_size, sizeof(saved_tab[0]), GFP_KERNEL);
1583 if (!saved_tab) {
1584 b43err(dev->wl, "PR41573 failed. Out of memory!\n");
1585 return;
1586 }
1587
1588 lpphy_read_tx_pctl_mode_from_hardware(dev);
1589 txpctl_mode = lpphy->txpctl_mode;
1590 tx_pwr_idx_over = lpphy->tx_pwr_idx_over;
1591 tssi_npt = lpphy->tssi_npt;
1592 tssi_idx = lpphy->tssi_idx;
1593
1594 if (dev->phy.rev < 2) {
1595 b43_lptab_read_bulk(dev, B43_LPTAB32(10, 0x140),
1596 saved_tab_size, saved_tab);
1597 } else {
1598 b43_lptab_read_bulk(dev, B43_LPTAB32(7, 0x140),
1599 saved_tab_size, saved_tab);
1600 }
1601 //FIXME PHY reset
1602 lpphy_table_init(dev); //FIXME is table init needed?
1603 lpphy_baseband_init(dev);
1604 lpphy_tx_pctl_init(dev);
1605 b43_lpphy_op_software_rfkill(dev, false);
1606 lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF);
1607 if (dev->phy.rev < 2) {
1608 b43_lptab_write_bulk(dev, B43_LPTAB32(10, 0x140),
1609 saved_tab_size, saved_tab);
1610 } else {
1611 b43_lptab_write_bulk(dev, B43_LPTAB32(7, 0x140),
1612 saved_tab_size, saved_tab);
1613 }
1614 b43_write16(dev, B43_MMIO_CHANNEL, lpphy->channel);
1615 lpphy->tssi_npt = tssi_npt;
1616 lpphy->tssi_idx = tssi_idx;
1617 lpphy_set_analog_filter(dev, lpphy->channel);
1618 if (tx_pwr_idx_over != -1)
1619 lpphy_set_tx_power_by_index(dev, tx_pwr_idx_over);
1620 if (lpphy->rc_cap)
1621 lpphy_set_rc_cap(dev);
1622 b43_lpphy_op_set_rx_antenna(dev, lpphy->antenna);
1623 lpphy_set_tx_power_control(dev, txpctl_mode);
1624 kfree(saved_tab);
1625}
1626
1627struct lpphy_rx_iq_comp { u8 chan; s8 c1, c0; };
1628
1629static const struct lpphy_rx_iq_comp lpphy_5354_iq_table[] = {
1630 { .chan = 1, .c1 = -66, .c0 = 15, },
1631 { .chan = 2, .c1 = -66, .c0 = 15, },
1632 { .chan = 3, .c1 = -66, .c0 = 15, },
1633 { .chan = 4, .c1 = -66, .c0 = 15, },
1634 { .chan = 5, .c1 = -66, .c0 = 15, },
1635 { .chan = 6, .c1 = -66, .c0 = 15, },
1636 { .chan = 7, .c1 = -66, .c0 = 14, },
1637 { .chan = 8, .c1 = -66, .c0 = 14, },
1638 { .chan = 9, .c1 = -66, .c0 = 14, },
1639 { .chan = 10, .c1 = -66, .c0 = 14, },
1640 { .chan = 11, .c1 = -66, .c0 = 14, },
1641 { .chan = 12, .c1 = -66, .c0 = 13, },
1642 { .chan = 13, .c1 = -66, .c0 = 13, },
1643 { .chan = 14, .c1 = -66, .c0 = 13, },
1644};
1645
1646static const struct lpphy_rx_iq_comp lpphy_rev0_1_iq_table[] = {
1647 { .chan = 1, .c1 = -64, .c0 = 13, },
1648 { .chan = 2, .c1 = -64, .c0 = 13, },
1649 { .chan = 3, .c1 = -64, .c0 = 13, },
1650 { .chan = 4, .c1 = -64, .c0 = 13, },
1651 { .chan = 5, .c1 = -64, .c0 = 12, },
1652 { .chan = 6, .c1 = -64, .c0 = 12, },
1653 { .chan = 7, .c1 = -64, .c0 = 12, },
1654 { .chan = 8, .c1 = -64, .c0 = 12, },
1655 { .chan = 9, .c1 = -64, .c0 = 12, },
1656 { .chan = 10, .c1 = -64, .c0 = 11, },
1657 { .chan = 11, .c1 = -64, .c0 = 11, },
1658 { .chan = 12, .c1 = -64, .c0 = 11, },
1659 { .chan = 13, .c1 = -64, .c0 = 11, },
1660 { .chan = 14, .c1 = -64, .c0 = 10, },
1661 { .chan = 34, .c1 = -62, .c0 = 24, },
1662 { .chan = 38, .c1 = -62, .c0 = 24, },
1663 { .chan = 42, .c1 = -62, .c0 = 24, },
1664 { .chan = 46, .c1 = -62, .c0 = 23, },
1665 { .chan = 36, .c1 = -62, .c0 = 24, },
1666 { .chan = 40, .c1 = -62, .c0 = 24, },
1667 { .chan = 44, .c1 = -62, .c0 = 23, },
1668 { .chan = 48, .c1 = -62, .c0 = 23, },
1669 { .chan = 52, .c1 = -62, .c0 = 23, },
1670 { .chan = 56, .c1 = -62, .c0 = 22, },
1671 { .chan = 60, .c1 = -62, .c0 = 22, },
1672 { .chan = 64, .c1 = -62, .c0 = 22, },
1673 { .chan = 100, .c1 = -62, .c0 = 16, },
1674 { .chan = 104, .c1 = -62, .c0 = 16, },
1675 { .chan = 108, .c1 = -62, .c0 = 15, },
1676 { .chan = 112, .c1 = -62, .c0 = 14, },
1677 { .chan = 116, .c1 = -62, .c0 = 14, },
1678 { .chan = 120, .c1 = -62, .c0 = 13, },
1679 { .chan = 124, .c1 = -62, .c0 = 12, },
1680 { .chan = 128, .c1 = -62, .c0 = 12, },
1681 { .chan = 132, .c1 = -62, .c0 = 12, },
1682 { .chan = 136, .c1 = -62, .c0 = 11, },
1683 { .chan = 140, .c1 = -62, .c0 = 10, },
1684 { .chan = 149, .c1 = -61, .c0 = 9, },
1685 { .chan = 153, .c1 = -61, .c0 = 9, },
1686 { .chan = 157, .c1 = -61, .c0 = 9, },
1687 { .chan = 161, .c1 = -61, .c0 = 8, },
1688 { .chan = 165, .c1 = -61, .c0 = 8, },
1689 { .chan = 184, .c1 = -62, .c0 = 25, },
1690 { .chan = 188, .c1 = -62, .c0 = 25, },
1691 { .chan = 192, .c1 = -62, .c0 = 25, },
1692 { .chan = 196, .c1 = -62, .c0 = 25, },
1693 { .chan = 200, .c1 = -62, .c0 = 25, },
1694 { .chan = 204, .c1 = -62, .c0 = 25, },
1695 { .chan = 208, .c1 = -62, .c0 = 25, },
1696 { .chan = 212, .c1 = -62, .c0 = 25, },
1697 { .chan = 216, .c1 = -62, .c0 = 26, },
1698};
1699
1700static const struct lpphy_rx_iq_comp lpphy_rev2plus_iq_comp = {
1701 .chan = 0,
1702 .c1 = -64,
1703 .c0 = 0,
1704};
1705
1706static u8 lpphy_nbits(s32 val)
1707{
1708 u32 tmp = abs(val);
1709 u8 nbits = 0;
1710
1711 while (tmp != 0) {
1712 nbits++;
1713 tmp >>= 1;
1714 }
1715
1716 return nbits;
1717}
1718
1719static int lpphy_calc_rx_iq_comp(struct b43_wldev *dev, u16 samples)
1720{
1721 struct lpphy_iq_est iq_est;
1722 u16 c0, c1;
1723 int prod, ipwr, qpwr, prod_msb, q_msb, tmp1, tmp2, tmp3, tmp4, ret;
1724
1725 c1 = b43_phy_read(dev, B43_LPPHY_RX_COMP_COEFF_S);
1726 c0 = c1 >> 8;
1727 c1 |= 0xFF;
1728
1729 b43_phy_maskset(dev, B43_LPPHY_RX_COMP_COEFF_S, 0xFF00, 0x00C0);
1730 b43_phy_mask(dev, B43_LPPHY_RX_COMP_COEFF_S, 0x00FF);
1731
1732 ret = lpphy_rx_iq_est(dev, samples, 32, &iq_est);
1733 if (!ret)
1734 goto out;
1735
1736 prod = iq_est.iq_prod;
1737 ipwr = iq_est.i_pwr;
1738 qpwr = iq_est.q_pwr;
1739
1740 if (ipwr + qpwr < 2) {
1741 ret = 0;
1742 goto out;
1743 }
1744
1745 prod_msb = lpphy_nbits(prod);
1746 q_msb = lpphy_nbits(qpwr);
1747 tmp1 = prod_msb - 20;
1748
1749 if (tmp1 >= 0) {
1750 tmp3 = ((prod << (30 - prod_msb)) + (ipwr >> (1 + tmp1))) /
1751 (ipwr >> tmp1);
1752 } else {
1753 tmp3 = ((prod << (30 - prod_msb)) + (ipwr << (-1 - tmp1))) /
1754 (ipwr << -tmp1);
1755 }
1756
1757 tmp2 = q_msb - 11;
1758
1759 if (tmp2 >= 0)
1760 tmp4 = (qpwr << (31 - q_msb)) / (ipwr >> tmp2);
1761 else
1762 tmp4 = (qpwr << (31 - q_msb)) / (ipwr << -tmp2);
1763
1764 tmp4 -= tmp3 * tmp3;
1765 tmp4 = -int_sqrt(tmp4);
1766
1767 c0 = tmp3 >> 3;
1768 c1 = tmp4 >> 4;
1769
1770out:
1771 b43_phy_maskset(dev, B43_LPPHY_RX_COMP_COEFF_S, 0xFF00, c1);
1772 b43_phy_maskset(dev, B43_LPPHY_RX_COMP_COEFF_S, 0x00FF, c0 << 8);
1773 return ret;
1774}
1775
1776/* Complex number using 2 32-bit signed integers */
1777typedef struct {s32 i, q;} lpphy_c32;
1778
1779static lpphy_c32 lpphy_cordic(int theta)
1780{
1781 u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304,
1782 58666, 29335, 14668, 7334, 3667, 1833, 917, 458,
1783 229, 115, 57, 29, };
1784 int i, tmp, signx = 1, angle = 0;
1785 lpphy_c32 ret = { .i = 39797, .q = 0, };
1786
1787 theta = clamp_t(int, theta, -180, 180);
1788
1789 if (theta > 90) {
1790 theta -= 180;
1791 signx = -1;
1792 } else if (theta < -90) {
1793 theta += 180;
1794 signx = -1;
1795 }
1796
1797 for (i = 0; i <= 17; i++) {
1798 if (theta > angle) {
1799 tmp = ret.i - (ret.q >> i);
1800 ret.q += ret.i >> i;
1801 ret.i = tmp;
1802 angle += arctg[i];
1803 } else {
1804 tmp = ret.i + (ret.q >> i);
1805 ret.q -= ret.i >> i;
1806 ret.i = tmp;
1807 angle -= arctg[i];
1808 }
1809 }
1810
1811 ret.i *= signx;
1812 ret.q *= signx;
1813
1814 return ret;
1815}
1816
1817static void lpphy_run_samples(struct b43_wldev *dev, u16 samples, u16 loops,
1818 u16 wait)
1819{
1820 b43_phy_maskset(dev, B43_LPPHY_SMPL_PLAY_BUFFER_CTL,
1821 0xFFC0, samples - 1);
1822 if (loops != 0xFFFF)
1823 loops--;
1824 b43_phy_maskset(dev, B43_LPPHY_SMPL_PLAY_COUNT, 0xF000, loops);
1825 b43_phy_maskset(dev, B43_LPPHY_SMPL_PLAY_BUFFER_CTL, 0x3F, wait << 6);
1826 b43_phy_set(dev, B43_LPPHY_A_PHY_CTL_ADDR, 0x1);
1827}
1828
1829//SPEC FIXME what does a negative freq mean?
1830static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max)
1831{
1832 struct b43_phy_lp *lpphy = dev->phy.lp;
1833 u16 buf[64];
1834 int i, samples = 0, angle = 0, rotation = (9 * freq) / 500;
1835 lpphy_c32 sample;
1836
1837 lpphy->tx_tone_freq = freq;
1838
1839 if (freq) {
1840 /* Find i for which abs(freq) integrally divides 20000 * i */
1841 for (i = 1; samples * abs(freq) != 20000 * i; i++) {
1842 samples = (20000 * i) / abs(freq);
1843 if(B43_WARN_ON(samples > 63))
1844 return;
1845 }
1846 } else {
1847 samples = 2;
1848 }
1849
1850 for (i = 0; i < samples; i++) {
1851 sample = lpphy_cordic(angle);
1852 angle += rotation;
1853 buf[i] = ((sample.i * max) & 0xFF) << 8;
1854 buf[i] |= (sample.q * max) & 0xFF;
1855 }
1856
1857 b43_lptab_write_bulk(dev, B43_LPTAB16(5, 0), samples, buf);
1858
1859 lpphy_run_samples(dev, samples, 0xFFFF, 0);
1860}
1861
1862static void lpphy_stop_tx_tone(struct b43_wldev *dev)
1863{
1864 struct b43_phy_lp *lpphy = dev->phy.lp;
1865 int i;
1866
1867 lpphy->tx_tone_freq = 0;
1868
1869 b43_phy_mask(dev, B43_LPPHY_SMPL_PLAY_COUNT, 0xF000);
1870 for (i = 0; i < 31; i++) {
1871 if (!(b43_phy_read(dev, B43_LPPHY_A_PHY_CTL_ADDR) & 0x1))
1872 break;
1873 udelay(100);
1874 }
1875}
1876
1877
1878static void lpphy_papd_cal(struct b43_wldev *dev, struct lpphy_tx_gains gains,
1879 int mode, bool useindex, u8 index)
1880{
1881 //TODO
1882}
1883
1884static void lpphy_papd_cal_txpwr(struct b43_wldev *dev)
1885{
1886 struct b43_phy_lp *lpphy = dev->phy.lp;
1887 struct ssb_bus *bus = dev->dev->bus;
1888 struct lpphy_tx_gains gains, oldgains;
1889 int old_txpctl, old_afe_ovr, old_rf, old_bbmult;
1890
1891 lpphy_read_tx_pctl_mode_from_hardware(dev);
1892 old_txpctl = lpphy->txpctl_mode;
1893 old_afe_ovr = b43_phy_read(dev, B43_LPPHY_AFE_CTL_OVR) & 0x40;
1894 if (old_afe_ovr)
1895 oldgains = lpphy_get_tx_gains(dev);
1896 old_rf = b43_phy_read(dev, B43_LPPHY_RF_PWR_OVERRIDE) & 0xFF;
1897 old_bbmult = lpphy_get_bb_mult(dev);
1898
1899 lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF);
1900
1901 if (bus->chip_id == 0x4325 && bus->chip_rev == 0)
1902 lpphy_papd_cal(dev, gains, 0, 1, 30);
1903 else
1904 lpphy_papd_cal(dev, gains, 0, 1, 65);
1905
1906 if (old_afe_ovr)
1907 lpphy_set_tx_gains(dev, oldgains);
1908 lpphy_set_bb_mult(dev, old_bbmult);
1909 lpphy_set_tx_power_control(dev, old_txpctl);
1910 b43_phy_maskset(dev, B43_LPPHY_RF_PWR_OVERRIDE, 0xFF00, old_rf);
1911}
1912
1913static int lpphy_rx_iq_cal(struct b43_wldev *dev, bool noise, bool tx,
1914 bool rx, bool pa, struct lpphy_tx_gains *gains)
1915{
1916 struct b43_phy_lp *lpphy = dev->phy.lp;
1917 struct ssb_bus *bus = dev->dev->bus;
1918 const struct lpphy_rx_iq_comp *iqcomp = NULL;
1919 struct lpphy_tx_gains nogains, oldgains;
1920 u16 tmp;
1921 int i, ret;
1922
1923 memset(&nogains, 0, sizeof(nogains));
1924 memset(&oldgains, 0, sizeof(oldgains));
1925
1926 if (bus->chip_id == 0x5354) {
1927 for (i = 0; i < ARRAY_SIZE(lpphy_5354_iq_table); i++) {
1928 if (lpphy_5354_iq_table[i].chan == lpphy->channel) {
1929 iqcomp = &lpphy_5354_iq_table[i];
1930 }
1931 }
1932 } else if (dev->phy.rev >= 2) {
1933 iqcomp = &lpphy_rev2plus_iq_comp;
1934 } else {
1935 for (i = 0; i < ARRAY_SIZE(lpphy_rev0_1_iq_table); i++) {
1936 if (lpphy_rev0_1_iq_table[i].chan == lpphy->channel) {
1937 iqcomp = &lpphy_rev0_1_iq_table[i];
1938 }
1939 }
1940 }
1941
1942 if (B43_WARN_ON(!iqcomp))
1943 return 0;
1944
1945 b43_phy_maskset(dev, B43_LPPHY_RX_COMP_COEFF_S, 0xFF00, iqcomp->c1);
1946 b43_phy_maskset(dev, B43_LPPHY_RX_COMP_COEFF_S,
1947 0x00FF, iqcomp->c0 << 8);
1948
1949 if (noise) {
1950 tx = true;
1951 rx = false;
1952 pa = false;
1953 }
1954
1955 lpphy_set_trsw_over(dev, tx, rx);
1956
1957 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
1958 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x8);
1959 b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0,
1960 0xFFF7, pa << 3);
1961 } else {
1962 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x20);
1963 b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0,
1964 0xFFDF, pa << 5);
1965 }
1966
1967 tmp = b43_phy_read(dev, B43_LPPHY_AFE_CTL_OVR) & 0x40;
1968
1969 if (noise)
1970 lpphy_set_rx_gain(dev, 0x2D5D);
1971 else {
1972 if (tmp)
1973 oldgains = lpphy_get_tx_gains(dev);
1974 if (!gains)
1975 gains = &nogains;
1976 lpphy_set_tx_gains(dev, *gains);
1977 }
1978
1979 b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVR, 0xFFFE);
1980 b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0xFFFE);
1981 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x800);
1982 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0x800);
1983 lpphy_set_deaf(dev, false);
1984 if (noise)
1985 ret = lpphy_calc_rx_iq_comp(dev, 0xFFF0);
1986 else {
1987 lpphy_start_tx_tone(dev, 4000, 100);
1988 ret = lpphy_calc_rx_iq_comp(dev, 0x4000);
1989 lpphy_stop_tx_tone(dev);
1990 }
1991 lpphy_clear_deaf(dev, false);
1992 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFFC);
1993 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFF7);
1994 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFDF);
1995 if (!noise) {
1996 if (tmp)
1997 lpphy_set_tx_gains(dev, oldgains);
1998 else
1999 lpphy_disable_tx_gain_override(dev);
2000 }
2001 lpphy_disable_rx_gain_override(dev);
2002 b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVR, 0xFFFE);
2003 b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0xF7FF);
2004 return ret;
2005}
2006
2007static void lpphy_calibration(struct b43_wldev *dev)
2008{
2009 struct b43_phy_lp *lpphy = dev->phy.lp;
2010 enum b43_lpphy_txpctl_mode saved_pctl_mode;
2011 bool full_cal = false;
2012
2013 if (lpphy->full_calib_chan != lpphy->channel) {
2014 full_cal = true;
2015 lpphy->full_calib_chan = lpphy->channel;
2016 }
2017
2018 b43_mac_suspend(dev);
2019
2020 lpphy_btcoex_override(dev);
2021 if (dev->phy.rev >= 2)
2022 lpphy_save_dig_flt_state(dev);
2023 lpphy_read_tx_pctl_mode_from_hardware(dev);
2024 saved_pctl_mode = lpphy->txpctl_mode;
2025 lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF);
2026 //TODO Perform transmit power table I/Q LO calibration
2027 if ((dev->phy.rev == 0) && (saved_pctl_mode != B43_LPPHY_TXPCTL_OFF))
2028 lpphy_pr41573_workaround(dev);
2029 if ((dev->phy.rev >= 2) && full_cal) {
2030 lpphy_papd_cal_txpwr(dev);
2031 }
2032 lpphy_set_tx_power_control(dev, saved_pctl_mode);
2033 if (dev->phy.rev >= 2)
2034 lpphy_restore_dig_flt_state(dev);
2035 lpphy_rx_iq_cal(dev, true, true, false, false, NULL);
2036
2037 b43_mac_enable(dev);
2038}
2039
1498static u16 b43_lpphy_op_read(struct b43_wldev *dev, u16 reg) 2040static u16 b43_lpphy_op_read(struct b43_wldev *dev, u16 reg)
1499{ 2041{
1500 b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); 2042 b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
@@ -1539,12 +2081,6 @@ static void b43_lpphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
1539 b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value); 2081 b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
1540} 2082}
1541 2083
1542static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev,
1543 bool blocked)
1544{
1545 //TODO
1546}
1547
1548struct b206x_channel { 2084struct b206x_channel {
1549 u8 channel; 2085 u8 channel;
1550 u16 freq; 2086 u16 freq;
@@ -2010,22 +2546,6 @@ static int lpphy_b2062_tune(struct b43_wldev *dev,
2010 return err; 2546 return err;
2011} 2547}
2012 2548
2013
2014/* This was previously called lpphy_japan_filter */
2015static void lpphy_set_analog_filter(struct b43_wldev *dev, int channel)
2016{
2017 struct b43_phy_lp *lpphy = dev->phy.lp;
2018 u16 tmp = (channel == 14); //SPEC FIXME check japanwidefilter!
2019
2020 if (dev->phy.rev < 2) { //SPEC FIXME Isn't this rev0/1-specific?
2021 b43_phy_maskset(dev, B43_LPPHY_LP_PHY_CTL, 0xFCFF, tmp << 9);
2022 if ((dev->phy.rev == 1) && (lpphy->rc_cap))
2023 lpphy_set_rc_cap(dev);
2024 } else {
2025 b43_radio_write(dev, B2063_TX_BB_SP3, 0x3F);
2026 }
2027}
2028
2029static void lpphy_b2063_vco_calib(struct b43_wldev *dev) 2549static void lpphy_b2063_vco_calib(struct b43_wldev *dev)
2030{ 2550{
2031 u16 tmp; 2551 u16 tmp;
@@ -2210,18 +2730,6 @@ static int b43_lpphy_op_init(struct b43_wldev *dev)
2210 return 0; 2730 return 0;
2211} 2731}
2212 2732
2213static void b43_lpphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna)
2214{
2215 if (dev->phy.rev >= 2)
2216 return; // rev2+ doesn't support antenna diversity
2217
2218 if (B43_WARN_ON(antenna > B43_ANTENNA_AUTO1))
2219 return;
2220
2221 b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFFFD, antenna & 0x2);
2222 b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFFFE, antenna & 0x1);
2223}
2224
2225static void b43_lpphy_op_adjust_txpower(struct b43_wldev *dev) 2733static void b43_lpphy_op_adjust_txpower(struct b43_wldev *dev)
2226{ 2734{
2227 //TODO 2735 //TODO
@@ -2244,6 +2752,11 @@ void b43_lpphy_op_switch_analog(struct b43_wldev *dev, bool on)
2244 } 2752 }
2245} 2753}
2246 2754
2755static void b43_lpphy_op_pwork_15sec(struct b43_wldev *dev)
2756{
2757 //TODO
2758}
2759
2247const struct b43_phy_operations b43_phyops_lp = { 2760const struct b43_phy_operations b43_phyops_lp = {
2248 .allocate = b43_lpphy_op_allocate, 2761 .allocate = b43_lpphy_op_allocate,
2249 .free = b43_lpphy_op_free, 2762 .free = b43_lpphy_op_free,
@@ -2261,4 +2774,6 @@ const struct b43_phy_operations b43_phyops_lp = {
2261 .set_rx_antenna = b43_lpphy_op_set_rx_antenna, 2774 .set_rx_antenna = b43_lpphy_op_set_rx_antenna,
2262 .recalc_txpower = b43_lpphy_op_recalc_txpower, 2775 .recalc_txpower = b43_lpphy_op_recalc_txpower,
2263 .adjust_txpower = b43_lpphy_op_adjust_txpower, 2776 .adjust_txpower = b43_lpphy_op_adjust_txpower,
2777 .pwork_15sec = b43_lpphy_op_pwork_15sec,
2778 .pwork_60sec = lpphy_calibration,
2264}; 2779};
diff --git a/drivers/net/wireless/b43/phy_lp.h b/drivers/net/wireless/b43/phy_lp.h
index c3232c17b60a..62737f700cbc 100644
--- a/drivers/net/wireless/b43/phy_lp.h
+++ b/drivers/net/wireless/b43/phy_lp.h
@@ -286,6 +286,7 @@
286#define B43_LPPHY_TR_LOOKUP_6 B43_PHY_OFDM(0xC8) /* TR Lookup 6 */ 286#define B43_LPPHY_TR_LOOKUP_6 B43_PHY_OFDM(0xC8) /* TR Lookup 6 */
287#define B43_LPPHY_TR_LOOKUP_7 B43_PHY_OFDM(0xC9) /* TR Lookup 7 */ 287#define B43_LPPHY_TR_LOOKUP_7 B43_PHY_OFDM(0xC9) /* TR Lookup 7 */
288#define B43_LPPHY_TR_LOOKUP_8 B43_PHY_OFDM(0xCA) /* TR Lookup 8 */ 288#define B43_LPPHY_TR_LOOKUP_8 B43_PHY_OFDM(0xCA) /* TR Lookup 8 */
289#define B43_LPPHY_RF_PWR_OVERRIDE B43_PHY_OFDM(0xD3) /* RF power override */
289 290
290 291
291 292
@@ -871,12 +872,12 @@ struct b43_phy_lp {
871 u8 rssi_gs; 872 u8 rssi_gs;
872 873
873 /* RC cap */ 874 /* RC cap */
874 u8 rc_cap; /* FIXME initial value? */ 875 u8 rc_cap;
875 /* BX arch */ 876 /* BX arch */
876 u8 bx_arch; 877 u8 bx_arch;
877 878
878 /* Full calibration channel */ 879 /* Full calibration channel */
879 u8 full_calib_chan; /* FIXME initial value? */ 880 u8 full_calib_chan;
880 881
881 /* Transmit iqlocal best coeffs */ 882 /* Transmit iqlocal best coeffs */
882 bool tx_iqloc_best_coeffs_valid; 883 bool tx_iqloc_best_coeffs_valid;
@@ -891,6 +892,12 @@ struct b43_phy_lp {
891 892
892 /* The channel we are tuned to */ 893 /* The channel we are tuned to */
893 u8 channel; 894 u8 channel;
895
896 /* The active antenna diversity mode */
897 int antenna;
898
899 /* Frequency of the active TX tone */
900 int tx_tone_freq;
894}; 901};
895 902
896enum tssi_mux_mode { 903enum tssi_mux_mode {