aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/phy_n.c
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2010-01-15 10:20:56 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-01-15 17:05:43 -0500
commit15931e318b27e85ea06f44d53abc3d3e6a3fc9ff (patch)
tree56d023734066e338e73c427ad38428eab11d9e2c /drivers/net/wireless/b43/phy_n.c
parentfb43b8e23519f853f142202bb341c21382f39070 (diff)
b43: N-PHY: add RX IQ calibrationi for rev < 3
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43/phy_n.c')
-rw-r--r--drivers/net/wireless/b43/phy_n.c206
1 files changed, 202 insertions, 4 deletions
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 4111a4626001..f982f56d5bf3 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -1660,6 +1660,206 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
1660 return error; 1660 return error;
1661} 1661}
1662 1662
1663/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalRxIqRev2 */
1664static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
1665 struct nphy_txgains target, u8 type, bool debug)
1666{
1667 struct b43_phy_n *nphy = dev->phy.n;
1668 int i, j, index;
1669 u8 rfctl[2];
1670 u8 afectl_core;
1671 u16 tmp[6];
1672 u16 cur_hpf1, cur_hpf2, cur_lna;
1673 u32 real, imag;
1674 enum ieee80211_band band;
1675
1676 u8 use;
1677 u16 cur_hpf;
1678 u16 lna[3] = { 3, 3, 1 };
1679 u16 hpf1[3] = { 7, 2, 0 };
1680 u16 hpf2[3] = { 2, 0, 0 };
1681 u32 power[3];
1682 u16 gain_save[2];
1683 u16 cal_gain[2];
1684 struct nphy_iqcal_params cal_params[2];
1685 struct nphy_iq_est est;
1686 int ret = 0;
1687 bool playtone = true;
1688 int desired = 13;
1689
1690 b43_nphy_stay_in_carrier_search(dev, 1);
1691
1692 if (dev->phy.rev < 2)
1693 ;/* TODO: Call N PHY Reapply TX Cal Coeffs */
1694 /* TODO: Read an N PHY Table with ID 7, length 2, offset 0x110,
1695 width 16, and data gain_save */
1696 for (i = 0; i < 2; i++) {
1697 b43_nphy_iq_cal_gain_params(dev, i, target, &cal_params[i]);
1698 cal_gain[i] = cal_params[i].cal_gain;
1699 }
1700 /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110,
1701 width 16, and data from cal_gain */
1702
1703 for (i = 0; i < 2; i++) {
1704 if (i == 0) {
1705 rfctl[0] = B43_NPHY_RFCTL_INTC1;
1706 rfctl[1] = B43_NPHY_RFCTL_INTC2;
1707 afectl_core = B43_NPHY_AFECTL_C1;
1708 } else {
1709 rfctl[0] = B43_NPHY_RFCTL_INTC2;
1710 rfctl[1] = B43_NPHY_RFCTL_INTC1;
1711 afectl_core = B43_NPHY_AFECTL_C2;
1712 }
1713
1714 tmp[1] = b43_phy_read(dev, B43_NPHY_RFSEQCA);
1715 tmp[2] = b43_phy_read(dev, afectl_core);
1716 tmp[3] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
1717 tmp[4] = b43_phy_read(dev, rfctl[0]);
1718 tmp[5] = b43_phy_read(dev, rfctl[1]);
1719
1720 b43_phy_maskset(dev, B43_NPHY_RFSEQCA,
1721 (u16)~B43_NPHY_RFSEQCA_RXDIS,
1722 ((1 - i) << B43_NPHY_RFSEQCA_RXDIS_SHIFT));
1723 b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXEN,
1724 (1 - i));
1725 b43_phy_set(dev, afectl_core, 0x0006);
1726 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0006);
1727
1728 band = b43_current_band(dev->wl);
1729
1730 if (nphy->rxcalparams & 0xFF000000) {
1731 if (band == IEEE80211_BAND_5GHZ)
1732 b43_phy_write(dev, rfctl[0], 0x140);
1733 else
1734 b43_phy_write(dev, rfctl[0], 0x110);
1735 } else {
1736 if (band == IEEE80211_BAND_5GHZ)
1737 b43_phy_write(dev, rfctl[0], 0x180);
1738 else
1739 b43_phy_write(dev, rfctl[0], 0x120);
1740 }
1741
1742 if (band == IEEE80211_BAND_5GHZ)
1743 b43_phy_write(dev, rfctl[1], 0x148);
1744 else
1745 b43_phy_write(dev, rfctl[1], 0x114);
1746
1747 if (nphy->rxcalparams & 0x10000) {
1748 b43_radio_maskset(dev, B2055_C1_GENSPARE2, 0xFC,
1749 (i + 1));
1750 b43_radio_maskset(dev, B2055_C2_GENSPARE2, 0xFC,
1751 (2 - i));
1752 }
1753
1754 for (j = 0; i < 4; j++) {
1755 if (j < 3) {
1756 cur_lna = lna[j];
1757 cur_hpf1 = hpf1[j];
1758 cur_hpf2 = hpf2[j];
1759 } else {
1760 if (power[1] > 10000) {
1761 use = 1;
1762 cur_hpf = cur_hpf1;
1763 index = 2;
1764 } else {
1765 if (power[0] > 10000) {
1766 use = 1;
1767 cur_hpf = cur_hpf1;
1768 index = 1;
1769 } else {
1770 index = 0;
1771 use = 2;
1772 cur_hpf = cur_hpf2;
1773 }
1774 }
1775 cur_lna = lna[index];
1776 cur_hpf1 = hpf1[index];
1777 cur_hpf2 = hpf2[index];
1778 cur_hpf += desired - hweight32(power[index]);
1779 cur_hpf = clamp_val(cur_hpf, 0, 10);
1780 if (use == 1)
1781 cur_hpf1 = cur_hpf;
1782 else
1783 cur_hpf2 = cur_hpf;
1784 }
1785
1786 tmp[0] = ((cur_hpf2 << 8) | (cur_hpf1 << 4) |
1787 (cur_lna << 2));
1788 /* TODO:Call N PHY RF Ctrl Override with 0x400, tmp[0],
1789 3, 0 as arguments */
1790 /* TODO: Call N PHY Force RF Seq with 2 as argument */
1791 /* TODO: Call N PHT Stop Playback */
1792
1793 if (playtone) {
1794 /* TODO: Call N PHY TX Tone with 4000,
1795 (nphy_rxcalparams & 0xffff), 0, 0
1796 as arguments and save result as ret */
1797 playtone = false;
1798 } else {
1799 /* TODO: Call N PHY Run Samples with 160,
1800 0xFFFF, 0, 0, 0 as arguments */
1801 }
1802
1803 if (ret == 0) {
1804 if (j < 3) {
1805 b43_nphy_rx_iq_est(dev, &est, 1024, 32,
1806 false);
1807 if (i == 0) {
1808 real = est.i0_pwr;
1809 imag = est.q0_pwr;
1810 } else {
1811 real = est.i1_pwr;
1812 imag = est.q1_pwr;
1813 }
1814 power[i] = ((real + imag) / 1024) + 1;
1815 } else {
1816 b43_nphy_calc_rx_iq_comp(dev, 1 << i);
1817 }
1818 /* TODO: Call N PHY Stop Playback */
1819 }
1820
1821 if (ret != 0)
1822 break;
1823 }
1824
1825 b43_radio_mask(dev, B2055_C1_GENSPARE2, 0xFC);
1826 b43_radio_mask(dev, B2055_C2_GENSPARE2, 0xFC);
1827 b43_phy_write(dev, rfctl[1], tmp[5]);
1828 b43_phy_write(dev, rfctl[0], tmp[4]);
1829 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp[3]);
1830 b43_phy_write(dev, afectl_core, tmp[2]);
1831 b43_phy_write(dev, B43_NPHY_RFSEQCA, tmp[1]);
1832
1833 if (ret != 0)
1834 break;
1835 }
1836
1837 /* TODO: Call N PHY RF Ctrl Override with 0x400, 0, 3, 1 as arguments*/
1838 /* TODO: Call N PHY Force RF Seq with 2 as argument */
1839 /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110,
1840 width 16, and data from gain_save */
1841
1842 b43_nphy_stay_in_carrier_search(dev, 0);
1843
1844 return ret;
1845}
1846
1847static int b43_nphy_rev3_cal_rx_iq(struct b43_wldev *dev,
1848 struct nphy_txgains target, u8 type, bool debug)
1849{
1850 return -1;
1851}
1852
1853/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalRxIq */
1854static int b43_nphy_cal_rx_iq(struct b43_wldev *dev,
1855 struct nphy_txgains target, u8 type, bool debug)
1856{
1857 if (dev->phy.rev >= 3)
1858 return b43_nphy_rev3_cal_rx_iq(dev, target, type, debug);
1859 else
1860 return b43_nphy_rev2_cal_rx_iq(dev, target, type, debug);
1861}
1862
1663/* 1863/*
1664 * Init N-PHY 1864 * Init N-PHY
1665 * http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N 1865 * http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N
@@ -1831,16 +2031,14 @@ int b43_phy_initn(struct b43_wldev *dev)
1831 } 2031 }
1832 } 2032 }
1833 2033
1834 /*
1835 if (!b43_nphy_cal_tx_iq_lo(dev, target, true, false)) { 2034 if (!b43_nphy_cal_tx_iq_lo(dev, target, true, false)) {
1836 if (b43_nphy_cal_rx_iq(dev, target, 2, 0) == 0) 2035 if (b43_nphy_cal_rx_iq(dev, target, 2, 0) == 0)
1837 Call N PHY Save Cal 2036 ;/* Call N PHY Save Cal */
1838 else if (nphy->mphase_cal_phase_id == 0) 2037 else if (nphy->mphase_cal_phase_id == 0)
1839 N PHY Periodic Calibration with argument 3 2038 ;/* N PHY Periodic Calibration with argument 3 */
1840 } else { 2039 } else {
1841 b43_nphy_restore_cal(dev); 2040 b43_nphy_restore_cal(dev);
1842 } 2041 }
1843 */
1844 2042
1845 /* b43_nphy_tx_pwr_ctrl_coef_setup(dev); */ 2043 /* b43_nphy_tx_pwr_ctrl_coef_setup(dev); */
1846 /* TODO N PHY TX Power Control Enable with argument tx_pwr_state */ 2044 /* TODO N PHY TX Power Control Enable with argument tx_pwr_state */