diff -r b5505a985f24 linux/drivers/media/dvb/dvb-core/dvb_frontend.c
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c	Sat Feb 21 01:12:09 2009 +0400
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c	Tue Apr 07 18:19:22 2009 +0400
@@ -1004,8 +1004,8 @@
 	 */
 	/* Legacy	*/
 	if (fe->legacy) {
-		if ((fepriv->state & FESTATE_LOSTLOCK) && 
-		    (fe->ops.info.caps & FE_CAN_RECOVER) && 
+		if ((fepriv->state & FESTATE_LOSTLOCK) &&
+		    (fe->ops.info.caps & FE_CAN_RECOVER) &&
 		    (fepriv->max_drift == 0)) {
 
 			dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);
@@ -1487,6 +1487,13 @@
 		break;
 	}
 
+	case FE_STATISTICS_CAPS: {
+		struct fecap_statistics *stats_cap = parg;
+		memcpy(stats_cap, &fe->ops.statistics_caps, sizeof (struct fecap_statistics));
+		err = 0;
+		break;
+	}
+
 	case FE_READ_STATUS: {
 		fe_status_t* status = parg;
 
@@ -1502,6 +1509,17 @@
 			err = fe->ops.read_status(fe, status);
 		break;
 	}
+
+	case FE_SIGNAL_LEVEL:
+		if (fe->ops.read_level)
+			err = fe->ops.read_level(fe, (__u32 *) parg);
+		break;
+
+	case FE_SIGNAL_STATS:
+		if (fe->ops.read_stats)
+			err = fe->ops.read_stats(fe, (struct fesignal_stat *) parg);
+		break;
+
 	case FE_READ_BER:
 		if (fe->ops.read_ber)
 			err = fe->ops.read_ber(fe, (__u32*) parg);
@@ -1645,7 +1663,7 @@
 			break;
 		}
 
-		memcpy(&fepriv->parameters, parg, sizeof (struct dvb_frontend_parameters));		
+		memcpy(&fepriv->parameters, parg, sizeof (struct dvb_frontend_parameters));
 		memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings));
 		memcpy(&fetunesettings.parameters, parg, sizeof (struct dvb_frontend_parameters));
 
diff -r b5505a985f24 linux/drivers/media/dvb/dvb-core/dvb_frontend.h
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h	Sat Feb 21 01:12:09 2009 +0400
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h	Tue Apr 07 18:19:22 2009 +0400
@@ -72,7 +72,7 @@
 	unsigned int audmode;
 	u64 std;
 };
-	
+
 enum dvbfe_modcod {
 	DVBFE_MODCOD_DUMMY_PLFRAME	= 0,
 	DVBFE_MODCOD_QPSK_1_4,
@@ -250,6 +250,7 @@
 struct dvb_frontend_ops {
 
 	struct dvb_frontend_info info;
+	struct fecap_statistics statistics_caps;
 
 	void (*release)(struct dvb_frontend* fe);
 	void (*release_sec)(struct dvb_frontend* fe);
@@ -304,6 +305,9 @@
 	enum dvbfe_search (*search)(struct dvb_frontend *fe, struct dvbfe_params *fe_params);
 	int (*track)(struct dvb_frontend *fe, struct dvbfe_params *fe_params, int *delay);
 
+	int (*read_level)(struct dvb_frontend *fe, u32 *signal); /* Raw AGC level */
+	int (*read_stats)(struct dvb_frontend *fe, struct fesignal_stat *stat);
+
 	struct dvb_tuner_ops tuner_ops;
 	struct analog_demod_ops analog_ops;
 };
diff -r b5505a985f24 linux/drivers/media/dvb/frontends/stb0899_drv.c
--- a/linux/drivers/media/dvb/frontends/stb0899_drv.c	Sat Feb 21 01:12:09 2009 +0400
+++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c	Tue Apr 07 18:19:22 2009 +0400
@@ -1225,6 +1225,29 @@
 	return 0;
 }
 
+static int stb0899_read_level(struct dvb_frontend *fe, u32 *signal)
+{
+	/* TODO! */
+	return 0;
+}
+
+static int stb0899_read_stats(struct dvb_frontend *fe, struct fesignal_stat *stats)
+{
+	u16 snr, strength;
+	u32 ber;
+
+	stb0899_read_snr(fe, &snr);
+	stb0899_read_signal_strength(fe, &strength);
+	stb0899_read_ber(fe, &ber);
+
+	stats->quality = snr;
+	stats->strength = strength;
+	stats->error = ber;
+	stats->unc = 0;
+
+	return 0;
+}
+
 static int stb0899_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
 {
 	struct stb0899_state *state = fe->demodulator_priv;
@@ -2039,6 +2062,26 @@
 		.type			= FE_QPSK, /* with old API */
 	},
 
+	.statistics_caps = {
+		.quality = {
+			.params         = FE_QUALITY_CNR,
+			.scale          = FE_SCALE_dB,
+			.exponent       = -4,
+		},
+
+		.strength = {
+			.params         = FE_SCALE_dB,
+			.exponent       = -4,
+		},
+
+		.error = {
+			.params         = FE_ERROR_BER,
+			.exponent       = 7,
+		},
+
+		.unc = FE_UNC_UNKNOWN,
+	},
+
 	.release			= stb0899_release,
 	.init				= stb0899_init,
 	.sleep				= stb0899_sleep,
