diff options
| -rw-r--r-- | drivers/net/wireless/b43/phy_n.c | 206 |
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 */ | ||
| 1664 | static 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 | |||
| 1847 | static 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 */ | ||
| 1854 | static 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 */ |
