diff mbox

[1/2] mac80211: Add support of transmit power control (TPC) per data packet

Message ID 1343404809-70329-2-git-send-email-thomas@net.t-labs.tu-berlin.de (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Thomas Huehn July 27, 2012, 4 p.m. UTC
This patch creates a transmit power control (TPC) API for data packets.
It enables a per multi-rate-retry stage annotaion of power-levelvalue
in dBm for each data packet via ieee80211_tx_info->control.Necessary
flags are defined to specify and map hardware specific TPC capabilities
to mac80211. Someone can specify transmit power control capabilities to
the stack via:

@IEEE80211_HW_SUPPORTS_TPC_DATA_PACKET:
	One power level per data packet can be processed. Each data
	packet with all its potential retries is send out at this
	individual power level.

@IEEE80211_HW_SUPPORTS_TPC_DATA_MRR
	One power levels per multi-rate-retry stage can be processed.
	Each retry stage of a data packet is send out at its individual
	power level.

Signed-off-by: Thomas Huehn <thomas@net.t-labs.tu-berlin.de>
Signed-off-by: Alina Friedrichsen <x-alina@gmx.net>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 include/net/mac80211.h | 41 +++++++++++++++++++++++++++--------------
 net/mac80211/rate.c    |  1 +
 2 files changed, 28 insertions(+), 14 deletions(-)

Comments

Johannes Berg July 30, 2012, 7:34 a.m. UTC | #1
On Fri, 2012-07-27 at 18:00 +0200, Thomas Huehn wrote:

>   * &struct ieee80211_tx_info contains an array of these structs
> - * in the control information, and it will be filled by the rate
> - * control algorithm according to what should be sent. For example,
> - * if this array contains, in the format { <idx>, <count> } the
> + * in the control information, and it will be filled by the joint rate-
> + * power control algorithm according to what should be sent. For example,
> + * if this array contains, in the format { <idx>, <count>, <tpc> } the
>   * information
> - *    { 3, 2 }, { 2, 2 }, { 1, 4 }, { -1, 0 }, { -1, 0 }
> + *    { 3, 2, 16 }, { 2, 2, 10 }, { 1, 4, 5 }, { -1, 0, 0 }
>   * then this means that the frame should be transmitted
> - * up to twice at rate 3, up to twice at rate 2, and up to four
> - * times at rate 1 if it doesn't get acknowledged. Say it gets
> - * acknowledged by the peer after the fifth attempt, the status
> + * up to twice at rate 3 with 16 dBm, up to twice at rate 2 with 10 dBm,

You might want to consider using 1/2 or 1/4 dBm granularity? A lot of
hardware can do that.

>  struct ieee80211_tx_rate {
>  	s8 idx;
>  	u8 count;
>  	u8 flags;
> +	u8 tpc;

I'm not sure that should be named "tpc". Think about what that means --
"transmit power control", but it's really the power value, so it should
be "txpower" or so.

johannes

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Thomas Huehn July 30, 2012, 11:29 a.m. UTC | #2
Hi Johannes

Johannes Berg schrieb:

> On Fri, 2012-07-27 at 18:00 +0200, Thomas Huehn wrote:
> 
>>   * &struct ieee80211_tx_info contains an array of these structs
>> - * in the control information, and it will be filled by the rate
>> - * control algorithm according to what should be sent. For example,
>> - * if this array contains, in the format { <idx>, <count> } the
>> + * in the control information, and it will be filled by the joint rate-
>> + * power control algorithm according to what should be sent. For example,
>> + * if this array contains, in the format { <idx>, <count>, <tpc> } the
>>   * information
>> - *    { 3, 2 }, { 2, 2 }, { 1, 4 }, { -1, 0 }, { -1, 0 }
>> + *    { 3, 2, 16 }, { 2, 2, 10 }, { 1, 4, 5 }, { -1, 0, 0 }
>>   * then this means that the frame should be transmitted
>> - * up to twice at rate 3, up to twice at rate 2, and up to four
>> - * times at rate 1 if it doesn't get acknowledged. Say it gets
>> - * acknowledged by the peer after the fifth attempt, the status
>> + * up to twice at rate 3 with 16 dBm, up to twice at rate 2 with 10 dBm,
> 
> You might want to consider using 1/2 or 1/4 dBm granularity? A lot of
> hardware can do that.
> 


The choice of 1 dBm as step width was based on our experiments with
Atheros chips that do support up to 0,5dBm step width. We concluded that
1dBm is sufficient as it provides 20 steps from 1 till 100 mWatt as
dynamic range of control. But there is no problem for my tpc algorithm
to handle a granularity of 0.5 dBm as step size, or any other upcoming
tpc controller. Should we gather some feedback about todays hardware
specs in terms of tx_power abilities? Or should I just apply 0.5 dBm
steps in v2 ?


>>  struct ieee80211_tx_rate {
>>  	s8 idx;
>>  	u8 count;
>>  	u8 flags;
>> +	u8 tpc;
> 
> I'm not sure that should be named "tpc". Think about what that means --
> "transmit power control", but it's really the power value, so it should
> be "txpower" or so.
> 


I will change this to tx_power in v2, sounds reasonable.

Greetings Thomas
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Johannes Berg July 30, 2012, 1:38 p.m. UTC | #3
On Mon, 2012-07-30 at 13:29 +0200, Thomas Huehn wrote:

> >> - *    { 3, 2 }, { 2, 2 }, { 1, 4 }, { -1, 0 }, { -1, 0 }
> >> + *    { 3, 2, 16 }, { 2, 2, 10 }, { 1, 4, 5 }, { -1, 0, 0 }
> >>   * then this means that the frame should be transmitted
> >> - * up to twice at rate 3, up to twice at rate 2, and up to four
> >> - * times at rate 1 if it doesn't get acknowledged. Say it gets
> >> - * acknowledged by the peer after the fifth attempt, the status
> >> + * up to twice at rate 3 with 16 dBm, up to twice at rate 2 with 10 dBm,
> > 
> > You might want to consider using 1/2 or 1/4 dBm granularity? A lot of
> > hardware can do that.
> > 
> 
> 
> The choice of 1 dBm as step width was based on our experiments with
> Atheros chips that do support up to 0,5dBm step width. We concluded that
> 1dBm is sufficient as it provides 20 steps from 1 till 100 mWatt as
> dynamic range of control. But there is no problem for my tpc algorithm
> to handle a granularity of 0.5 dBm as step size, or any other upcoming
> tpc controller. Should we gather some feedback about todays hardware
> specs in terms of tx_power abilities? Or should I just apply 0.5 dBm
> steps in v2 ?

I have no idea, it was really just a thought. I believe Broadcom HW can
handle 1/4 dBm, but then you'd have to know what the granularity really
is otherwise it all doesn't make much sense...

It really only gets interesting if there's a limit (regulatory or
otherwise) that isn't a full dBm, because then the algorithm couldn't
use the maximum permitted power, right? Say there's a 14.5 dBm limit,
then the algorithm could only go up to 14 dBm.

johannes

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 8114f59..27ef037 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -491,32 +491,35 @@  enum mac80211_rate_control_flags {
  * @idx: rate index to attempt to send with
  * @flags: rate control flags (&enum mac80211_rate_control_flags)
  * @count: number of tries in this rate before going to the next rate
+ * @tpc: transmit power level in dBm per packet multi-rate-retry (mrr) stage
  *
  * A value of -1 for @idx indicates an invalid rate and, if used
  * in an array of retry rates, that no more rates should be tried.
  *
  * When used for transmit status reporting, the driver should
- * always report the rate along with the flags it used.
+ * always report the rate  and power along with the flags it used.
  *
  * &struct ieee80211_tx_info contains an array of these structs
- * in the control information, and it will be filled by the rate
- * control algorithm according to what should be sent. For example,
- * if this array contains, in the format { <idx>, <count> } the
+ * in the control information, and it will be filled by the joint rate-
+ * power control algorithm according to what should be sent. For example,
+ * if this array contains, in the format { <idx>, <count>, <tpc> } the
  * information
- *    { 3, 2 }, { 2, 2 }, { 1, 4 }, { -1, 0 }, { -1, 0 }
+ *    { 3, 2, 16 }, { 2, 2, 10 }, { 1, 4, 5 }, { -1, 0, 0 }
  * then this means that the frame should be transmitted
- * up to twice at rate 3, up to twice at rate 2, and up to four
- * times at rate 1 if it doesn't get acknowledged. Say it gets
- * acknowledged by the peer after the fifth attempt, the status
+ * up to twice at rate 3 with 16 dBm, up to twice at rate 2 with 10 dBm,
+ * and up to four times at rate 1 with 5 dBm if it doesn't get acknowledged.
+ * Say it gets acknowledged by the peer after the fifth attempt, the status
  * information should then contain
- *   { 3, 2 }, { 2, 2 }, { 1, 1 }, { -1, 0 } ...
- * since it was transmitted twice at rate 3, twice at rate 2
- * and once at rate 1 after which we received an acknowledgement.
+ *   { 3, 2, 16 }, { 2, 2, 10 }, { 1, 1, 5 }, { -1, 0, 0 }
+ * since it was transmitted twice at rate 3 with 16 dBm, twice at rate 2 with
+ * 10 dBm and once at rate 1 with 5 dBm after which we received an
+ * acknowledgement.
  */
 struct ieee80211_tx_rate {
 	s8 idx;
 	u8 count;
 	u8 flags;
+	u8 tpc;
 } __packed;
 
 /**
@@ -552,7 +555,7 @@  struct ieee80211_tx_info {
 	union {
 		struct {
 			union {
-				/* rate control */
+				/* rate control and transmit power control */
 				struct {
 					struct ieee80211_tx_rate rates[
 						IEEE80211_TX_MAX_RATES];
@@ -573,7 +576,7 @@  struct ieee80211_tx_info {
 			u8 ampdu_ack_len;
 			u8 ampdu_len;
 			u8 antenna;
-			/* 21 bytes free */
+			/* 17 bytes free */
 		} status;
 		struct {
 			struct ieee80211_tx_rate driver_rates[
@@ -640,7 +643,7 @@  ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
 		info->status.rates[i].count = 0;
 
 	BUILD_BUG_ON(
-	    offsetof(struct ieee80211_tx_info, status.ack_signal) != 20);
+	    offsetof(struct ieee80211_tx_info, status.ack_signal) != 24);
 	memset(&info->status.ampdu_ack_len, 0,
 	       sizeof(struct ieee80211_tx_info) -
 	       offsetof(struct ieee80211_tx_info, status.ampdu_ack_len));
@@ -1216,6 +1219,14 @@  struct ieee80211_tx_control {
  *	queue mapping in order to use different queues (not just one per AC)
  *	for different virtual interfaces. See the doc section on HW queue
  *	control for more details.
+ *
+ * @IEEE80211_HW_SUPPORTS_TPC_DATA_PACKET: One power level per data packet
+ *	can be processed. Each data packet with all its potential retries
+ *	is send out at this individual power level.
+ *
+ * @IEEE80211_HW_SUPPORTS_TPC_DATA_MRR: One power levels per multi-rate-retry
+ *	stage can be processed. Each retry stage of a data packet is send out
+ *	using its specified power level.
  */
 enum ieee80211_hw_flags {
 	IEEE80211_HW_HAS_RATE_CONTROL			= 1<<0,
@@ -1243,6 +1254,8 @@  enum ieee80211_hw_flags {
 	IEEE80211_HW_AP_LINK_PS				= 1<<22,
 	IEEE80211_HW_TX_AMPDU_SETUP_IN_HW		= 1<<23,
 	IEEE80211_HW_SCAN_WHILE_IDLE			= 1<<24,
+	IEEE80211_HW_SUPPORTS_TPC_DATA_PACKET		= 1<<25,
+	IEEE80211_HW_SUPPORTS_TPC_DATA_MRR		= 1<<26,
 };
 
 /**
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 3313c11..98bde93 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -448,6 +448,7 @@  void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
 		info->control.rates[i].idx = -1;
 		info->control.rates[i].flags = 0;
 		info->control.rates[i].count = 0;
+		info->control.rates[i].tpc = sdata->local->hw.conf.power_level;
 	}
 
 	if (sdata->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)