aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-5000.c
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2008-08-04 04:00:42 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-08-04 15:09:12 -0400
commitcaab8f1a5d0da583b6ffe41afea2774c676444ca (patch)
treea732088119050a566e00d44d05976d9a4363379d /drivers/net/wireless/iwlwifi/iwl-5000.c
parentda99c4b6c25964b90c79f19beccda208df1a865a (diff)
iwlwifi: implement iwl5000_calc_rssi
This patch implements rssi calculation for 5000 HW. Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-5000.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 56dbc8144a34..c5b104fd149c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1459,6 +1459,44 @@ static void iwl5000_temperature(struct iwl_priv *priv)
1459 priv->temperature = le32_to_cpu(priv->statistics.general.temperature); 1459 priv->temperature = le32_to_cpu(priv->statistics.general.temperature);
1460} 1460}
1461 1461
1462/* Calc max signal level (dBm) among 3 possible receivers */
1463static int iwl5000_calc_rssi(struct iwl_priv *priv,
1464 struct iwl_rx_phy_res *rx_resp)
1465{
1466 /* data from PHY/DSP regarding signal strength, etc.,
1467 * contents are always there, not configurable by host
1468 */
1469 struct iwl5000_non_cfg_phy *ncphy =
1470 (struct iwl5000_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
1471 u32 val, rssi_a, rssi_b, rssi_c, max_rssi;
1472 u8 agc;
1473
1474 val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_AGC_IDX]);
1475 agc = (val & IWL50_OFDM_AGC_MSK) >> IWL50_OFDM_AGC_BIT_POS;
1476
1477 /* Find max rssi among 3 possible receivers.
1478 * These values are measured by the digital signal processor (DSP).
1479 * They should stay fairly constant even as the signal strength varies,
1480 * if the radio's automatic gain control (AGC) is working right.
1481 * AGC value (see below) will provide the "interesting" info.
1482 */
1483 val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_AB_IDX]);
1484 rssi_a = (val & IWL50_OFDM_RSSI_A_MSK) >> IWL50_OFDM_RSSI_A_BIT_POS;
1485 rssi_b = (val & IWL50_OFDM_RSSI_B_MSK) >> IWL50_OFDM_RSSI_B_BIT_POS;
1486 val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_C_IDX]);
1487 rssi_c = (val & IWL50_OFDM_RSSI_C_MSK) >> IWL50_OFDM_RSSI_C_BIT_POS;
1488
1489 max_rssi = max_t(u32, rssi_a, rssi_b);
1490 max_rssi = max_t(u32, max_rssi, rssi_c);
1491
1492 IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
1493 rssi_a, rssi_b, rssi_c, max_rssi, agc);
1494
1495 /* dBm = max_rssi dB - agc dB - constant.
1496 * Higher AGC (higher radio gain) means lower signal. */
1497 return max_rssi - agc - IWL_RSSI_OFFSET;
1498}
1499
1462static struct iwl_hcmd_ops iwl5000_hcmd = { 1500static struct iwl_hcmd_ops iwl5000_hcmd = {
1463 .rxon_assoc = iwl5000_send_rxon_assoc, 1501 .rxon_assoc = iwl5000_send_rxon_assoc,
1464}; 1502};
@@ -1469,6 +1507,7 @@ static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
1469 .gain_computation = iwl5000_gain_computation, 1507 .gain_computation = iwl5000_gain_computation,
1470 .chain_noise_reset = iwl5000_chain_noise_reset, 1508 .chain_noise_reset = iwl5000_chain_noise_reset,
1471 .rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag, 1509 .rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag,
1510 .calc_rssi = iwl5000_calc_rssi,
1472}; 1511};
1473 1512
1474static struct iwl_lib_ops iwl5000_lib = { 1513static struct iwl_lib_ops iwl5000_lib = {