Ejemplo n.º 1
0
/*
 * iwl_mvm_get_signal_strength - use new rx PHY INFO API
 * values are reported by the fw as positive values - need to negate
 * to obtain their dBM.  Account for missing antennas by replacing 0
 * values by -256dBm: practically 0 power and a non-feasible 8 bit value.
 */
static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
                                        struct iwl_rx_phy_info *phy_info,
                                        struct ieee80211_rx_status *rx_status)
{
    int energy_a, energy_b, energy_c, max_energy;
    u32 val;

    val =
        le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_ENERGY_ANT_ABC_IDX]);
    energy_a = (val & IWL_RX_INFO_ENERGY_ANT_A_MSK) >>
               IWL_RX_INFO_ENERGY_ANT_A_POS;
    energy_a = energy_a ? -energy_a : S8_MIN;
    energy_b = (val & IWL_RX_INFO_ENERGY_ANT_B_MSK) >>
               IWL_RX_INFO_ENERGY_ANT_B_POS;
    energy_b = energy_b ? -energy_b : S8_MIN;
    energy_c = (val & IWL_RX_INFO_ENERGY_ANT_C_MSK) >>
               IWL_RX_INFO_ENERGY_ANT_C_POS;
    energy_c = energy_c ? -energy_c : S8_MIN;
    max_energy = max(energy_a, energy_b);
    max_energy = max(max_energy, energy_c);

    IWL_DEBUG_STATS(mvm, "energy In A %d B %d C %d , and max %d\n",
                    energy_a, energy_b, energy_c, max_energy);

    rx_status->signal = max_energy;
    rx_status->chains = (le16_to_cpu(phy_info->phy_flags) &
                         RX_RES_PHY_FLAGS_ANTENNA)
                        >> RX_RES_PHY_FLAGS_ANTENNA_POS;
    rx_status->chain_signal[0] = energy_a;
    rx_status->chain_signal[1] = energy_b;
    rx_status->chain_signal[2] = energy_c;
}
Ejemplo n.º 2
0
static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
					struct iwl_rx_mpdu_desc *desc,
					struct ieee80211_rx_status *rx_status)
{
	int energy_a, energy_b, max_energy;

	energy_a = desc->energy_a;
	energy_a = energy_a ? -energy_a : S8_MIN;
	energy_b = desc->energy_b;
	energy_b = energy_b ? -energy_b : S8_MIN;
	max_energy = max(energy_a, energy_b);

	IWL_DEBUG_STATS(mvm, "energy In A %d B %d, and max %d\n",
			energy_a, energy_b, max_energy);

	rx_status->signal = max_energy;
	rx_status->chains = 0; /* TODO: phy info */
	rx_status->chain_signal[0] = energy_a;
	rx_status->chain_signal[1] = energy_b;
	rx_status->chain_signal[2] = S8_MIN;
}
Ejemplo n.º 3
0
static void iwl_mvm_calc_rssi(struct iwl_mvm *mvm,
			      struct iwl_rx_phy_info *phy_info,
			      struct ieee80211_rx_status *rx_status)
{
	int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm;
	int rssi_all_band_a, rssi_all_band_b;
	u32 agc_a, agc_b, max_agc;
	u32 val;

	val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]);
	agc_a = (val & IWL_OFDM_AGC_A_MSK) >> IWL_OFDM_AGC_A_POS;
	agc_b = (val & IWL_OFDM_AGC_B_MSK) >> IWL_OFDM_AGC_B_POS;
	max_agc = max_t(u32, agc_a, agc_b);

	val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_AB_IDX]);
	rssi_a = (val & IWL_OFDM_RSSI_INBAND_A_MSK) >> IWL_OFDM_RSSI_A_POS;
	rssi_b = (val & IWL_OFDM_RSSI_INBAND_B_MSK) >> IWL_OFDM_RSSI_B_POS;
	rssi_all_band_a = (val & IWL_OFDM_RSSI_ALLBAND_A_MSK) >>
				IWL_OFDM_RSSI_ALLBAND_A_POS;
	rssi_all_band_b = (val & IWL_OFDM_RSSI_ALLBAND_B_MSK) >>
				IWL_OFDM_RSSI_ALLBAND_B_POS;

	/*
	 * dBm = rssi dB - agc dB - constant.
	 * Higher AGC (higher radio gain) means lower signal.
	 */
	rssi_a_dbm = rssi_a - IWL_RSSI_OFFSET - agc_a;
	rssi_b_dbm = rssi_b - IWL_RSSI_OFFSET - agc_b;
	max_rssi_dbm = max_t(int, rssi_a_dbm, rssi_b_dbm);

	IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d Max %d AGCA %d AGCB %d\n",
			rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b);

	rx_status->signal = max_rssi_dbm;
	rx_status->chains = (le16_to_cpu(phy_info->phy_flags) &
				RX_RES_PHY_FLAGS_ANTENNA)
					>> RX_RES_PHY_FLAGS_ANTENNA_POS;
	rx_status->chain_signal[0] = rssi_a_dbm;
	rx_status->chain_signal[1] = rssi_b_dbm;
}
Ejemplo n.º 4
0
/*
 * iwl_mvm_calc_rssi - calculate the rssi in dBm
 * @phy_info: the phy information for the coming packet
 */
