[PATCH 1/2] carl9170: support per multi-retry-stage tpc

Subsystems: atheros ath generic utilities, carl9170 linux community wireless driver, the rest

STALE5118d

2 messages, 1 author, 2012-07-27 · open the first message on its own page

[PATCH 1/2] carl9170: support per multi-retry-stage tpc

From: Christian Lamparter <chunkeey@googlemail.com>
Date: 2012-07-27 23:15:28

This patch add support for the upcoming
transmit power controller algorithm.

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
---
Thomas,

since you are going to touch the code anyway (due to
the ack_signal offset). I thought it might be a good
idea to make patches for carl9170 and p54 myself, so
we can have some support for hw with per mrr tpc and
global ack (carl9170) and per data tpc (p54) from the
get-go.

Regards,
	Chr.

(Of course, I think you might do a few iterations, but
that's fine.)
---
 drivers/net/wireless/ath/carl9170/mac.c  |   10 +++++-----
 drivers/net/wireless/ath/carl9170/main.c |    5 ++++-
 drivers/net/wireless/ath/carl9170/tx.c   |    4 ++--
 3 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c
index 53415bf..949861b 100644
--- a/drivers/net/wireless/ath/carl9170/mac.c
+++ b/drivers/net/wireless/ath/carl9170/mac.c
@@ -488,7 +488,7 @@ int carl9170_disable_key(struct ar9170 *ar, const u8 id)
 
 int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel)
 {
-	unsigned int power, chains;
+	unsigned int power, chains, ack_power;
 
 	if (ar->eeprom.tx_mask != 1)
 		chains = AR9170_TX_PHY_TXCHAIN_2;
@@ -506,17 +506,17 @@ int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel)
 		BUG_ON(1);
 	}
 
+	ack_power = min_t(unsigned int, power, ar->hw->conf.ack_power * 2);
 	power = min_t(unsigned int, power, ar->hw->conf.power_level * 2);
-
 	carl9170_regwrite_begin(ar);
 	carl9170_regwrite(AR9170_MAC_REG_ACK_TPC,
-			  0x3c1e | power << 20 | chains << 26);
+			  0x3c1e | ack_power << 20 | chains << 26);
 	carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC,
 			  power << 5 | chains << 11 |
 			  power << 21 | chains << 27);
 	carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC,
-			  power << 5 | chains << 11 |
-			  power << 21 | chains << 27);
+			  ack_power << 5 | chains << 11 |
+			  ack_power << 21 | chains << 27);
 	carl9170_regwrite_finish();
 	return carl9170_regwrite_result();
 }
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index 858e58d..801fbb2 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -886,7 +886,8 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
 			goto out;
 	}
 