@@ -2059,6 +2102,9 @@
 	.read_signal_strength		= stb0899_read_signal_strength,
 	.read_status			= stb0899_read_status,
 	.read_ber			= stb0899_read_ber,
+
+	.read_level                     = stb0899_read_level,
+	.read_stats                     = stb0899_read_stats,
 
 	.set_voltage			= stb0899_set_voltage,
 	.set_tone			= stb0899_set_tone,
diff -r b5505a985f24 linux/include/linux/dvb/frontend.h
--- a/linux/include/linux/dvb/frontend.h	Sat Feb 21 01:12:09 2009 +0400
+++ b/linux/include/linux/dvb/frontend.h	Tue Apr 07 18:19:22 2009 +0400
@@ -645,4 +645,118 @@
 };
 #define DVBFE_GET_EVENT			_IOR('o', 86, struct dvbfe_event)
 
+/* Frontend General Statistics
+ * General parameters
+ * FE_*_UNKNOWN:
+ *	Parameter is unknown to the frontend and doesn't really
+ *	make any sense for an application.
+ *
+ * FE_*_RELATIVE:
+ *	Parameter is relative on the basis of a ceil - floor basis
+ *	Format is based on empirical test to determine
+ *	the floor and ceiling values. This format is exactly the
+ *	same format as the existing statistics implementation.
+ */
+enum fecap_quality_params {
+	FE_QUALITY_UNKNOWN		= 0,
+	FE_QUALITY_SNR			= (1 <<  0),
+	FE_QUALITY_CNR			= (1 <<  1),
+	FE_QUALITY_EsNo			= (1 <<  2),
+	FE_QUALITY_EbNo			= (1 <<  3),
+	FE_QUALITY_RELATIVE		= (1 << 31),
+};
+
+enum fecap_scale_params {
+	FE_SCALE_UNKNOWN		= 0,
+	FE_SCALE_dB			= (1 <<  0),
+	FE_SCALE_RELATIVE		= (1 << 31),
+};
+
+enum fecap_error_params {
+	FE_ERROR_UNKNOWN		= 0,
+	FE_ERROR_BER			= (1 <<  0),
+	FE_ERROR_PER			= (1 <<  1),
+	FE_ERROR_RELATIVE		= (1 << 31),
+};
+
+enum fecap_unc_params {
+	FE_UNC_UNKNOWN			= 0,
+	FE_UNC_RELATIVE			= (1 << 31),
+};
+
+/* General parameters
+ * width:
+ * 	Specifies the width of the field
+ *
+ * exponent:
+ *	Specifies the multiplier for the respective field
+ *	MSB:1bit indicates the signdness of the parameter
+ */
+struct fecap_quality {
+	enum fecap_quality_params	params;
+	enum fecap_scale_params		scale;
+
+	__u32				width;
+	__s32				exponent;
+};
+
+struct fecap_strength {
+	enum fecap_scale_params		params;
+	__u32				width;
+	__s32				exponent;
+};
+
+struct fecap_error {
+	enum fecap_error_params		params;
+	__u32 				width;
+	__s32 				exponent;
+};
+
+struct fecap_statistics {
+	struct fecap_quality		quality;
+	struct fecap_strength		strength;
+	struct fecap_error		error;
+	enum fecap_unc_params		unc;
+};
+
+/* FE_STATISTICS_CAPS
+ * Userspace query for frontend signal statistics capabilities
+ */
+#define FE_STATISTICS_CAPS		_IOR('o', 84, struct fecap_statistics)
+
+
+/* FE_SIGNAL_LEVEL
+ * This system call provides a direct monitor of the signal, without
+ * passing through the relevant processing chains. In many cases, it
+ * is simply considered as direct AGC1 scaled values. This parameter
+ * can generally be used to position an antenna to while looking at
+ * a peak of this value. This parameter can be read back, even when
+ * a frontend LOCK has not been achieved. Some microntroller based
+ * demodulators do not provide a direct access to the AGC on the
+ * demodulator, hence this parameter will be Unsupported for such
+ * devices.
+ */
+#define FE_SIGNAL_LEVEL			_IOR('o', 85, __u32)
+
+
+struct fesignal_stat {
+	__u32 quality;
+	__u32 strength;
+	__u32 error;
+	__u32 unc;
+};
+
+/* FE_SIGNAL_STATS
+ * This system call provides a snapshot of all the receiver system
+ * at any given point of time. System signal statistics are always
+ * computed with respect to time and is best obtained the nearest
+ * to each of the individual parameters in a time domain.
+ * Signal statistics are assumed, "at any given instance of time".
+ * It is not possible to get a snapshot at the exact single instance
+ * and hence we look at the nearest instance, in the time domain.
+ * The statistics are described by the FE_STATISTICS_CAPS ioctl,
+ * ie. based on the device capabilities.
+ */
+#define FE_SIGNAL_STATS			_IOR('o', 86, struct fesignal_stat)
+
 #endif /*_DVBFRONTEND_H_*/