Search Linux Wireless

Re: [PATCH] rt2800: Initialize max_txpower to MAX_G_TXPOWER and MAX_A_TXPOWER respectively

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On Mon, Jun 4, 2012 at 1:08 PM, Stanislaw Gruszka <sgruszka@xxxxxxxxxx> wrote:
> On Tue, May 22, 2012 at 12:02:24PM +0200, Helmut Schaa wrote:
>> Btw. I've got a proof-of-concept patch for this but need to dig it up first.
>
> So, when you will post it  ? :-)

Now :D

However, treat this with care, and it still requires Tobias initial
cfg80211 patch  ...

Helmut

>From 44e01b6fcfa70fa2d015b30bab0cb1fb377dd3ca Mon Sep 17 00:00:00 2001
From: Helmut Schaa <helmut.schaa@xxxxxxxxxxxxxx>
Date: Mon, 4 Jun 2012 14:19:38 +0200
Subject: [PATCH] rt2x00: Allow txpower control on rt2800 devices
without eirp max tx power

Some rt2800 devices don't have their calibrated max eirp tx power in
their calibration data. For these devices we only allow tx power
reduction. As a calculation base we use the maximum allowed tx power as
imposed by the regulatory framework.

Signed-off-by: Helmut Schaa <helmut.schaa@xxxxxxxxxxxxxx>
---
 drivers/net/wireless/rt2x00/rt2800lib.c |   56 ++++++++++++++++++++++++++-----
 1 files changed, 47 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c
b/drivers/net/wireless/rt2x00/rt2800lib.c
index f028aa5..2304d0d 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2330,6 +2330,24 @@ static int rt2800_get_txpower_bw_comp(struct
rt2x00_dev *rt2x00dev,
 	return comp_value;
 }

+static int rt2800_get_txpower_reg_delta(struct rt2x00_dev *rt2x00dev,
+					int power_level)
+{
+	if (!test_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags))
+		return 0;
+
+	/*
+	 * XXX: We don't know the maximum transmit power of our hardware since
+	 * the EEPROM doesn't expose it. We only know that we are calibrated
+	 * to 100% tx power.
+	 *
+	 * Hence, we assume the regulatory limit that cfg80211 calulated for
+	 * the current channel is our maximum and if we are requested to lower
+	 * the value we just reduce our tx power accordingly.
+	 */
+	return power_level - rt2x00dev->hw->conf.channel->max_power;
+}
+
 static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int
is_rate_b,
 				   enum ieee80211_band band, int power_level,
 				   u8 txpower, int delta)
@@ -2341,9 +2359,6 @@ static u8 rt2800_compensate_txpower(struct
rt2x00_dev *rt2x00dev, int is_rate_b,
 	u8 eirp_txpower_criterion;
 	u8 reg_limit;

-	if (!((band == IEEE80211_BAND_5GHZ) && is_rate_b))
-		return txpower;
-
 	if (test_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags)) {
 		/*
 		 * Check if eirp txpower exceed txpower_limit.
@@ -2370,10 +2385,17 @@ static u8 rt2800_compensate_txpower(struct
rt2x00_dev *rt2x00dev, int is_rate_b,

 		reg_limit = (eirp_txpower > power_level) ?
 					(eirp_txpower - power_level) : 0;
-	} else
-		reg_limit = 0;

-	return txpower + delta - reg_limit;
+		return txpower + delta - reg_limit;
+	} else if (delta < 0) {
+		/*
+		 * For devices without calibrated max EIRP tx power only allow
+		 * tx power reduction.
+		 */
+		return txpower + delta;
+	}
+
+	return txpower;
 }

 static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
@@ -2399,13 +2421,29 @@ static void rt2800_config_txpower(struct
rt2x00_dev *rt2x00dev,
 	delta += rt2800_get_gain_calibration_delta(rt2x00dev);

 	/*
-	 * set to normal bbp tx power control mode: +/- 0dBm
+	 * Apply regulatory delta
+	 */
+	delta += rt2800_get_txpower_reg_delta(rt2x00dev, power_level);
+
+	/*
+	 * Set bbp tx power control mode
 	 */
 	rt2800_bbp_read(rt2x00dev, 1, &r1);
-	rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, 0);
+	if (delta <= -12) {
+		/* reduce tx power by 12 dBm */
+		rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, 2);
+		delta += 12;
+	} else if (delta <= -6) {
+		/* reduce tx power by 6 dBm */
+		rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, 1);
+		delta += 6;
+	} else {
+	 	/* set to normal bbp tx power control mode: +/- 0dBm */
+		rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, 0);
+	}
 	rt2800_bbp_write(rt2x00dev, 1, r1);
-	offset = TX_PWR_CFG_0;

+	offset = TX_PWR_CFG_0;
 	for (i = 0; i < EEPROM_TXPOWER_BYRATE_SIZE; i += 2) {
 		/* just to be safe */
 		if (offset > TX_PWR_CFG_4)
-- 
1.7.7
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux