Commit 5e846004 authored by Helmut Schaa's avatar Helmut Schaa Committed by John W. Linville

rt2x00: Limit txpower by eeprom values

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: default avatarHelmut Schaa <helmut.schaa@googlemail.com>
Signed-off-by: default avatarIvo van Doorn <IvDoorn@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 8b967e41
...@@ -802,6 +802,18 @@ ...@@ -802,6 +802,18 @@
*/ */
#define EDCA_TID_AC_MAP 0x1310 #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: * TX_PWR_CFG_0:
*/ */
...@@ -1853,9 +1865,15 @@ struct mac_iveiv_entry { ...@@ -1853,9 +1865,15 @@ struct mac_iveiv_entry {
#define EEPROM_TXPOWER_A_2 FIELD16(0xff00) #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 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. * EEPROM BBP.
......
...@@ -1086,66 +1086,115 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, ...@@ -1086,66 +1086,115 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
} }
static void rt2800_config_txpower(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 reg;
u32 value = TXPOWER_G_TO_DEV(txpower);
u8 r1; u8 r1;
u32 offset;
/*
* set to normal tx power mode: +/- 0dBm
*/
rt2800_bbp_read(rt2x00dev, 1, &r1); rt2800_bbp_read(rt2x00dev, 1, &r1);
rt2x00_set_field8(&r1, BBP1_TX_POWER, 0); rt2x00_set_field8(&r1, BBP1_TX_POWER, 0);
rt2800_bbp_write(rt2x00dev, 1, r1); rt2800_bbp_write(rt2x00dev, 1, r1);
rt2800_register_read(rt2x00dev, TX_PWR_CFG_0, &reg); /*
rt2x00_set_field32(&reg, TX_PWR_CFG_0_1MBS, value); * The eeprom contains the tx power values for each rate. These
rt2x00_set_field32(&reg, TX_PWR_CFG_0_2MBS, value); * values map to 100% tx power. Each 16bit word contains four tx
rt2x00_set_field32(&reg, TX_PWR_CFG_0_55MBS, value); * power values and the order is the same as used in the TX_PWR_CFG
rt2x00_set_field32(&reg, TX_PWR_CFG_0_11MBS, value); * registers.
rt2x00_set_field32(&reg, TX_PWR_CFG_0_6MBS, value); */
rt2x00_set_field32(&reg, TX_PWR_CFG_0_9MBS, value); offset = TX_PWR_CFG_0;
rt2x00_set_field32(&reg, TX_PWR_CFG_0_12MBS, value);
rt2x00_set_field32(&reg, TX_PWR_CFG_0_18MBS, value); for (i = 0; i < EEPROM_TXPOWER_BYRATE_SIZE; i += 2) {
rt2800_register_write(rt2x00dev, TX_PWR_CFG_0, reg); /* just to be safe */
if (offset > TX_PWR_CFG_4)
rt2800_register_read(rt2x00dev, TX_PWR_CFG_1, &reg); break;
rt2x00_set_field32(&reg, TX_PWR_CFG_1_24MBS, value);
rt2x00_set_field32(&reg, TX_PWR_CFG_1_36MBS, value); rt2800_register_read(rt2x00dev, offset, &reg);
rt2x00_set_field32(&reg, TX_PWR_CFG_1_48MBS, value);
rt2x00_set_field32(&reg, TX_PWR_CFG_1_54MBS, value); /* read the next four txpower values */
rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS0, value); rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i,
rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS1, value); &eeprom);
rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS2, value);
rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS3, value); /* TX_PWR_CFG_0: 1MBS, TX_PWR_CFG_1: 24MBS,
rt2800_register_write(rt2x00dev, TX_PWR_CFG_1, reg); * TX_PWR_CFG_2: MCS4, TX_PWR_CFG_3: MCS12,
* TX_PWR_CFG_4: unknown */
rt2800_register_read(rt2x00dev, TX_PWR_CFG_2, &reg); txpower = rt2x00_get_field16(eeprom,
rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS4, value); EEPROM_TXPOWER_BYRATE_RATE0);
rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS5, value); rt2x00_set_field32(&reg, TX_PWR_CFG_RATE0,
rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS6, value); min(txpower, max_value));
rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS7, value);
rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS8, value); /* TX_PWR_CFG_0: 2MBS, TX_PWR_CFG_1: 36MBS,
rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS9, value); * TX_PWR_CFG_2: MCS5, TX_PWR_CFG_3: MCS13,
rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS10, value); * TX_PWR_CFG_4: unknown */
rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS11, value); txpower = rt2x00_get_field16(eeprom,
rt2800_register_write(rt2x00dev, TX_PWR_CFG_2, reg); EEPROM_TXPOWER_BYRATE_RATE1);
rt2x00_set_field32(&reg, TX_PWR_CFG_RATE1,
rt2800_register_read(rt2x00dev, TX_PWR_CFG_3, &reg); min(txpower, max_value));
rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS12, value);
rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS13, value); /* TX_PWR_CFG_0: 55MBS, TX_PWR_CFG_1: 48MBS,
rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS14, value); * TX_PWR_CFG_2: MCS6, TX_PWR_CFG_3: MCS14,
rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS15, value); * TX_PWR_CFG_4: unknown */
rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN1, value); txpower = rt2x00_get_field16(eeprom,
rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN2, value); EEPROM_TXPOWER_BYRATE_RATE2);
rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN3, value); rt2x00_set_field32(&reg, TX_PWR_CFG_RATE2,
rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN4, value); min(txpower, max_value));
rt2800_register_write(rt2x00dev, TX_PWR_CFG_3, reg);
/* TX_PWR_CFG_0: 11MBS, TX_PWR_CFG_1: 54MBS,
rt2800_register_read(rt2x00dev, TX_PWR_CFG_4, &reg); * TX_PWR_CFG_2: MCS7, TX_PWR_CFG_3: MCS15,
rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN5, value); * TX_PWR_CFG_4: unknown */
rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN6, value); txpower = rt2x00_get_field16(eeprom,
rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN7, value); EEPROM_TXPOWER_BYRATE_RATE3);
rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN8, value); rt2x00_set_field32(&reg, TX_PWR_CFG_RATE3,
rt2800_register_write(rt2x00dev, TX_PWR_CFG_4, reg); 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(&reg, 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(&reg, 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(&reg, 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(&reg, 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, static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment