Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Gábor Stefanik and committed by
John W. Linville
2c0d6100 29906f6a

+658 -136
+649 -134
drivers/net/wireless/b43/phy_lp.c
··· 67 67 struct b43_phy_lp *lpphy = phy->lp; 68 68 69 69 memset(lpphy, 0, sizeof(*lpphy)); 70 + lpphy->antenna = B43_ANTENNA_DEFAULT; 70 71 71 72 //TODO 72 73 } ··· 380 379 } 381 380 } 382 381 383 - /* lpphy_restore_dig_flt_state is unused but kept as a reference */ 384 - #if 0 385 382 static void lpphy_restore_dig_flt_state(struct b43_wldev *dev) 386 383 { 387 384 static const u16 addr[] = { ··· 400 401 for (i = 0; i < ARRAY_SIZE(addr); i++) 401 402 b43_phy_write(dev, addr[i], lpphy->dig_flt_state[i]); 402 403 } 403 - #endif 404 404 405 405 static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) 406 406 { ··· 752 754 } 753 755 } 754 756 757 + static void lpphy_set_trsw_over(struct b43_wldev *dev, bool tx, bool rx) 758 + { 759 + u16 trsw = (tx << 1) | rx; 760 + b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFC, trsw); 761 + b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x3); 762 + } 763 + 755 764 static void lpphy_disable_crs(struct b43_wldev *dev, bool user) 756 765 { 757 766 lpphy_set_deaf(dev, user); 758 - b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFC, 0x1); 759 - b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x3); 767 + lpphy_set_trsw_over(dev, false, true); 760 768 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFB); 761 769 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x4); 762 770 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFF7); ··· 797 793 798 794 struct lpphy_tx_gains { u16 gm, pga, pad, dac; }; 799 795 796 + static void lpphy_disable_rx_gain_override(struct b43_wldev *dev) 797 + { 798 + b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFFE); 799 + b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFEF); 800 + b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFBF); 801 + if (dev->phy.rev >= 2) { 802 + b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF); 803 + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 804 + b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFBFF); 805 + b43_phy_mask(dev, B43_PHY_OFDM(0xE5), 0xFFF7); 806 + } 807 + } else { 808 + b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFDFF); 809 + } 810 + } 811 + 812 + static void lpphy_enable_rx_gain_override(struct b43_wldev *dev) 813 + { 814 + b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1); 815 + b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x10); 816 + b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x40); 817 + if (dev->phy.rev >= 2) { 818 + b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x100); 819 + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 820 + b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x400); 821 + b43_phy_set(dev, B43_PHY_OFDM(0xE5), 0x8); 822 + } 823 + } else { 824 + b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x200); 825 + } 826 + } 827 + 828 + static void lpphy_disable_tx_gain_override(struct b43_wldev *dev) 829 + { 830 + if (dev->phy.rev < 2) 831 + b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF); 832 + else { 833 + b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFF7F); 834 + b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xBFFF); 835 + } 836 + b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVR, 0xFFBF); 837 + } 838 + 839 + static void lpphy_enable_tx_gain_override(struct b43_wldev *dev) 840 + { 841 + if (dev->phy.rev < 2) 842 + b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x100); 843 + else { 844 + b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x80); 845 + b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x4000); 846 + } 847 + b43_phy_set(dev, B43_LPPHY_AFE_CTL_OVR, 0x40); 848 + } 849 + 800 850 static struct lpphy_tx_gains lpphy_get_tx_gains(struct b43_wldev *dev) 801 851 { 802 852 struct lpphy_tx_gains gains; ··· 880 822 b43_phy_maskset(dev, B43_LPPHY_AFE_DAC_CTL, 0xF000, ctl); 881 823 } 882 824 825 + static u16 lpphy_get_pa_gain(struct b43_wldev *dev) 826 + { 827 + return b43_phy_read(dev, B43_PHY_OFDM(0xFB)) & 0x7F; 828 + } 829 + 830 + static void lpphy_set_pa_gain(struct b43_wldev *dev, u16 gain) 831 + { 832 + b43_phy_maskset(dev, B43_PHY_OFDM(0xFB), 0xE03F, gain << 6); 833 + b43_phy_maskset(dev, B43_PHY_OFDM(0xFD), 0x80FF, gain << 8); 834 + } 835 + 883 836 static void lpphy_set_tx_gains(struct b43_wldev *dev, 884 837 struct lpphy_tx_gains gains) 885 838 { ··· 901 832 b43_phy_maskset(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL, 902 833 0xF800, rf_gain); 903 834 } else { 904 - pa_gain = b43_phy_read(dev, B43_PHY_OFDM(0xFB)) & 0x1FC0; 905 - pa_gain <<= 2; 835 + pa_gain = lpphy_get_pa_gain(dev); 906 836 b43_phy_write(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL, 907 837 (gains.pga << 8) | gains.gm); 838 + /* 839 + * SPEC FIXME The spec calls for (pa_gain << 8) here, but that 840 + * conflicts with the spec for set_pa_gain! Vendor driver bug? 841 + */ 908 842 b43_phy_maskset(dev, B43_PHY_OFDM(0xFB), 909 - 0x8000, gains.pad | pa_gain); 843 + 0x8000, gains.pad | (pa_gain << 6)); 910 844 b43_phy_write(dev, B43_PHY_OFDM(0xFC), 911 845 (gains.pga << 8) | gains.gm); 912 846 b43_phy_maskset(dev, B43_PHY_OFDM(0xFD), 913 - 0x8000, gains.pad | pa_gain); 847 + 0x8000, gains.pad | (pa_gain << 8)); 914 848 } 915 849 lpphy_set_dac_gain(dev, gains.dac); 916 - if (dev->phy.rev < 2) { 917 - b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF, 1 << 8); 918 - } else { 919 - b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFF7F, 1 << 7); 920 - b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xBFFF, 1 << 14); 921 - } 922 - b43_phy_maskset(dev, B43_LPPHY_AFE_CTL_OVR, 0xFFBF, 1 << 6); 850 + lpphy_enable_tx_gain_override(dev); 923 851 } 924 852 925 853 static void lpphy_rev0_1_set_rx_gain(struct b43_wldev *dev, u32 gain) ··· 953 887 b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2_VAL, 954 888 0xE7FF, tmp<<11); 955 889 b43_phy_maskset(dev, B43_PHY_OFDM(0xE6), 0xFFE7, tmp << 3); 956 - } 957 - } 958 - 959 - /* lpphy_disable_rx_gain_override is unused but kept as a reference */ 960 - #if 0 961 - static void lpphy_disable_rx_gain_override(struct b43_wldev *dev) 962 - { 963 - b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFFE); 964 - b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFEF); 965 - b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFBF); 966 - if (dev->phy.rev >= 2) { 967 - b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF); 968 - if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 969 - b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFBFF); 970 - b43_phy_mask(dev, B43_PHY_OFDM(0xE5), 0xFFF7); 971 - } 972 - } else { 973 - b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFDFF); 974 - } 975 - } 976 - #endif 977 - 978 - static void lpphy_enable_rx_gain_override(struct b43_wldev *dev) 979 - { 980 - b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1); 981 - b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x10); 982 - b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x40); 983 - if (dev->phy.rev >= 2) { 984 - b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x100); 985 - if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 986 - b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x400); 987 - b43_phy_set(dev, B43_PHY_OFDM(0xE5), 0x8); 988 - } 989 - } else { 990 - b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x200); 991 890 } 992 891 } 993 892 ··· 1040 1009 1041 1010 memset(&iq_est, 0, sizeof(iq_est)); 1042 1011 1043 - b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFC, 0x3); 1044 - b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x3); 1012 + lpphy_set_trsw_over(dev, true, true); 1045 1013 b43_phy_set(dev, B43_LPPHY_AFE_CTL_OVR, 1); 1046 1014 b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0xFFFE); 1047 1015 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x800); ··· 1162 1132 b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_NNUM, 1163 1133 0x8FFF, ((u16)lpphy->tssi_npt << 16)); 1164 1134 //TODO Set "TSSI Transmit Count" variable to total transmitted frame count 1165 - //TODO Disable TX gain override 1135 + lpphy_disable_tx_gain_override(dev); 1166 1136 lpphy->tx_pwr_idx_over = -1; 1167 1137 } 1168 1138 } ··· 1348 1318 } 1349 1319 } 1350 1320 1321 + static void b43_lpphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna) 1322 + { 1323 + if (dev->phy.rev >= 2) 1324 + return; // rev2+ doesn't support antenna diversity 1325 + 1326 + if (B43_WARN_ON(antenna > B43_ANTENNA_AUTO1)) 1327 + return; 1328 + 1329 + b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_ANTDIVHELP); 1330 + 1331 + b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFFFD, antenna & 0x2); 1332 + b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFFFE, antenna & 0x1); 1333 + 1334 + b43_hf_write(dev, b43_hf_read(dev) | B43_HF_ANTDIVHELP); 1335 + 1336 + dev->phy.lp->antenna = antenna; 1337 + } 1338 + 1339 + static void lpphy_set_tx_iqcc(struct b43_wldev *dev, u16 a, u16 b) 1340 + { 1341 + u16 tmp[2]; 1342 + 1343 + tmp[0] = a; 1344 + tmp[1] = b; 1345 + b43_lptab_write_bulk(dev, B43_LPTAB16(0, 80), 2, tmp); 1346 + } 1347 + 1351 1348 static void lpphy_set_tx_power_by_index(struct b43_wldev *dev, u8 index) 1352 1349 { 1353 1350 struct b43_phy_lp *lpphy = dev->phy.lp; 1351 + struct lpphy_tx_gains gains; 1352 + u32 iq_comp, tx_gain, coeff, rf_power; 1354 1353 1355 1354 lpphy->tx_pwr_idx_over = index; 1355 + lpphy_read_tx_pctl_mode_from_hardware(dev); 1356 1356 if (lpphy->txpctl_mode != B43_LPPHY_TXPCTL_OFF) 1357 1357 lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_SW); 1358 - 1359 - //TODO 1358 + if (dev->phy.rev >= 2) { 1359 + iq_comp = b43_lptab_read(dev, B43_LPTAB32(7, index + 320)); 1360 + tx_gain = b43_lptab_read(dev, B43_LPTAB32(7, index + 192)); 1361 + gains.pad = (tx_gain >> 16) & 0xFF; 1362 + gains.gm = tx_gain & 0xFF; 1363 + gains.pga = (tx_gain >> 8) & 0xFF; 1364 + gains.dac = (iq_comp >> 28) & 0xFF; 1365 + lpphy_set_tx_gains(dev, gains); 1366 + } else { 1367 + iq_comp = b43_lptab_read(dev, B43_LPTAB32(10, index + 320)); 1368 + tx_gain = b43_lptab_read(dev, B43_LPTAB32(10, index + 192)); 1369 + b43_phy_maskset(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL, 1370 + 0xF800, (tx_gain >> 4) & 0x7FFF); 1371 + lpphy_set_dac_gain(dev, tx_gain & 0x7); 1372 + lpphy_set_pa_gain(dev, (tx_gain >> 24) & 0x7F); 1373 + } 1374 + lpphy_set_bb_mult(dev, (iq_comp >> 20) & 0xFF); 1375 + lpphy_set_tx_iqcc(dev, (iq_comp >> 10) & 0x3FF, iq_comp & 0x3FF); 1376 + if (dev->phy.rev >= 2) { 1377 + coeff = b43_lptab_read(dev, B43_LPTAB32(7, index + 448)); 1378 + } else { 1379 + coeff = b43_lptab_read(dev, B43_LPTAB32(10, index + 448)); 1380 + } 1381 + b43_lptab_write(dev, B43_LPTAB16(0, 85), coeff & 0xFFFF); 1382 + if (dev->phy.rev >= 2) { 1383 + rf_power = b43_lptab_read(dev, B43_LPTAB32(7, index + 576)); 1384 + b43_phy_maskset(dev, B43_LPPHY_RF_PWR_OVERRIDE, 0xFF00, 1385 + rf_power & 0xFFFF);//SPEC FIXME mask & set != 0 1386 + } 1387 + lpphy_enable_tx_gain_override(dev); 1360 1388 } 1361 1389 1362 1390 static void lpphy_btcoex_override(struct b43_wldev *dev) ··· 1423 1335 b43_write16(dev, B43_MMIO_BTCOEX_TXCTL, 0xFF); 1424 1336 } 1425 1337 1426 - static void lpphy_pr41573_workaround(struct b43_wldev *dev) 1338 + static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev, 1339 + bool blocked) 1427 1340 { 1428 - struct b43_phy_lp *lpphy = dev->phy.lp; 1429 - u32 *saved_tab; 1430 - const unsigned int saved_tab_size = 256; 1431 - enum b43_lpphy_txpctl_mode txpctl_mode; 1432 - s8 tx_pwr_idx_over; 1433 - u16 tssi_npt, tssi_idx; 1434 - 1435 - saved_tab = kcalloc(saved_tab_size, sizeof(saved_tab[0]), GFP_KERNEL); 1436 - if (!saved_tab) { 1437 - b43err(dev->wl, "PR41573 failed. Out of memory!\n"); 1438 - return; 1439 - } 1440 - 1441 - lpphy_read_tx_pctl_mode_from_hardware(dev); 1442 - txpctl_mode = lpphy->txpctl_mode; 1443 - tx_pwr_idx_over = lpphy->tx_pwr_idx_over; 1444 - tssi_npt = lpphy->tssi_npt; 1445 - tssi_idx = lpphy->tssi_idx; 1446 - 1447 - if (dev->phy.rev < 2) { 1448 - b43_lptab_read_bulk(dev, B43_LPTAB32(10, 0x140), 1449 - saved_tab_size, saved_tab); 1341 + //TODO check MAC control register 1342 + if (blocked) { 1343 + if (dev->phy.rev >= 2) { 1344 + b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0x83FF); 1345 + b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1F00); 1346 + b43_phy_mask(dev, B43_LPPHY_AFE_DDFS, 0x80FF); 1347 + b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2_VAL, 0xDFFF); 1348 + b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x0808); 1349 + } else { 1350 + b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xE0FF); 1351 + b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1F00); 1352 + b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2_VAL, 0xFCFF); 1353 + b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x0018); 1354 + } 1450 1355 } else { 1451 - b43_lptab_read_bulk(dev, B43_LPTAB32(7, 0x140), 1452 - saved_tab_size, saved_tab); 1356 + b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xE0FF); 1357 + if (dev->phy.rev >= 2) 1358 + b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xF7F7); 1359 + else 1360 + b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFFE7); 1453 1361 } 1454 - //TODO 1455 - 1456 - kfree(saved_tab); 1457 1362 } 1458 1363 1459 - static void lpphy_calibration(struct b43_wldev *dev) 1364 + /* This was previously called lpphy_japan_filter */ 1365 + static void lpphy_set_analog_filter(struct b43_wldev *dev, int channel) 1460 1366 { 1461 1367 struct b43_phy_lp *lpphy = dev->phy.lp; 1462 - enum b43_lpphy_txpctl_mode saved_pctl_mode; 1368 + u16 tmp = (channel == 14); //SPEC FIXME check japanwidefilter! 1463 1369 1464 - b43_mac_suspend(dev); 1465 - 1466 - lpphy_btcoex_override(dev); 1467 - lpphy_read_tx_pctl_mode_from_hardware(dev); 1468 - saved_pctl_mode = lpphy->txpctl_mode; 1469 - lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF); 1470 - //TODO Perform transmit power table I/Q LO calibration 1471 - if ((dev->phy.rev == 0) && (saved_pctl_mode != B43_LPPHY_TXPCTL_OFF)) 1472 - lpphy_pr41573_workaround(dev); 1473 - //TODO If a full calibration has not been performed on this channel yet, perform PAPD TX-power calibration 1474 - lpphy_set_tx_power_control(dev, saved_pctl_mode); 1475 - //TODO Perform I/Q calibration with a single control value set 1476 - 1477 - b43_mac_enable(dev); 1370 + if (dev->phy.rev < 2) { //SPEC FIXME Isn't this rev0/1-specific? 1371 + b43_phy_maskset(dev, B43_LPPHY_LP_PHY_CTL, 0xFCFF, tmp << 9); 1372 + if ((dev->phy.rev == 1) && (lpphy->rc_cap)) 1373 + lpphy_set_rc_cap(dev); 1374 + } else { 1375 + b43_radio_write(dev, B2063_TX_BB_SP3, 0x3F); 1376 + } 1478 1377 } 1479 1378 1480 1379 static void lpphy_set_tssi_mux(struct b43_wldev *dev, enum tssi_mux_mode mode) ··· 1570 1495 } 1571 1496 } 1572 1497 1498 + static void lpphy_pr41573_workaround(struct b43_wldev *dev) 1499 + { 1500 + struct b43_phy_lp *lpphy = dev->phy.lp; 1501 + u32 *saved_tab; 1502 + const unsigned int saved_tab_size = 256; 1503 + enum b43_lpphy_txpctl_mode txpctl_mode; 1504 + s8 tx_pwr_idx_over; 1505 + u16 tssi_npt, tssi_idx; 1506 + 1507 + saved_tab = kcalloc(saved_tab_size, sizeof(saved_tab[0]), GFP_KERNEL); 1508 + if (!saved_tab) { 1509 + b43err(dev->wl, "PR41573 failed. Out of memory!\n"); 1510 + return; 1511 + } 1512 + 1513 + lpphy_read_tx_pctl_mode_from_hardware(dev); 1514 + txpctl_mode = lpphy->txpctl_mode; 1515 + tx_pwr_idx_over = lpphy->tx_pwr_idx_over; 1516 + tssi_npt = lpphy->tssi_npt; 1517 + tssi_idx = lpphy->tssi_idx; 1518 + 1519 + if (dev->phy.rev < 2) { 1520 + b43_lptab_read_bulk(dev, B43_LPTAB32(10, 0x140), 1521 + saved_tab_size, saved_tab); 1522 + } else { 1523 + b43_lptab_read_bulk(dev, B43_LPTAB32(7, 0x140), 1524 + saved_tab_size, saved_tab); 1525 + } 1526 + //FIXME PHY reset 1527 + lpphy_table_init(dev); //FIXME is table init needed? 1528 + lpphy_baseband_init(dev); 1529 + lpphy_tx_pctl_init(dev); 1530 + b43_lpphy_op_software_rfkill(dev, false); 1531 + lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF); 1532 + if (dev->phy.rev < 2) { 1533 + b43_lptab_write_bulk(dev, B43_LPTAB32(10, 0x140), 1534 + saved_tab_size, saved_tab); 1535 + } else { 1536 + b43_lptab_write_bulk(dev, B43_LPTAB32(7, 0x140), 1537 + saved_tab_size, saved_tab); 1538 + } 1539 + b43_write16(dev, B43_MMIO_CHANNEL, lpphy->channel); 1540 + lpphy->tssi_npt = tssi_npt; 1541 + lpphy->tssi_idx = tssi_idx; 1542 + lpphy_set_analog_filter(dev, lpphy->channel); 1543 + if (tx_pwr_idx_over != -1) 1544 + lpphy_set_tx_power_by_index(dev, tx_pwr_idx_over); 1545 + if (lpphy->rc_cap) 1546 + lpphy_set_rc_cap(dev); 1547 + b43_lpphy_op_set_rx_antenna(dev, lpphy->antenna); 1548 + lpphy_set_tx_power_control(dev, txpctl_mode); 1549 + kfree(saved_tab); 1550 + } 1551 + 1552 + struct lpphy_rx_iq_comp { u8 chan; s8 c1, c0; }; 1553 + 1554 + static const struct lpphy_rx_iq_comp lpphy_5354_iq_table[] = { 1555 + { .chan = 1, .c1 = -66, .c0 = 15, }, 1556 + { .chan = 2, .c1 = -66, .c0 = 15, }, 1557 + { .chan = 3, .c1 = -66, .c0 = 15, }, 1558 + { .chan = 4, .c1 = -66, .c0 = 15, }, 1559 + { .chan = 5, .c1 = -66, .c0 = 15, }, 1560 + { .chan = 6, .c1 = -66, .c0 = 15, }, 1561 + { .chan = 7, .c1 = -66, .c0 = 14, }, 1562 + { .chan = 8, .c1 = -66, .c0 = 14, }, 1563 + { .chan = 9, .c1 = -66, .c0 = 14, }, 1564 + { .chan = 10, .c1 = -66, .c0 = 14, }, 1565 + { .chan = 11, .c1 = -66, .c0 = 14, }, 1566 + { .chan = 12, .c1 = -66, .c0 = 13, }, 1567 + { .chan = 13, .c1 = -66, .c0 = 13, }, 1568 + { .chan = 14, .c1 = -66, .c0 = 13, }, 1569 + }; 1570 + 1571 + static const struct lpphy_rx_iq_comp lpphy_rev0_1_iq_table[] = { 1572 + { .chan = 1, .c1 = -64, .c0 = 13, }, 1573 + { .chan = 2, .c1 = -64, .c0 = 13, }, 1574 + { .chan = 3, .c1 = -64, .c0 = 13, }, 1575 + { .chan = 4, .c1 = -64, .c0 = 13, }, 1576 + { .chan = 5, .c1 = -64, .c0 = 12, }, 1577 + { .chan = 6, .c1 = -64, .c0 = 12, }, 1578 + { .chan = 7, .c1 = -64, .c0 = 12, }, 1579 + { .chan = 8, .c1 = -64, .c0 = 12, }, 1580 + { .chan = 9, .c1 = -64, .c0 = 12, }, 1581 + { .chan = 10, .c1 = -64, .c0 = 11, }, 1582 + { .chan = 11, .c1 = -64, .c0 = 11, }, 1583 + { .chan = 12, .c1 = -64, .c0 = 11, }, 1584 + { .chan = 13, .c1 = -64, .c0 = 11, }, 1585 + { .chan = 14, .c1 = -64, .c0 = 10, }, 1586 + { .chan = 34, .c1 = -62, .c0 = 24, }, 1587 + { .chan = 38, .c1 = -62, .c0 = 24, }, 1588 + { .chan = 42, .c1 = -62, .c0 = 24, }, 1589 + { .chan = 46, .c1 = -62, .c0 = 23, }, 1590 + { .chan = 36, .c1 = -62, .c0 = 24, }, 1591 + { .chan = 40, .c1 = -62, .c0 = 24, }, 1592 + { .chan = 44, .c1 = -62, .c0 = 23, }, 1593 + { .chan = 48, .c1 = -62, .c0 = 23, }, 1594 + { .chan = 52, .c1 = -62, .c0 = 23, }, 1595 + { .chan = 56, .c1 = -62, .c0 = 22, }, 1596 + { .chan = 60, .c1 = -62, .c0 = 22, }, 1597 + { .chan = 64, .c1 = -62, .c0 = 22, }, 1598 + { .chan = 100, .c1 = -62, .c0 = 16, }, 1599 + { .chan = 104, .c1 = -62, .c0 = 16, }, 1600 + { .chan = 108, .c1 = -62, .c0 = 15, }, 1601 + { .chan = 112, .c1 = -62, .c0 = 14, }, 1602 + { .chan = 116, .c1 = -62, .c0 = 14, }, 1603 + { .chan = 120, .c1 = -62, .c0 = 13, }, 1604 + { .chan = 124, .c1 = -62, .c0 = 12, }, 1605 + { .chan = 128, .c1 = -62, .c0 = 12, }, 1606 + { .chan = 132, .c1 = -62, .c0 = 12, }, 1607 + { .chan = 136, .c1 = -62, .c0 = 11, }, 1608 + { .chan = 140, .c1 = -62, .c0 = 10, }, 1609 + { .chan = 149, .c1 = -61, .c0 = 9, }, 1610 + { .chan = 153, .c1 = -61, .c0 = 9, }, 1611 + { .chan = 157, .c1 = -61, .c0 = 9, }, 1612 + { .chan = 161, .c1 = -61, .c0 = 8, }, 1613 + { .chan = 165, .c1 = -61, .c0 = 8, }, 1614 + { .chan = 184, .c1 = -62, .c0 = 25, }, 1615 + { .chan = 188, .c1 = -62, .c0 = 25, }, 1616 + { .chan = 192, .c1 = -62, .c0 = 25, }, 1617 + { .chan = 196, .c1 = -62, .c0 = 25, }, 1618 + { .chan = 200, .c1 = -62, .c0 = 25, }, 1619 + { .chan = 204, .c1 = -62, .c0 = 25, }, 1620 + { .chan = 208, .c1 = -62, .c0 = 25, }, 1621 + { .chan = 212, .c1 = -62, .c0 = 25, }, 1622 + { .chan = 216, .c1 = -62, .c0 = 26, }, 1623 + }; 1624 + 1625 + static const struct lpphy_rx_iq_comp lpphy_rev2plus_iq_comp = { 1626 + .chan = 0, 1627 + .c1 = -64, 1628 + .c0 = 0, 1629 + }; 1630 + 1631 + static u8 lpphy_nbits(s32 val) 1632 + { 1633 + u32 tmp = abs(val); 1634 + u8 nbits = 0; 1635 + 1636 + while (tmp != 0) { 1637 + nbits++; 1638 + tmp >>= 1; 1639 + } 1640 + 1641 + return nbits; 1642 + } 1643 + 1644 + static int lpphy_calc_rx_iq_comp(struct b43_wldev *dev, u16 samples) 1645 + { 1646 + struct lpphy_iq_est iq_est; 1647 + u16 c0, c1; 1648 + int prod, ipwr, qpwr, prod_msb, q_msb, tmp1, tmp2, tmp3, tmp4, ret; 1649 + 1650 + c1 = b43_phy_read(dev, B43_LPPHY_RX_COMP_COEFF_S); 1651 + c0 = c1 >> 8; 1652 + c1 |= 0xFF; 1653 + 1654 + b43_phy_maskset(dev, B43_LPPHY_RX_COMP_COEFF_S, 0xFF00, 0x00C0); 1655 + b43_phy_mask(dev, B43_LPPHY_RX_COMP_COEFF_S, 0x00FF); 1656 + 1657 + ret = lpphy_rx_iq_est(dev, samples, 32, &iq_est); 1658 + if (!ret) 1659 + goto out; 1660 + 1661 + prod = iq_est.iq_prod; 1662 + ipwr = iq_est.i_pwr; 1663 + qpwr = iq_est.q_pwr; 1664 + 1665 + if (ipwr + qpwr < 2) { 1666 + ret = 0; 1667 + goto out; 1668 + } 1669 + 1670 + prod_msb = lpphy_nbits(prod); 1671 + q_msb = lpphy_nbits(qpwr); 1672 + tmp1 = prod_msb - 20; 1673 + 1674 + if (tmp1 >= 0) { 1675 + tmp3 = ((prod << (30 - prod_msb)) + (ipwr >> (1 + tmp1))) / 1676 + (ipwr >> tmp1); 1677 + } else { 1678 + tmp3 = ((prod << (30 - prod_msb)) + (ipwr << (-1 - tmp1))) / 1679 + (ipwr << -tmp1); 1680 + } 1681 + 1682 + tmp2 = q_msb - 11; 1683 + 1684 + if (tmp2 >= 0) 1685 + tmp4 = (qpwr << (31 - q_msb)) / (ipwr >> tmp2); 1686 + else 1687 + tmp4 = (qpwr << (31 - q_msb)) / (ipwr << -tmp2); 1688 + 1689 + tmp4 -= tmp3 * tmp3; 1690 + tmp4 = -int_sqrt(tmp4); 1691 + 1692 + c0 = tmp3 >> 3; 1693 + c1 = tmp4 >> 4; 1694 + 1695 + out: 1696 + b43_phy_maskset(dev, B43_LPPHY_RX_COMP_COEFF_S, 0xFF00, c1); 1697 + b43_phy_maskset(dev, B43_LPPHY_RX_COMP_COEFF_S, 0x00FF, c0 << 8); 1698 + return ret; 1699 + } 1700 + 1701 + /* Complex number using 2 32-bit signed integers */ 1702 + typedef struct {s32 i, q;} lpphy_c32; 1703 + 1704 + static lpphy_c32 lpphy_cordic(int theta) 1705 + { 1706 + u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304, 1707 + 58666, 29335, 14668, 7334, 3667, 1833, 917, 458, 1708 + 229, 115, 57, 29, }; 1709 + int i, tmp, signx = 1, angle = 0; 1710 + lpphy_c32 ret = { .i = 39797, .q = 0, }; 1711 + 1712 + theta = clamp_t(int, theta, -180, 180); 1713 + 1714 + if (theta > 90) { 1715 + theta -= 180; 1716 + signx = -1; 1717 + } else if (theta < -90) { 1718 + theta += 180; 1719 + signx = -1; 1720 + } 1721 + 1722 + for (i = 0; i <= 17; i++) { 1723 + if (theta > angle) { 1724 + tmp = ret.i - (ret.q >> i); 1725 + ret.q += ret.i >> i; 1726 + ret.i = tmp; 1727 + angle += arctg[i]; 1728 + } else { 1729 + tmp = ret.i + (ret.q >> i); 1730 + ret.q -= ret.i >> i; 1731 + ret.i = tmp; 1732 + angle -= arctg[i]; 1733 + } 1734 + } 1735 + 1736 + ret.i *= signx; 1737 + ret.q *= signx; 1738 + 1739 + return ret; 1740 + } 1741 + 1742 + static void lpphy_run_samples(struct b43_wldev *dev, u16 samples, u16 loops, 1743 + u16 wait) 1744 + { 1745 + b43_phy_maskset(dev, B43_LPPHY_SMPL_PLAY_BUFFER_CTL, 1746 + 0xFFC0, samples - 1); 1747 + if (loops != 0xFFFF) 1748 + loops--; 1749 + b43_phy_maskset(dev, B43_LPPHY_SMPL_PLAY_COUNT, 0xF000, loops); 1750 + b43_phy_maskset(dev, B43_LPPHY_SMPL_PLAY_BUFFER_CTL, 0x3F, wait << 6); 1751 + b43_phy_set(dev, B43_LPPHY_A_PHY_CTL_ADDR, 0x1); 1752 + } 1753 + 1754 + //SPEC FIXME what does a negative freq mean? 1755 + static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max) 1756 + { 1757 + struct b43_phy_lp *lpphy = dev->phy.lp; 1758 + u16 buf[64]; 1759 + int i, samples = 0, angle = 0, rotation = (9 * freq) / 500; 1760 + lpphy_c32 sample; 1761 + 1762 + lpphy->tx_tone_freq = freq; 1763 + 1764 + if (freq) { 1765 + /* Find i for which abs(freq) integrally divides 20000 * i */ 1766 + for (i = 1; samples * abs(freq) != 20000 * i; i++) { 1767 + samples = (20000 * i) / abs(freq); 1768 + if(B43_WARN_ON(samples > 63)) 1769 + return; 1770 + } 1771 + } else { 1772 + samples = 2; 1773 + } 1774 + 1775 + for (i = 0; i < samples; i++) { 1776 + sample = lpphy_cordic(angle); 1777 + angle += rotation; 1778 + buf[i] = ((sample.i * max) & 0xFF) << 8; 1779 + buf[i] |= (sample.q * max) & 0xFF; 1780 + } 1781 + 1782 + b43_lptab_write_bulk(dev, B43_LPTAB16(5, 0), samples, buf); 1783 + 1784 + lpphy_run_samples(dev, samples, 0xFFFF, 0); 1785 + } 1786 + 1787 + static void lpphy_stop_tx_tone(struct b43_wldev *dev) 1788 + { 1789 + struct b43_phy_lp *lpphy = dev->phy.lp; 1790 + int i; 1791 + 1792 + lpphy->tx_tone_freq = 0; 1793 + 1794 + b43_phy_mask(dev, B43_LPPHY_SMPL_PLAY_COUNT, 0xF000); 1795 + for (i = 0; i < 31; i++) { 1796 + if (!(b43_phy_read(dev, B43_LPPHY_A_PHY_CTL_ADDR) & 0x1)) 1797 + break; 1798 + udelay(100); 1799 + } 1800 + } 1801 + 1802 + 1803 + static void lpphy_papd_cal(struct b43_wldev *dev, struct lpphy_tx_gains gains, 1804 + int mode, bool useindex, u8 index) 1805 + { 1806 + //TODO 1807 + } 1808 + 1809 + static void lpphy_papd_cal_txpwr(struct b43_wldev *dev) 1810 + { 1811 + struct b43_phy_lp *lpphy = dev->phy.lp; 1812 + struct ssb_bus *bus = dev->dev->bus; 1813 + struct lpphy_tx_gains gains, oldgains; 1814 + int old_txpctl, old_afe_ovr, old_rf, old_bbmult; 1815 + 1816 + lpphy_read_tx_pctl_mode_from_hardware(dev); 1817 + old_txpctl = lpphy->txpctl_mode; 1818 + old_afe_ovr = b43_phy_read(dev, B43_LPPHY_AFE_CTL_OVR) & 0x40; 1819 + if (old_afe_ovr) 1820 + oldgains = lpphy_get_tx_gains(dev); 1821 + old_rf = b43_phy_read(dev, B43_LPPHY_RF_PWR_OVERRIDE) & 0xFF; 1822 + old_bbmult = lpphy_get_bb_mult(dev); 1823 + 1824 + lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF); 1825 + 1826 + if (bus->chip_id == 0x4325 && bus->chip_rev == 0) 1827 + lpphy_papd_cal(dev, gains, 0, 1, 30); 1828 + else 1829 + lpphy_papd_cal(dev, gains, 0, 1, 65); 1830 + 1831 + if (old_afe_ovr) 1832 + lpphy_set_tx_gains(dev, oldgains); 1833 + lpphy_set_bb_mult(dev, old_bbmult); 1834 + lpphy_set_tx_power_control(dev, old_txpctl); 1835 + b43_phy_maskset(dev, B43_LPPHY_RF_PWR_OVERRIDE, 0xFF00, old_rf); 1836 + } 1837 + 1838 + static int lpphy_rx_iq_cal(struct b43_wldev *dev, bool noise, bool tx, 1839 + bool rx, bool pa, struct lpphy_tx_gains *gains) 1840 + { 1841 + struct b43_phy_lp *lpphy = dev->phy.lp; 1842 + struct ssb_bus *bus = dev->dev->bus; 1843 + const struct lpphy_rx_iq_comp *iqcomp = NULL; 1844 + struct lpphy_tx_gains nogains, oldgains; 1845 + u16 tmp; 1846 + int i, ret; 1847 + 1848 + memset(&nogains, 0, sizeof(nogains)); 1849 + memset(&oldgains, 0, sizeof(oldgains)); 1850 + 1851 + if (bus->chip_id == 0x5354) { 1852 + for (i = 0; i < ARRAY_SIZE(lpphy_5354_iq_table); i++) { 1853 + if (lpphy_5354_iq_table[i].chan == lpphy->channel) { 1854 + iqcomp = &lpphy_5354_iq_table[i]; 1855 + } 1856 + } 1857 + } else if (dev->phy.rev >= 2) { 1858 + iqcomp = &lpphy_rev2plus_iq_comp; 1859 + } else { 1860 + for (i = 0; i < ARRAY_SIZE(lpphy_rev0_1_iq_table); i++) { 1861 + if (lpphy_rev0_1_iq_table[i].chan == lpphy->channel) { 1862 + iqcomp = &lpphy_rev0_1_iq_table[i]; 1863 + } 1864 + } 1865 + } 1866 + 1867 + if (B43_WARN_ON(!iqcomp)) 1868 + return 0; 1869 + 1870 + b43_phy_maskset(dev, B43_LPPHY_RX_COMP_COEFF_S, 0xFF00, iqcomp->c1); 1871 + b43_phy_maskset(dev, B43_LPPHY_RX_COMP_COEFF_S, 1872 + 0x00FF, iqcomp->c0 << 8); 1873 + 1874 + if (noise) { 1875 + tx = true; 1876 + rx = false; 1877 + pa = false; 1878 + } 1879 + 1880 + lpphy_set_trsw_over(dev, tx, rx); 1881 + 1882 + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 1883 + b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x8); 1884 + b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 1885 + 0xFFF7, pa << 3); 1886 + } else { 1887 + b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x20); 1888 + b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 1889 + 0xFFDF, pa << 5); 1890 + } 1891 + 1892 + tmp = b43_phy_read(dev, B43_LPPHY_AFE_CTL_OVR) & 0x40; 1893 + 1894 + if (noise) 1895 + lpphy_set_rx_gain(dev, 0x2D5D); 1896 + else { 1897 + if (tmp) 1898 + oldgains = lpphy_get_tx_gains(dev); 1899 + if (!gains) 1900 + gains = &nogains; 1901 + lpphy_set_tx_gains(dev, *gains); 1902 + } 1903 + 1904 + b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVR, 0xFFFE); 1905 + b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0xFFFE); 1906 + b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x800); 1907 + b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0x800); 1908 + lpphy_set_deaf(dev, false); 1909 + if (noise) 1910 + ret = lpphy_calc_rx_iq_comp(dev, 0xFFF0); 1911 + else { 1912 + lpphy_start_tx_tone(dev, 4000, 100); 1913 + ret = lpphy_calc_rx_iq_comp(dev, 0x4000); 1914 + lpphy_stop_tx_tone(dev); 1915 + } 1916 + lpphy_clear_deaf(dev, false); 1917 + b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFFC); 1918 + b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFF7); 1919 + b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFDF); 1920 + if (!noise) { 1921 + if (tmp) 1922 + lpphy_set_tx_gains(dev, oldgains); 1923 + else 1924 + lpphy_disable_tx_gain_override(dev); 1925 + } 1926 + lpphy_disable_rx_gain_override(dev); 1927 + b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVR, 0xFFFE); 1928 + b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0xF7FF); 1929 + return ret; 1930 + } 1931 + 1932 + static void lpphy_calibration(struct b43_wldev *dev) 1933 + { 1934 + struct b43_phy_lp *lpphy = dev->phy.lp; 1935 + enum b43_lpphy_txpctl_mode saved_pctl_mode; 1936 + bool full_cal = false; 1937 + 1938 + if (lpphy->full_calib_chan != lpphy->channel) { 1939 + full_cal = true; 1940 + lpphy->full_calib_chan = lpphy->channel; 1941 + } 1942 + 1943 + b43_mac_suspend(dev); 1944 + 1945 + lpphy_btcoex_override(dev); 1946 + if (dev->phy.rev >= 2) 1947 + lpphy_save_dig_flt_state(dev); 1948 + lpphy_read_tx_pctl_mode_from_hardware(dev); 1949 + saved_pctl_mode = lpphy->txpctl_mode; 1950 + lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF); 1951 + //TODO Perform transmit power table I/Q LO calibration 1952 + if ((dev->phy.rev == 0) && (saved_pctl_mode != B43_LPPHY_TXPCTL_OFF)) 1953 + lpphy_pr41573_workaround(dev); 1954 + if ((dev->phy.rev >= 2) && full_cal) { 1955 + lpphy_papd_cal_txpwr(dev); 1956 + } 1957 + lpphy_set_tx_power_control(dev, saved_pctl_mode); 1958 + if (dev->phy.rev >= 2) 1959 + lpphy_restore_dig_flt_state(dev); 1960 + lpphy_rx_iq_cal(dev, true, true, false, false, NULL); 1961 + 1962 + b43_mac_enable(dev); 1963 + } 1964 + 1573 1965 static u16 b43_lpphy_op_read(struct b43_wldev *dev, u16 reg) 1574 1966 { 1575 1967 b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); ··· 2079 1537 2080 1538 b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg); 2081 1539 b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value); 2082 - } 2083 - 2084 - static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev, 2085 - bool blocked) 2086 - { 2087 - //TODO 2088 1540 } 2089 1541 2090 1542 struct b206x_channel { ··· 2546 2010 return err; 2547 2011 } 2548 2012 2549 - 2550 - /* This was previously called lpphy_japan_filter */ 2551 - static void lpphy_set_analog_filter(struct b43_wldev *dev, int channel) 2552 - { 2553 - struct b43_phy_lp *lpphy = dev->phy.lp; 2554 - u16 tmp = (channel == 14); //SPEC FIXME check japanwidefilter! 2555 - 2556 - if (dev->phy.rev < 2) { //SPEC FIXME Isn't this rev0/1-specific? 2557 - b43_phy_maskset(dev, B43_LPPHY_LP_PHY_CTL, 0xFCFF, tmp << 9); 2558 - if ((dev->phy.rev == 1) && (lpphy->rc_cap)) 2559 - lpphy_set_rc_cap(dev); 2560 - } else { 2561 - b43_radio_write(dev, B2063_TX_BB_SP3, 0x3F); 2562 - } 2563 - } 2564 - 2565 2013 static void lpphy_b2063_vco_calib(struct b43_wldev *dev) 2566 2014 { 2567 2015 u16 tmp; ··· 2730 2210 return 0; 2731 2211 } 2732 2212 2733 - static void b43_lpphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna) 2734 - { 2735 - if (dev->phy.rev >= 2) 2736 - return; // rev2+ doesn't support antenna diversity 2737 - 2738 - if (B43_WARN_ON(antenna > B43_ANTENNA_AUTO1)) 2739 - return; 2740 - 2741 - b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFFFD, antenna & 0x2); 2742 - b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFFFE, antenna & 0x1); 2743 - } 2744 - 2745 2213 static void b43_lpphy_op_adjust_txpower(struct b43_wldev *dev) 2746 2214 { 2747 2215 //TODO ··· 2752 2244 } 2753 2245 } 2754 2246 2247 + static void b43_lpphy_op_pwork_15sec(struct b43_wldev *dev) 2248 + { 2249 + //TODO 2250 + } 2251 + 2755 2252 const struct b43_phy_operations b43_phyops_lp = { 2756 2253 .allocate = b43_lpphy_op_allocate, 2757 2254 .free = b43_lpphy_op_free, ··· 2774 2261 .set_rx_antenna = b43_lpphy_op_set_rx_antenna, 2775 2262 .recalc_txpower = b43_lpphy_op_recalc_txpower, 2776 2263 .adjust_txpower = b43_lpphy_op_adjust_txpower, 2264 + .pwork_15sec = b43_lpphy_op_pwork_15sec, 2265 + .pwork_60sec = lpphy_calibration, 2777 2266 };
+9 -2
drivers/net/wireless/b43/phy_lp.h
··· 286 286 #define B43_LPPHY_TR_LOOKUP_6 B43_PHY_OFDM(0xC8) /* TR Lookup 6 */ 287 287 #define B43_LPPHY_TR_LOOKUP_7 B43_PHY_OFDM(0xC9) /* TR Lookup 7 */ 288 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 ··· 872 871 u8 rssi_gs; 873 872 874 873 /* RC cap */ 875 - u8 rc_cap; /* FIXME initial value? */ 874 + u8 rc_cap; 876 875 /* BX arch */ 877 876 u8 bx_arch; 878 877 879 878 /* Full calibration channel */ 880 - u8 full_calib_chan; /* FIXME initial value? */ 879 + u8 full_calib_chan; 881 880 882 881 /* Transmit iqlocal best coeffs */ 883 882 bool tx_iqloc_best_coeffs_valid; ··· 892 891 893 892 /* The channel we are tuned to */ 894 893 u8 channel; 894 + 895 + /* The active antenna diversity mode */ 896 + int antenna; 897 + 898 + /* Frequency of the active TX tone */ 899 + int tx_tone_freq; 895 900 }; 896 901 897 902 enum tssi_mux_mode {