static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm,
			     struct iwl_rx_phy_info *phy_info)
{
	int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm;
	int rssi_all_band_a, rssi_all_band_b;
	u32 agc_a, agc_b, max_agc;
	u32 val;

	/* Find max rssi among 2 possible receivers.
	 * These values are measured by the Digital Signal Processor (DSP).
	 * They should stay fairly constant even as the signal strength varies,
	 * if the radio's Automatic Gain Control (AGC) is working right.
	 * AGC value (see below) will provide the "interesting" info.
	 */
	val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]);
	agc_a = (val & IWL_OFDM_AGC_A_MSK) >> IWL_OFDM_AGC_A_POS;
	agc_b = (val & IWL_OFDM_AGC_B_MSK) >> IWL_OFDM_AGC_B_POS;
	max_agc = max_t(u32, agc_a, agc_b);

	val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_AB_IDX]);
	rssi_a = (val & IWL_OFDM_RSSI_INBAND_A_MSK) >> IWL_OFDM_RSSI_A_POS;
	rssi_b = (val & IWL_OFDM_RSSI_INBAND_B_MSK) >> IWL_OFDM_RSSI_B_POS;
	rssi_all_band_a = (val & IWL_OFDM_RSSI_ALLBAND_A_MSK) >>
				IWL_OFDM_RSSI_ALLBAND_A_POS;
	rssi_all_band_b = (val & IWL_OFDM_RSSI_ALLBAND_B_MSK) >>
				IWL_OFDM_RSSI_ALLBAND_B_POS;

	/*
	 * dBm = rssi dB - agc dB - constant.
	 * Higher AGC (higher radio gain) means lower signal.
	 */
	rssi_a_dbm = rssi_a - IWL_RSSI_OFFSET - agc_a;
	rssi_b_dbm = rssi_b - IWL_RSSI_OFFSET - agc_b;
	max_rssi_dbm = max_t(int, rssi_a_dbm, rssi_b_dbm);

	IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d Max %d AGCA %d AGCB %d\n",
			rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b);

	return max_rssi_dbm;
}
Ejemplo n.º 5
0
/* Calc max signal level (dBm) among 3 possible receivers */
static int iwlagn_calc_rssi(struct iwl_priv *priv,
			     struct iwl_rx_phy_res *rx_resp)
{
	/* data from PHY/DSP regarding signal strength, etc.,
	 *   contents are always there, not configurable by host
	 */
	struct iwlagn_non_cfg_phy *ncphy =
		(struct iwlagn_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
	u32 val, rssi_a, rssi_b, rssi_c, max_rssi;
	u8 agc;

	val  = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_AGC_IDX]);
	agc = (val & IWLAGN_OFDM_AGC_MSK) >> IWLAGN_OFDM_AGC_BIT_POS;

	/* Find max rssi among 3 possible receivers.
	 * These values are measured by the digital signal processor (DSP).
	 * They should stay fairly constant even as the signal strength varies,
	 *   if the radio's automatic gain control (AGC) is working right.
	 * AGC value (see below) will provide the "interesting" info.
	 */
	val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_AB_IDX]);
	rssi_a = (val & IWLAGN_OFDM_RSSI_INBAND_A_BITMSK) >>
		IWLAGN_OFDM_RSSI_A_BIT_POS;
	rssi_b = (val & IWLAGN_OFDM_RSSI_INBAND_B_BITMSK) >>
		IWLAGN_OFDM_RSSI_B_BIT_POS;
	val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_C_IDX]);
	rssi_c = (val & IWLAGN_OFDM_RSSI_INBAND_C_BITMSK) >>
		IWLAGN_OFDM_RSSI_C_BIT_POS;

	max_rssi = max_t(u32, rssi_a, rssi_b);
	max_rssi = max_t(u32, max_rssi, rssi_c);

	IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n",
		rssi_a, rssi_b, rssi_c, max_rssi, agc);

	/* dBm = max_rssi dB - agc dB - constant.
	 * Higher AGC (higher radio gain) means lower signal. */
	return max_rssi - agc - IWLAGN_RSSI_OFFSET;
}