-	if (changed & IEEE80211_CONF_CHANGE_POWER) {
+	if (changed & (IEEE80211_CONF_CHANGE_POWER |
+	    IEEE80211_CONF_CHANGE_ACK_POWER)) {
 		err = carl9170_set_mac_tpc(ar, ar->hw->conf.channel);
 		if (err)
 			goto out;
@@ -1782,6 +1783,8 @@ void *carl9170_alloc(size_t priv_size)
 		     IEEE80211_HW_SUPPORTS_PS |
 		     IEEE80211_HW_PS_NULLFUNC_STACK |
 		     IEEE80211_HW_NEED_DTIM_PERIOD |
+		     IEEE80211_HW_SUPPORTS_TPC_DATA_MRR |
+		     IEEE80211_HW_SUPPORTS_TPC_ACK_GLOBAL |
 		     IEEE80211_HW_SIGNAL_DBM;
 
 	if (!modparam_noht) {
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
index 84377cf..c68cffb 100644
--- a/drivers/net/wireless/ath/carl9170/tx.c
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -277,7 +277,7 @@ static void carl9170_tx_release(struct kref *ref)
 		return;
 
 	BUILD_BUG_ON(
-	    offsetof(struct ieee80211_tx_info, status.ack_signal) != 20);
+	    offsetof(struct ieee80211_tx_info, status.ack_signal) != 24);
 
 	memset(&txinfo->status.ack_signal, 0,
 	       sizeof(struct ieee80211_tx_info) -
@@ -761,7 +761,7 @@ static void carl9170_tx_rate_tpc_chains(struct ar9170 *ar,
 			*chains = AR9170_TX_PHY_TXCHAIN_2;
 	}
 
-	*tpc = min_t(unsigned int, *tpc, ar->hw->conf.power_level * 2);
+	*tpc = min_t(unsigned int, *tpc, txrate->tpc * 2);
 }
 
 static __le32 carl9170_tx_physet(struct ar9170 *ar,
-- 
1.7.10.4

[PATCH 2/2] p54: support per packet tpc

From: Christian Lamparter <chunkeey@googlemail.com>
Date: 2012-07-27 23:15:29

This patch add support for the upcoming
transmit power controller algorithm.

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
---
 drivers/net/wireless/p54/eeprom.c |    3 +++
 drivers/net/wireless/p54/lmac.h   |    2 +-
 drivers/net/wireless/p54/main.c   |    4 +---
 drivers/net/wireless/p54/p54.h    |    1 -
 drivers/net/wireless/p54/txrx.c   |   13 ++++++++-----
 5 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c
index fa8ce51..cb2b496 100644
--- a/drivers/net/wireless/p54/eeprom.c
+++ b/drivers/net/wireless/p54/eeprom.c
@@ -75,6 +75,7 @@ static struct p54_rssi_db_entry p54_rssi_default = {
 struct p54_channel_entry {
 	u16 freq;
 	u16 data;
+	u16 max_power;
 	int index;
 	enum ieee80211_band band;
 };
@@ -192,6 +193,7 @@ static int p54_generate_band(struct ieee80211_hw *dev,
 
 		tmp->channels[j].band = chan->band;
 		tmp->channels[j].center_freq = chan->freq;
+		tmp->channels[j].max_power = chan->max_power;
 		priv->survey[*chan_num].channel = &tmp->channels[j];
 		priv->survey[*chan_num].filled = SURVEY_INFO_NOISE_DBM |
 			SURVEY_INFO_CHANNEL_TIME |
@@ -265,6 +267,7 @@ static void p54_update_channel_param(struct p54_channel_list *list,
 		list->channels[i].band = band;
 		list->channels[i].index = ieee80211_frequency_to_channel(freq);
 		/* TODO: parse output_limit and fill max_power */
+		list->channels[i].max_power = 20;
 	}
 }
 
diff --git a/drivers/net/wireless/p54/lmac.h b/drivers/net/wireless/p54/lmac.h
index de1d46b..b15d533 100644
--- a/drivers/net/wireless/p54/lmac.h
+++ b/drivers/net/wireless/p54/lmac.h
@@ -56,7 +56,7 @@ enum p54_control_frame_types {
 #define P54_HDR_FLAG_DATA_OUT_PROMISC		BIT(0)
 #define P54_HDR_FLAG_DATA_OUT_TIMESTAMP		BIT(1)
 #define P54_HDR_FLAG_DATA_OUT_SEQNR		BIT(2)
-#define P54_HDR_FLAG_DATA_OUT_BIT3		BIT(3)
+#define P54_HDR_FLAG_DATA_OUT_TPC		BIT(3)
 #define P54_HDR_FLAG_DATA_OUT_BURST		BIT(4)
 #define P54_HDR_FLAG_DATA_OUT_NOCANCEL		BIT(5)
 #define P54_HDR_FLAG_DATA_OUT_CLEARTIM		BIT(6)
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index 5e91ad0..de2a443 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -320,11 +320,8 @@ static int p54_config(struct ieee80211_hw *dev, u32 changed)
 {
 	int ret = 0;
 	struct p54_common *priv = dev->priv;
-	struct ieee80211_conf *conf = &dev->conf;
 
 	mutex_lock(&priv->conf_mutex);
-	if (changed & IEEE80211_CONF_CHANGE_POWER)
-		priv->output_power = conf->power_level << 2;
 	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
 		struct ieee80211_channel *oldchan;
 		WARN_ON(p54_wait_for_stats(dev));
@@ -737,6 +734,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
 		     IEEE80211_HW_SIGNAL_DBM |
 		     IEEE80211_HW_SUPPORTS_PS |
 		     IEEE80211_HW_PS_NULLFUNC_STACK |
+		     IEEE80211_HW_SUPPORTS_TPC_DATA_PACKET |
 		     IEEE80211_HW_REPORTS_TX_ACK_STATUS;
 
 	dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index 40b401e..73b4061 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -198,7 +198,6 @@ struct p54_common {
 	u16 rxhw;
 	u8 rx_diversity_mask;
 	u8 tx_diversity_mask;
-	unsigned int output_power;
 	struct p54_rssi_db_entry *cur_rssi;
 	struct ieee80211_channel *curchan;
 	struct survey_info *survey;
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
index 5861e13..eb5ac80 100644
--- a/drivers/net/wireless/p54/txrx.c
+++ b/drivers/net/wireless/p54/txrx.c
@@ -426,7 +426,7 @@ static void p54_rx_frame_sent(struct p54_common *priv, struct sk_buff *skb)
 	       sizeof(struct ieee80211_tx_info) -
 	       offsetof(struct ieee80211_tx_info, status.ack_signal));
 	BUILD_BUG_ON(offsetof(struct ieee80211_tx_info,
-			      status.ack_signal) != 20);
+			      status.ack_signal) != 24);
 
 	if (entry_hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN))
 		pad = entry_data->align[0];
@@ -777,7 +777,7 @@ void p54_tx_80211(struct ieee80211_hw *dev,
 	struct p54_tx_info *p54info;
 	struct p54_hdr *hdr;
 	struct p54_tx_data *txhdr;
-	unsigned int padding, len, extra_len = 0;
+	unsigned int padding, len, extra_len = 0, output_power;
 	int i, j, ridx;
 	u16 hdr_flags = 0, aid = 0;
 	u8 rate, queue = 0, crypt_offset = 0;
@@ -825,7 +825,7 @@ void p54_tx_80211(struct ieee80211_hw *dev,
 	 * RTS/CTS won't happen on 5 GHz
 	 */
 	cts_rate = info->control.rts_cts_rate_idx;
-
+	output_power = info->control.rates[0].tpc * 4;
 	memset(&txhdr->rateset, 0, sizeof(txhdr->rateset));
 
 	/* see how many rates got used */
@@ -891,6 +891,8 @@ void p54_tx_80211(struct ieee80211_hw *dev,
 	if (burst_allowed)
 		hdr_flags |= P54_HDR_FLAG_DATA_OUT_BURST;
 
+	hdr_flags |= P54_HDR_FLAG_DATA_OUT_TPC;
+
 	/* TODO: enable bursting */
 	hdr->flags = cpu_to_le16(hdr_flags);
 	hdr->tries = ridx;
@@ -920,11 +922,12 @@ void p54_tx_80211(struct ieee80211_hw *dev,
 	txhdr->tx_antenna = 2 & priv->tx_diversity_mask;
 	if (priv->rxhw == 5) {
 		txhdr->longbow.cts_rate = cts_rate;
-		txhdr->longbow.output_power = cpu_to_le16(priv->output_power);
+		txhdr->longbow.output_power = cpu_to_le16(output_power);
 	} else {
-		txhdr->normal.output_power = priv->output_power;
+		txhdr->normal.output_power = output_power;
 		txhdr->normal.cts_rate = cts_rate;
 	}
+
 	if (padding)
 		txhdr->align[0] = padding;
 
-- 
1.7.10.4
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help