diff options
author | Ben Cahill <ben.m.cahill@intel.com> | 2007-11-28 22:09:51 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:05:20 -0500 |
commit | f7d09d7c453f197d802c50172b27170a43e1a816 (patch) | |
tree | da98dbeb0e03fd500eab7e9a5ab915278caef311 /drivers/net | |
parent | abceddb40728397fcfd0b295d7530920a606ab88 (diff) |
iwlwifi: Document Rx calibration
Document Rx calibration
Signed-off-by: Ben Cahill <ben.m.cahill@intel.com>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965-commands.h | 267 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.h | 18 |
3 files changed, 261 insertions, 25 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-commands.h b/drivers/net/wireless/iwlwifi/iwl-4965-commands.h index 00d4ab7c7ace..575a065f8e5c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-commands.h | |||
@@ -1573,25 +1573,278 @@ struct iwl4965_missed_beacon_notif { | |||
1573 | __le32 num_recvd_beacons; | 1573 | __le32 num_recvd_beacons; |
1574 | } __attribute__ ((packed)); | 1574 | } __attribute__ ((packed)); |
1575 | 1575 | ||
1576 | |||
1576 | /****************************************************************************** | 1577 | /****************************************************************************** |
1577 | * (11) | 1578 | * (11) |
1578 | * Rx Calibration Commands: | 1579 | * Rx Calibration Commands: |
1579 | * | 1580 | * |
1581 | * With the uCode used for open source drivers, most Tx calibration (except | ||
1582 | * for Tx Power) and most Rx calibration is done by uCode during the | ||
1583 | * "initialize" phase of uCode boot. Driver must calibrate only: | ||
1584 | * | ||
1585 | * 1) Tx power (depends on temperature), described elsewhere | ||
1586 | * 2) Receiver gain balance (optimize MIMO, and detect disconnected antennas) | ||
1587 | * 3) Receiver sensitivity (to optimize signal detection) | ||
1588 | * | ||
1580 | *****************************************************************************/ | 1589 | *****************************************************************************/ |
1581 | 1590 | ||
1582 | #define PHY_CALIBRATE_DIFF_GAIN_CMD (7) | 1591 | /** |
1583 | #define HD_TABLE_SIZE (11) | 1592 | * SENSITIVITY_CMD = 0xa8 (command, has simple generic response) |
1593 | * | ||
1594 | * This command sets up the Rx signal detector for a sensitivity level that | ||
1595 | * is high enough to lock onto all signals within the associated network, | ||
1596 | * but low enough to ignore signals that are below a certain threshold, so as | ||
1597 | * not to have too many "false alarms". False alarms are signals that the | ||
1598 | * Rx DSP tries to lock onto, but then discards after determining that they | ||
1599 | * are noise. | ||
1600 | * | ||
1601 | * The optimum number of false alarms is between 5 and 50 per 200 TUs | ||
1602 | * (200 * 1024 uSecs, i.e. 204.8 milliseconds) of actual Rx time (i.e. | ||
1603 | * time listening, not transmitting). Driver must adjust sensitivity so that | ||
1604 | * the ratio of actual false alarms to actual Rx time falls within this range. | ||
1605 | * | ||
1606 | * While associated, uCode delivers STATISTICS_NOTIFICATIONs after each | ||
1607 | * received beacon. These provide information to the driver to analyze the | ||
1608 | * sensitivity. Don't analyze statistics that come in from scanning, or any | ||
1609 | * other non-associated-network source. Pertinent statistics include: | ||
1610 | * | ||
1611 | * From "general" statistics (struct statistics_rx_non_phy): | ||
1612 | * | ||
1613 | * (beacon_energy_[abc] & 0x0FF00) >> 8 (unsigned, higher value is lower level) | ||
1614 | * Measure of energy of desired signal. Used for establishing a level | ||
1615 | * below which the device does not detect signals. | ||
1616 | * | ||
1617 | * (beacon_silence_rssi_[abc] & 0x0FF00) >> 8 (unsigned, units in dB) | ||
1618 | * Measure of background noise in silent period after beacon. | ||
1619 | * | ||
1620 | * channel_load | ||
1621 | * uSecs of actual Rx time during beacon period (varies according to | ||
1622 | * how much time was spent transmitting). | ||
1623 | * | ||
1624 | * From "cck" and "ofdm" statistics (struct statistics_rx_phy), separately: | ||
1625 | * | ||
1626 | * false_alarm_cnt | ||
1627 | * Signal locks abandoned early (before phy-level header). | ||
1628 | * | ||
1629 | * plcp_err | ||
1630 | * Signal locks abandoned late (during phy-level header). | ||
1631 | * | ||
1632 | * NOTE: Both false_alarm_cnt and plcp_err increment monotonically from | ||
1633 | * beacon to beacon, i.e. each value is an accumulation of all errors | ||
1634 | * before and including the latest beacon. Values will wrap around to 0 | ||
1635 | * after counting up to 2^32 - 1. Driver must differentiate vs. | ||
1636 | * previous beacon's values to determine # false alarms in the current | ||
1637 | * beacon period. | ||
1638 | * | ||
1639 | * Total number of false alarms = false_alarms + plcp_errs | ||
1640 | * | ||
1641 | * For OFDM, adjust the following table entries in struct iwl_sensitivity_cmd | ||
1642 | * (notice that the start points for OFDM are at or close to settings for | ||
1643 | * maximum sensitivity): | ||
1644 | * | ||
1645 | * START / MIN / MAX | ||
1646 | * HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX 90 / 85 / 120 | ||
1647 | * HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX 170 / 170 / 210 | ||
1648 | * HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX 105 / 105 / 140 | ||
1649 | * HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX 220 / 220 / 270 | ||
1650 | * | ||
1651 | * If actual rate of OFDM false alarms (+ plcp_errors) is too high | ||
1652 | * (greater than 50 for each 204.8 msecs listening), reduce sensitivity | ||
1653 | * by *adding* 1 to all 4 of the table entries above, up to the max for | ||
1654 | * each entry. Conversely, if false alarm rate is too low (less than 5 | ||
1655 | * for each 204.8 msecs listening), *subtract* 1 from each entry to | ||
1656 | * increase sensitivity. | ||
1657 | * | ||
1658 | * For CCK sensitivity, keep track of the following: | ||
1659 | * | ||
1660 | * 1). 20-beacon history of maximum background noise, indicated by | ||
1661 | * (beacon_silence_rssi_[abc] & 0x0FF00), units in dB, across the | ||
1662 | * 3 receivers. For any given beacon, the "silence reference" is | ||
1663 | * the maximum of last 60 samples (20 beacons * 3 receivers). | ||
1664 | * | ||
1665 | * 2). 10-beacon history of strongest signal level, as indicated | ||
1666 | * by (beacon_energy_[abc] & 0x0FF00) >> 8, across the 3 receivers, | ||
1667 | * i.e. the strength of the signal through the best receiver at the | ||
1668 | * moment. These measurements are "upside down", with lower values | ||
1669 | * for stronger signals, so max energy will be *minimum* value. | ||
1670 | * | ||
1671 | * Then for any given beacon, the driver must determine the *weakest* | ||
1672 | * of the strongest signals; this is the minimum level that needs to be | ||
1673 | * successfully detected, when using the best receiver at the moment. | ||
1674 | * "Max cck energy" is the maximum (higher value means lower energy!) | ||
1675 | * of the last 10 minima. Once this is determined, driver must add | ||
1676 | * a little margin by adding "6" to it. | ||
1677 | * | ||
1678 | * 3). Number of consecutive beacon periods with too few false alarms. | ||
1679 | * Reset this to 0 at the first beacon period that falls within the | ||
1680 | * "good" range (5 to 50 false alarms per 204.8 milliseconds rx). | ||
1681 | * | ||
1682 | * Then, adjust the following CCK table entries in struct iwl_sensitivity_cmd | ||
1683 | * (notice that the start points for CCK are at maximum sensitivity): | ||
1684 | * | ||
1685 | * START / MIN / MAX | ||
1686 | * HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX 125 / 125 / 200 | ||
1687 | * HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX 200 / 200 / 400 | ||
1688 | * HD_MIN_ENERGY_CCK_DET_INDEX 100 / 0 / 100 | ||
1689 | * | ||
1690 | * If actual rate of CCK false alarms (+ plcp_errors) is too high | ||
1691 | * (greater than 50 for each 204.8 msecs listening), method for reducing | ||
1692 | * sensitivity is: | ||
1693 | * | ||
1694 | * 1) *Add* 3 to value in HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX, | ||
1695 | * up to max 400. | ||
1696 | * | ||
1697 | * 2) If current value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX is < 160, | ||
1698 | * sensitivity has been reduced a significant amount; bring it up to | ||
1699 | * a moderate 161. Otherwise, *add* 3, up to max 200. | ||
1700 | * | ||
1701 | * 3) a) If current value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX is > 160, | ||
1702 | * sensitivity has been reduced only a moderate or small amount; | ||
1703 | * *subtract* 2 from value in HD_MIN_ENERGY_CCK_DET_INDEX, | ||
1704 | * down to min 0. Otherwise (if gain has been significantly reduced), | ||
1705 | * don't change the HD_MIN_ENERGY_CCK_DET_INDEX value. | ||
1706 | * | ||
1707 | * b) Save a snapshot of the "silence reference". | ||
1708 | * | ||
1709 | * If actual rate of CCK false alarms (+ plcp_errors) is too low | ||
1710 | * (less than 5 for each 204.8 msecs listening), method for increasing | ||
1711 | * sensitivity is used only if: | ||
1712 | * | ||
1713 | * 1a) Previous beacon did not have too many false alarms | ||
1714 | * 1b) AND difference between previous "silence reference" and current | ||
1715 | * "silence reference" (prev - current) is 2 or more, | ||
1716 | * OR 2) 100 or more consecutive beacon periods have had rate of | ||
1717 | * less than 5 false alarms per 204.8 milliseconds rx time. | ||
1718 | * | ||
1719 | * Method for increasing sensitivity: | ||
1720 | * | ||
1721 | * 1) *Subtract* 3 from value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX, | ||
1722 | * down to min 125. | ||
1723 | * | ||
1724 | * 2) *Subtract* 3 from value in HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX, | ||
1725 | * down to min 200. | ||
1726 | * | ||
1727 | * 3) *Add* 2 to value in HD_MIN_ENERGY_CCK_DET_INDEX, up to max 100. | ||
1728 | * | ||
1729 | * If actual rate of CCK false alarms (+ plcp_errors) is within good range | ||
1730 | * (between 5 and 50 for each 204.8 msecs listening): | ||
1731 | * | ||
1732 | * 1) Save a snapshot of the silence reference. | ||
1733 | * | ||
1734 | * 2) If previous beacon had too many CCK false alarms (+ plcp_errors), | ||
1735 | * give some extra margin to energy threshold by *subtracting* 8 | ||
1736 | * from value in HD_MIN_ENERGY_CCK_DET_INDEX. | ||
1737 | * | ||
1738 | * For all cases (too few, too many, good range), make sure that the CCK | ||
1739 | * detection threshold (energy) is below the energy level for robust | ||
1740 | * detection over the past 10 beacon periods, the "Max cck energy". | ||
1741 | * Lower values mean higher energy; this means making sure that the value | ||
1742 | * in HD_MIN_ENERGY_CCK_DET_INDEX is at or *above* "Max cck energy". | ||
1743 | * | ||
1744 | * Driver should set the following entries to fixed values: | ||
1745 | * | ||
1746 | * HD_MIN_ENERGY_OFDM_DET_INDEX 100 | ||
1747 | * HD_BARKER_CORR_TH_ADD_MIN_INDEX 190 | ||
1748 | * HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX 390 | ||
1749 | * HD_OFDM_ENERGY_TH_IN_INDEX 62 | ||
1750 | */ | ||
1751 | |||
1752 | /* | ||
1753 | * Table entries in SENSITIVITY_CMD (struct iwl4965_sensitivity_cmd) | ||
1754 | */ | ||
1755 | #define HD_TABLE_SIZE (11) /* number of entries */ | ||
1756 | #define HD_MIN_ENERGY_CCK_DET_INDEX (0) /* table indexes */ | ||
1757 | #define HD_MIN_ENERGY_OFDM_DET_INDEX (1) | ||
1758 | #define HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX (2) | ||
1759 | #define HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX (3) | ||
1760 | #define HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX (4) | ||
1761 | #define HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX (5) | ||
1762 | #define HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX (6) | ||
1763 | #define HD_BARKER_CORR_TH_ADD_MIN_INDEX (7) | ||
1764 | #define HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX (8) | ||
1765 | #define HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX (9) | ||
1766 | #define HD_OFDM_ENERGY_TH_IN_INDEX (10) | ||
1767 | |||
1768 | /* Control field in struct iwl4965_sensitivity_cmd */ | ||
1769 | #define SENSITIVITY_CMD_CONTROL_DEFAULT_TABLE __constant_cpu_to_le16(0) | ||
1770 | #define SENSITIVITY_CMD_CONTROL_WORK_TABLE __constant_cpu_to_le16(1) | ||
1584 | 1771 | ||
1772 | /** | ||
1773 | * struct iwl4965_sensitivity_cmd | ||
1774 | * @control: (1) updates working table, (0) updates default table | ||
1775 | * @table: energy threshold values, use HD_* as index into table | ||
1776 | * | ||
1777 | * Always use "1" in "control" to update uCode's working table and DSP. | ||
1778 | */ | ||
1585 | struct iwl4965_sensitivity_cmd { | 1779 | struct iwl4965_sensitivity_cmd { |
1586 | __le16 control; | 1780 | __le16 control; /* always use "1" */ |
1587 | __le16 table[HD_TABLE_SIZE]; | 1781 | __le16 table[HD_TABLE_SIZE]; /* use HD_* as index */ |
1588 | } __attribute__ ((packed)); | 1782 | } __attribute__ ((packed)); |
1589 | 1783 | ||
1784 | |||
1785 | /** | ||
1786 | * REPLY_PHY_CALIBRATION_CMD = 0xb0 (command, has simple generic response) | ||
1787 | * | ||
1788 | * This command sets the relative gains of 4965's 3 radio receiver chains. | ||
1789 | * | ||
1790 | * After the first association, driver should accumulate signal and noise | ||
1791 | * statistics from the STATISTICS_NOTIFICATIONs that follow the first 20 | ||
1792 | * beacons from the associated network (don't collect statistics that come | ||
1793 | * in from scanning, or any other non-network source). | ||
1794 | * | ||
1795 | * DISCONNECTED ANTENNA: | ||
1796 | * | ||
1797 | * Driver should determine which antennas are actually connected, by comparing | ||
1798 | * average beacon signal levels for the 3 Rx chains. Accumulate (add) the | ||
1799 | * following values over 20 beacons, one accumulator for each of the chains | ||
1800 | * a/b/c, from struct statistics_rx_non_phy: | ||
1801 | * | ||
1802 | * beacon_rssi_[abc] & 0x0FF (unsigned, units in dB) | ||
1803 | * | ||
1804 | * Find the strongest signal from among a/b/c. Compare the other two to the | ||
1805 | * strongest. If any signal is more than 15 dB (times 20, unless you | ||
1806 | * divide the accumulated values by 20) below the strongest, the driver | ||
1807 | * considers that antenna to be disconnected, and should not try to use that | ||
1808 | * antenna/chain for Rx or Tx. If both A and B seem to be disconnected, | ||
1809 | * driver should declare the stronger one as connected, and attempt to use it | ||
1810 | * (A and B are the only 2 Tx chains!). | ||
1811 | * | ||
1812 | * | ||
1813 | * RX BALANCE: | ||
1814 | * | ||
1815 | * Driver should balance the 3 receivers (but just the ones that are connected | ||
1816 | * to antennas, see above) for gain, by comparing the average signal levels | ||
1817 | * detected during the silence after each beacon (background noise). | ||
1818 | * Accumulate (add) the following values over 20 beacons, one accumulator for | ||
1819 | * each of the chains a/b/c, from struct statistics_rx_non_phy: | ||
1820 | * | ||
1821 | * beacon_silence_rssi_[abc] & 0x0FF (unsigned, units in dB) | ||
1822 | * | ||
1823 | * Find the weakest background noise level from among a/b/c. This Rx chain | ||
1824 | * will be the reference, with 0 gain adjustment. Attenuate other channels by | ||
1825 | * finding noise difference: | ||
1826 | * | ||
1827 | * (accum_noise[i] - accum_noise[reference]) / 30 | ||
1828 | * | ||
1829 | * The "30" adjusts the dB in the 20 accumulated samples to units of 1.5 dB. | ||
1830 | * For use in diff_gain_[abc] fields of struct iwl_calibration_cmd, the | ||
1831 | * driver should limit the difference results to a range of 0-3 (0-4.5 dB), | ||
1832 | * and set bit 2 to indicate "reduce gain". The value for the reference | ||
1833 | * (weakest) chain should be "0". | ||
1834 | * | ||
1835 | * diff_gain_[abc] bit fields: | ||
1836 | * 2: (1) reduce gain, (0) increase gain | ||
1837 | * 1-0: amount of gain, units of 1.5 dB | ||
1838 | */ | ||
1839 | |||
1840 | /* "Differential Gain" opcode used in REPLY_PHY_CALIBRATION_CMD. */ | ||
1841 | #define PHY_CALIBRATE_DIFF_GAIN_CMD (7) | ||
1842 | |||
1590 | struct iwl4965_calibration_cmd { | 1843 | struct iwl4965_calibration_cmd { |
1591 | u8 opCode; | 1844 | u8 opCode; /* PHY_CALIBRATE_DIFF_GAIN_CMD (7) */ |
1592 | u8 flags; | 1845 | u8 flags; /* not used */ |
1593 | __le16 reserved; | 1846 | __le16 reserved; |
1594 | s8 diff_gain_a; | 1847 | s8 diff_gain_a; /* see above */ |
1595 | s8 diff_gain_b; | 1848 | s8 diff_gain_b; |
1596 | s8 diff_gain_c; | 1849 | s8 diff_gain_c; |
1597 | u8 reserved1; | 1850 | u8 reserved1; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 7d95de9d034a..d44166a599fc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -1068,6 +1068,7 @@ static int iwl4965_sensitivity_write(struct iwl4965_priv *priv, u8 flags) | |||
1068 | data->auto_corr_cck, data->auto_corr_cck_mrc, | 1068 | data->auto_corr_cck, data->auto_corr_cck_mrc, |
1069 | data->nrg_th_cck); | 1069 | data->nrg_th_cck); |
1070 | 1070 | ||
1071 | /* Update uCode's "work" table, and copy it to DSP */ | ||
1071 | cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE; | 1072 | cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE; |
1072 | 1073 | ||
1073 | if (flags & CMD_ASYNC) | 1074 | if (flags & CMD_ASYNC) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h index af3497442a4b..321767f5390e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965.h | |||
@@ -924,22 +924,6 @@ struct iwl4965_lq_mngr { | |||
924 | #define CAL_NUM_OF_BEACONS 20 | 924 | #define CAL_NUM_OF_BEACONS 20 |
925 | #define MAXIMUM_ALLOWED_PATHLOSS 15 | 925 | #define MAXIMUM_ALLOWED_PATHLOSS 15 |
926 | 926 | ||
927 | /* Param table within SENSITIVITY_CMD */ | ||
928 | #define HD_MIN_ENERGY_CCK_DET_INDEX (0) | ||
929 | #define HD_MIN_ENERGY_OFDM_DET_INDEX (1) | ||
930 | #define HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX (2) | ||
931 | #define HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX (3) | ||
932 | #define HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX (4) | ||
933 | #define HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX (5) | ||
934 | #define HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX (6) | ||
935 | #define HD_BARKER_CORR_TH_ADD_MIN_INDEX (7) | ||
936 | #define HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX (8) | ||
937 | #define HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX (9) | ||
938 | #define HD_OFDM_ENERGY_TH_IN_INDEX (10) | ||
939 | |||
940 | #define SENSITIVITY_CMD_CONTROL_DEFAULT_TABLE __constant_cpu_to_le16(0) | ||
941 | #define SENSITIVITY_CMD_CONTROL_WORK_TABLE __constant_cpu_to_le16(1) | ||
942 | |||
943 | #define CHAIN_NOISE_MAX_DELTA_GAIN_CODE 3 | 927 | #define CHAIN_NOISE_MAX_DELTA_GAIN_CODE 3 |
944 | 928 | ||
945 | #define MAX_FA_OFDM 50 | 929 | #define MAX_FA_OFDM 50 |
@@ -967,8 +951,6 @@ struct iwl4965_lq_mngr { | |||
967 | #define AUTO_CORR_STEP_CCK 3 | 951 | #define AUTO_CORR_STEP_CCK 3 |
968 | #define AUTO_CORR_MAX_TH_CCK 160 | 952 | #define AUTO_CORR_MAX_TH_CCK 160 |
969 | 953 | ||
970 | #define NRG_ALG 0 | ||
971 | #define AUTO_CORR_ALG 1 | ||
972 | #define NRG_DIFF 2 | 954 | #define NRG_DIFF 2 |
973 | #define NRG_STEP_CCK 2 | 955 | #define NRG_STEP_CCK 2 |
974 | #define NRG_MARGIN 8 | 956 | #define NRG_MARGIN 8 |