aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Cahill <ben.m.cahill@intel.com>2007-11-28 22:09:51 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:05:20 -0500
commitf7d09d7c453f197d802c50172b27170a43e1a816 (patch)
treeda98dbeb0e03fd500eab7e9a5ab915278caef311
parentabceddb40728397fcfd0b295d7530920a606ab88 (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>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-commands.h267
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.h18
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 */
1585struct iwl4965_sensitivity_cmd { 1779struct 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
1590struct iwl4965_calibration_cmd { 1843struct 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