From: Ivo van Doorn <ivdoorn@gmail.com>
To: "John W. Linville" <linville@tuxdriver.com>
Cc: linux-wireless@vger.kernel.org, users@rt2x00.serialmonkey.com,
Helmut Schaa <helmut.schaa@googlemail.com>
Subject: [PATCH 01/17] rt2x00: Limit txpower by eeprom values
Date: Sun, 11 Jul 2010 12:23:09 +0200 [thread overview]
Message-ID: <201007111223.11190.IvDoorn@gmail.com> (raw)
From: Helmut Schaa <helmut.schaa@googlemail.com>
Limit the txpower per rate by the approriate values in the eeprom.
This avoids too high txpower values resulting in bad tx performance.
Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2800.h | 20 ++++-
drivers/net/wireless/rt2x00/rt2800lib.c | 153 ++++++++++++++++++++-----------
2 files changed, 120 insertions(+), 53 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 3ed87ba..3cda229 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -803,6 +803,18 @@
#define EDCA_TID_AC_MAP 0x1310
/*
+ * TX_PWR_CFG:
+ */
+#define TX_PWR_CFG_RATE0 FIELD32(0x0000000f)
+#define TX_PWR_CFG_RATE1 FIELD32(0x000000f0)
+#define TX_PWR_CFG_RATE2 FIELD32(0x00000f00)
+#define TX_PWR_CFG_RATE3 FIELD32(0x0000f000)
+#define TX_PWR_CFG_RATE4 FIELD32(0x000f0000)
+#define TX_PWR_CFG_RATE5 FIELD32(0x00f00000)
+#define TX_PWR_CFG_RATE6 FIELD32(0x0f000000)
+#define TX_PWR_CFG_RATE7 FIELD32(0xf0000000)
+
+/*
* TX_PWR_CFG_0:
*/
#define TX_PWR_CFG_0 0x1314
@@ -1853,9 +1865,15 @@ struct mac_iveiv_entry {
#define EEPROM_TXPOWER_A_2 FIELD16(0xff00)
/*
- * EEPROM TXpower byrate: 20MHZ power
+ * EEPROM TXPOWER by rate: tx power per tx rate for HT20 mode
*/
#define EEPROM_TXPOWER_BYRATE 0x006f
+#define EEPROM_TXPOWER_BYRATE_SIZE 9
+
+#define EEPROM_TXPOWER_BYRATE_RATE0 FIELD16(0x000f)
+#define EEPROM_TXPOWER_BYRATE_RATE1 FIELD16(0x00f0)
+#define EEPROM_TXPOWER_BYRATE_RATE2 FIELD16(0x0f00)
+#define EEPROM_TXPOWER_BYRATE_RATE3 FIELD16(0xf000)
/*
* EEPROM BBP.
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index d3cf0cc..9030eef 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1086,66 +1086,115 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
}
static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
- const int txpower)
+ const int max_txpower)
{
+ u8 txpower;
+ u8 max_value = (u8)max_txpower;
+ u16 eeprom;
+ int i;
u32 reg;
- u32 value = TXPOWER_G_TO_DEV(txpower);
u8 r1;
+ u32 offset;
+ /*
+ * set to normal tx power mode: +/- 0dBm
+ */
rt2800_bbp_read(rt2x00dev, 1, &r1);
rt2x00_set_field8(&r1, BBP1_TX_POWER, 0);
rt2800_bbp_write(rt2x00dev, 1, r1);
- rt2800_register_read(rt2x00dev, TX_PWR_CFG_0, ®);
- rt2x00_set_field32(®, TX_PWR_CFG_0_1MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_0_2MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_0_55MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_0_11MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_0_6MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_0_9MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_0_12MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_0_18MBS, value);
- rt2800_register_write(rt2x00dev, TX_PWR_CFG_0, reg);
-
- rt2800_register_read(rt2x00dev, TX_PWR_CFG_1, ®);
- rt2x00_set_field32(®, TX_PWR_CFG_1_24MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_1_36MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_1_48MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_1_54MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_1_MCS0, value);
- rt2x00_set_field32(®, TX_PWR_CFG_1_MCS1, value);
- rt2x00_set_field32(®, TX_PWR_CFG_1_MCS2, value);
- rt2x00_set_field32(®, TX_PWR_CFG_1_MCS3, value);
- rt2800_register_write(rt2x00dev, TX_PWR_CFG_1, reg);
-
- rt2800_register_read(rt2x00dev, TX_PWR_CFG_2, ®);
- rt2x00_set_field32(®, TX_PWR_CFG_2_MCS4, value);
- rt2x00_set_field32(®, TX_PWR_CFG_2_MCS5, value);
- rt2x00_set_field32(®, TX_PWR_CFG_2_MCS6, value);
- rt2x00_set_field32(®, TX_PWR_CFG_2_MCS7, value);
- rt2x00_set_field32(®, TX_PWR_CFG_2_MCS8, value);
- rt2x00_set_field32(®, TX_PWR_CFG_2_MCS9, value);
- rt2x00_set_field32(®, TX_PWR_CFG_2_MCS10, value);
- rt2x00_set_field32(®, TX_PWR_CFG_2_MCS11, value);
- rt2800_register_write(rt2x00dev, TX_PWR_CFG_2, reg);
-
- rt2800_register_read(rt2x00dev, TX_PWR_CFG_3, ®);
- rt2x00_set_field32(®, TX_PWR_CFG_3_MCS12, value);
- rt2x00_set_field32(®, TX_PWR_CFG_3_MCS13, value);
- rt2x00_set_field32(®, TX_PWR_CFG_3_MCS14, value);
- rt2x00_set_field32(®, TX_PWR_CFG_3_MCS15, value);
- rt2x00_set_field32(®, TX_PWR_CFG_3_UKNOWN1, value);
- rt2x00_set_field32(®, TX_PWR_CFG_3_UKNOWN2, value);
- rt2x00_set_field32(®, TX_PWR_CFG_3_UKNOWN3, value);
- rt2x00_set_field32(®, TX_PWR_CFG_3_UKNOWN4, value);
- rt2800_register_write(rt2x00dev, TX_PWR_CFG_3, reg);
-
- rt2800_register_read(rt2x00dev, TX_PWR_CFG_4, ®);
- rt2x00_set_field32(®, TX_PWR_CFG_4_UKNOWN5, value);
- rt2x00_set_field32(®, TX_PWR_CFG_4_UKNOWN6, value);
- rt2x00_set_field32(®, TX_PWR_CFG_4_UKNOWN7, value);
- rt2x00_set_field32(®, TX_PWR_CFG_4_UKNOWN8, value);
- rt2800_register_write(rt2x00dev, TX_PWR_CFG_4, reg);
+ /*
+ * The eeprom contains the tx power values for each rate. These
+ * values map to 100% tx power. Each 16bit word contains four tx
+ * power values and the order is the same as used in the TX_PWR_CFG
+ * registers.
+ */
+ 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)
+ break;
+
+ rt2800_register_read(rt2x00dev, offset, ®);
+
+ /* read the next four txpower values */
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i,
+ &eeprom);
+
+ /* TX_PWR_CFG_0: 1MBS, TX_PWR_CFG_1: 24MBS,
+ * TX_PWR_CFG_2: MCS4, TX_PWR_CFG_3: MCS12,
+ * TX_PWR_CFG_4: unknown */
+ txpower = rt2x00_get_field16(eeprom,
+ EEPROM_TXPOWER_BYRATE_RATE0);
+ rt2x00_set_field32(®, TX_PWR_CFG_RATE0,
+ min(txpower, max_value));
+
+ /* TX_PWR_CFG_0: 2MBS, TX_PWR_CFG_1: 36MBS,
+ * TX_PWR_CFG_2: MCS5, TX_PWR_CFG_3: MCS13,
+ * TX_PWR_CFG_4: unknown */
+ txpower = rt2x00_get_field16(eeprom,
+ EEPROM_TXPOWER_BYRATE_RATE1);
+ rt2x00_set_field32(®, TX_PWR_CFG_RATE1,
+ min(txpower, max_value));
+
+ /* TX_PWR_CFG_0: 55MBS, TX_PWR_CFG_1: 48MBS,
+ * TX_PWR_CFG_2: MCS6, TX_PWR_CFG_3: MCS14,
+ * TX_PWR_CFG_4: unknown */
+ txpower = rt2x00_get_field16(eeprom,
+ EEPROM_TXPOWER_BYRATE_RATE2);
+ rt2x00_set_field32(®, TX_PWR_CFG_RATE2,
+ min(txpower, max_value));
+
+ /* TX_PWR_CFG_0: 11MBS, TX_PWR_CFG_1: 54MBS,
+ * TX_PWR_CFG_2: MCS7, TX_PWR_CFG_3: MCS15,
+ * TX_PWR_CFG_4: unknown */
+ txpower = rt2x00_get_field16(eeprom,
+ EEPROM_TXPOWER_BYRATE_RATE3);
+ rt2x00_set_field32(®, TX_PWR_CFG_RATE3,
+ min(txpower, max_value));
+
+ /* read the next four txpower values */
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i + 1,
+ &eeprom);
+
+ /* TX_PWR_CFG_0: 6MBS, TX_PWR_CFG_1: MCS0,
+ * TX_PWR_CFG_2: MCS8, TX_PWR_CFG_3: unknown,
+ * TX_PWR_CFG_4: unknown */
+ txpower = rt2x00_get_field16(eeprom,
+ EEPROM_TXPOWER_BYRATE_RATE0);
+ rt2x00_set_field32(®, TX_PWR_CFG_RATE4,
+ min(txpower, max_value));
+
+ /* TX_PWR_CFG_0: 9MBS, TX_PWR_CFG_1: MCS1,
+ * TX_PWR_CFG_2: MCS9, TX_PWR_CFG_3: unknown,
+ * TX_PWR_CFG_4: unknown */
+ txpower = rt2x00_get_field16(eeprom,
+ EEPROM_TXPOWER_BYRATE_RATE1);
+ rt2x00_set_field32(®, TX_PWR_CFG_RATE5,
+ min(txpower, max_value));
+
+ /* TX_PWR_CFG_0: 12MBS, TX_PWR_CFG_1: MCS2,
+ * TX_PWR_CFG_2: MCS10, TX_PWR_CFG_3: unknown,
+ * TX_PWR_CFG_4: unknown */
+ txpower = rt2x00_get_field16(eeprom,
+ EEPROM_TXPOWER_BYRATE_RATE2);
+ rt2x00_set_field32(®, TX_PWR_CFG_RATE6,
+ min(txpower, max_value));
+
+ /* TX_PWR_CFG_0: 18MBS, TX_PWR_CFG_1: MCS3,
+ * TX_PWR_CFG_2: MCS11, TX_PWR_CFG_3: unknown,
+ * TX_PWR_CFG_4: unknown */
+ txpower = rt2x00_get_field16(eeprom,
+ EEPROM_TXPOWER_BYRATE_RATE3);
+ rt2x00_set_field32(®, TX_PWR_CFG_RATE7,
+ min(txpower, max_value));
+
+ rt2800_register_write(rt2x00dev, offset, reg);
+
+ /* next TX_PWR_CFG register */
+ offset += 4;
+ }
}
static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev,
--
1.7.1.1
next reply other threads:[~2010-07-11 10:31 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-11 10:23 Ivo van Doorn [this message]
2010-07-11 10:23 ` [PATCH 02/17] rt2x00: Convert AGC value from descriptor to RSSI (dBm) Ivo van Doorn
2010-07-11 10:24 ` [PATCH 03/17] rt2x00: Rename CONFIG_DISABLE_LINK_TUNING Ivo van Doorn
2010-07-11 10:24 ` [PATCH 04/17] rt2x00: Disable link tuning while scanning Ivo van Doorn
2010-07-11 10:25 ` [PATCH 05/17] rt2x00: Fix vgc_level_reg handling Ivo van Doorn
2010-07-11 10:25 ` [PATCH 06/17] rt2x00: Implement watchdog monitoring Ivo van Doorn
2010-07-11 10:26 ` [PATCH 07/17] rt2x00: Make rt2800_write_beacon only export to GPL Ivo van Doorn
2010-07-11 10:26 ` [PATCH 08/17] rt2x00: Convert rt2x00 to use threaded interrupts Ivo van Doorn
2010-07-11 10:27 ` [PATCH 09/17] rt2x00: Allow beacon update without scheduling a work Ivo van Doorn
2010-07-11 10:27 ` [PATCH 10/17] rt2x00: Implement broad- and multicast buffering Ivo van Doorn
2010-07-11 10:28 ` [PATCH 11/17] rt2x00: Use pretbtt irq for fetching beacons on rt2800pci Ivo van Doorn
2010-07-11 10:28 ` [PATCH 12/17] rt2x00: Use separate mac80211_ops for rt2800pci and rt2800usb Ivo van Doorn
2010-07-11 10:29 ` [PATCH 13/17] rt2x00: Remove set_tim callback from PCI drivers Ivo van Doorn
2010-07-11 10:29 ` [PATCH 14/17] rt2x00: Don't initialize beacon interval to 0 on rt2800 devices Ivo van Doorn
2010-07-11 10:30 ` [PATCH 15/17] rt2x00: Add missing TSF sync mode for AP operation Ivo van Doorn
2010-07-11 10:30 ` [PATCH 16/17] rt2x00: Move common firmware loading into rt2800lib Ivo van Doorn
2010-07-11 10:31 ` [PATCH 17/17] rt2x00: Move driver callback functions into the ops structure Ivo van Doorn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201007111223.11190.IvDoorn@gmail.com \
--to=ivdoorn@gmail.com \
--cc=helmut.schaa@googlemail.com \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
--cc=users@rt2x00.serialmonkey.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).