aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00
diff options
context:
space:
mode:
authorHelmut Schaa <helmut.schaa@googlemail.com>2010-07-11 06:23:09 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-07-12 16:05:32 -0400
commit5e846004914d2295e020edd48a828b653323f93e (patch)
tree2a5d150d952cb42c5d798d19e3caad9b50c55c2d /drivers/net/wireless/rt2x00
parent8b967e41e0f75328150b7cddf79de4ee57616f01 (diff)
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: Helmut Schaa <helmut.schaa@googlemail.com> Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h20
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c153
2 files changed, 120 insertions, 53 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 3ed87badc2d3..3cda22931876 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -803,6 +803,18 @@
803#define EDCA_TID_AC_MAP 0x1310 803#define EDCA_TID_AC_MAP 0x1310
804 804
805/* 805/*
806 * TX_PWR_CFG:
807 */
808#define TX_PWR_CFG_RATE0 FIELD32(0x0000000f)
809#define TX_PWR_CFG_RATE1 FIELD32(0x000000f0)
810#define TX_PWR_CFG_RATE2 FIELD32(0x00000f00)
811#define TX_PWR_CFG_RATE3 FIELD32(0x0000f000)
812#define TX_PWR_CFG_RATE4 FIELD32(0x000f0000)
813#define TX_PWR_CFG_RATE5 FIELD32(0x00f00000)
814#define TX_PWR_CFG_RATE6 FIELD32(0x0f000000)
815#define TX_PWR_CFG_RATE7 FIELD32(0xf0000000)
816
817/*
806 * TX_PWR_CFG_0: 818 * TX_PWR_CFG_0:
807 */ 819 */
808#define TX_PWR_CFG_0 0x1314 820#define TX_PWR_CFG_0 0x1314
@@ -1853,9 +1865,15 @@ struct mac_iveiv_entry {
1853#define EEPROM_TXPOWER_A_2 FIELD16(0xff00) 1865#define EEPROM_TXPOWER_A_2 FIELD16(0xff00)
1854 1866
1855/* 1867/*
1856 * EEPROM TXpower byrate: 20MHZ power 1868 * EEPROM TXPOWER by rate: tx power per tx rate for HT20 mode
1857 */ 1869 */
1858#define EEPROM_TXPOWER_BYRATE 0x006f 1870#define EEPROM_TXPOWER_BYRATE 0x006f
1871#define EEPROM_TXPOWER_BYRATE_SIZE 9
1872
1873#define EEPROM_TXPOWER_BYRATE_RATE0 FIELD16(0x000f)
1874#define EEPROM_TXPOWER_BYRATE_RATE1 FIELD16(0x00f0)
1875#define EEPROM_TXPOWER_BYRATE_RATE2 FIELD16(0x0f00)
1876#define EEPROM_TXPOWER_BYRATE_RATE3 FIELD16(0xf000)
1859 1877
1860/* 1878/*
1861 * EEPROM BBP. 1879 * EEPROM BBP.
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index d3cf0cc39500..9030eef2403d 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,
1086} 1086}
1087 1087
1088static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, 1088static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
1089 const int txpower) 1089 const int max_txpower)
1090{ 1090{
1091 u8 txpower;
1092 u8 max_value = (u8)max_txpower;
1093 u16 eeprom;
1094 int i;
1091 u32 reg; 1095 u32 reg;
1092 u32 value = TXPOWER_G_TO_DEV(txpower);
1093 u8 r1; 1096 u8 r1;
1097 u32 offset;
1094 1098
1099 /*
1100 * set to normal tx power mode: +/- 0dBm
1101 */
1095 rt2800_bbp_read(rt2x00dev, 1, &r1); 1102 rt2800_bbp_read(rt2x00dev, 1, &r1);
1096 rt2x00_set_field8(&r1, BBP1_TX_POWER, 0); 1103 rt2x00_set_field8(&r1, BBP1_TX_POWER, 0);
1097 rt2800_bbp_write(rt2x00dev, 1, r1); 1104 rt2800_bbp_write(rt2x00dev, 1, r1);
1098 1105
1099 rt2800_register_read(rt2x00dev, TX_PWR_CFG_0, &reg); 1106 /*
1100 rt2x00_set_field32(&reg, TX_PWR_CFG_0_1MBS, value); 1107 * The eeprom contains the tx power values for each rate. These
1101 rt2x00_set_field32(&reg, TX_PWR_CFG_0_2MBS, value); 1108 * values map to 100% tx power. Each 16bit word contains four tx
1102 rt2x00_set_field32(&reg, TX_PWR_CFG_0_55MBS, value); 1109 * power values and the order is the same as used in the TX_PWR_CFG
1103 rt2x00_set_field32(&reg, TX_PWR_CFG_0_11MBS, value); 1110 * registers.
1104 rt2x00_set_field32(&reg, TX_PWR_CFG_0_6MBS, value); 1111 */
1105 rt2x00_set_field32(&reg, TX_PWR_CFG_0_9MBS, value); 1112 offset = TX_PWR_CFG_0;
1106 rt2x00_set_field32(&reg, TX_PWR_CFG_0_12MBS, value); 1113
1107 rt2x00_set_field32(&reg, TX_PWR_CFG_0_18MBS, value); 1114 for (i = 0; i < EEPROM_TXPOWER_BYRATE_SIZE; i += 2) {
1108 rt2800_register_write(rt2x00dev, TX_PWR_CFG_0, reg); 1115 /* just to be safe */
1109 1116 if (offset > TX_PWR_CFG_4)
1110 rt2800_register_read(rt2x00dev, TX_PWR_CFG_1, &reg); 1117 break;
1111 rt2x00_set_field32(&reg, TX_PWR_CFG_1_24MBS, value); 1118
1112 rt2x00_set_field32(&reg, TX_PWR_CFG_1_36MBS, value); 1119 rt2800_register_read(rt2x00dev, offset, &reg);
1113 rt2x00_set_field32(&reg, TX_PWR_CFG_1_48MBS, value); 1120
1114 rt2x00_set_field32(&reg, TX_PWR_CFG_1_54MBS, value); 1121 /* read the next four txpower values */
1115 rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS0, value); 1122 rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i,
1116 rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS1, value); 1123 &eeprom);
1117 rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS2, value); 1124
1118 rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS3, value); 1125 /* TX_PWR_CFG_0: 1MBS, TX_PWR_CFG_1: 24MBS,
1119 rt2800_register_write(rt2x00dev, TX_PWR_CFG_1, reg); 1126 * TX_PWR_CFG_2: MCS4, TX_PWR_CFG_3: MCS12,
1120 1127 * TX_PWR_CFG_4: unknown */
1121 rt2800_register_read(rt2x00dev, TX_PWR_CFG_2, &reg); 1128 txpower = rt2x00_get_field16(eeprom,
1122 rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS4, value); 1129 EEPROM_TXPOWER_BYRATE_RATE0);
1123 rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS5, value); 1130 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE0,
1124 rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS6, value); 1131 min(txpower, max_value));
1125 rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS7, value); 1132
1126 rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS8, value); 1133 /* TX_PWR_CFG_0: 2MBS, TX_PWR_CFG_1: 36MBS,
1127 rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS9, value); 1134 * TX_PWR_CFG_2: MCS5, TX_PWR_CFG_3: MCS13,
1128 rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS10, value); 1135 * TX_PWR_CFG_4: unknown */
1129 rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS11, value); 1136 txpower = rt2x00_get_field16(eeprom,
1130 rt2800_register_write(rt2x00dev, TX_PWR_CFG_2, reg); 1137 EEPROM_TXPOWER_BYRATE_RATE1);
1131 1138 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE1,
1132 rt2800_register_read(rt2x00dev, TX_PWR_CFG_3, &reg); 1139 min(txpower, max_value));
1133 rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS12, value); 1140
1134 rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS13, value); 1141 /* TX_PWR_CFG_0: 55MBS, TX_PWR_CFG_1: 48MBS,
1135 rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS14, value); 1142 * TX_PWR_CFG_2: MCS6, TX_PWR_CFG_3: MCS14,
1136 rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS15, value); 1143 * TX_PWR_CFG_4: unknown */
1137 rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN1, value); 1144 txpower = rt2x00_get_field16(eeprom,
1138 rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN2, value); 1145 EEPROM_TXPOWER_BYRATE_RATE2);
1139 rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN3, value); 1146 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE2,
1140 rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN4, value); 1147 min(txpower, max_value));
1141 rt2800_register_write(rt2x00dev, TX_PWR_CFG_3, reg); 1148
1142 1149 /* TX_PWR_CFG_0: 11MBS, TX_PWR_CFG_1: 54MBS,
1143 rt2800_register_read(rt2x00dev, TX_PWR_CFG_4, &reg); 1150 * TX_PWR_CFG_2: MCS7, TX_PWR_CFG_3: MCS15,
1144 rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN5, value); 1151 * TX_PWR_CFG_4: unknown */
1145 rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN6, value); 1152 txpower = rt2x00_get_field16(eeprom,
1146 rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN7, value); 1153 EEPROM_TXPOWER_BYRATE_RATE3);
1147 rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN8, value); 1154 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE3,
1148 rt2800_register_write(rt2x00dev, TX_PWR_CFG_4, reg); 1155 min(txpower, max_value));
1156
1157 /* read the next four txpower values */
1158 rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i + 1,
1159 &eeprom);
1160
1161 /* TX_PWR_CFG_0: 6MBS, TX_PWR_CFG_1: MCS0,
1162 * TX_PWR_CFG_2: MCS8, TX_PWR_CFG_3: unknown,
1163 * TX_PWR_CFG_4: unknown */
1164 txpower = rt2x00_get_field16(eeprom,
1165 EEPROM_TXPOWER_BYRATE_RATE0);
1166 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE4,
1167 min(txpower, max_value));
1168
1169 /* TX_PWR_CFG_0: 9MBS, TX_PWR_CFG_1: MCS1,
1170 * TX_PWR_CFG_2: MCS9, TX_PWR_CFG_3: unknown,
1171 * TX_PWR_CFG_4: unknown */
1172 txpower = rt2x00_get_field16(eeprom,
1173 EEPROM_TXPOWER_BYRATE_RATE1);
1174 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE5,
1175 min(txpower, max_value));
1176
1177 /* TX_PWR_CFG_0: 12MBS, TX_PWR_CFG_1: MCS2,
1178 * TX_PWR_CFG_2: MCS10, TX_PWR_CFG_3: unknown,
1179 * TX_PWR_CFG_4: unknown */
1180 txpower = rt2x00_get_field16(eeprom,
1181 EEPROM_TXPOWER_BYRATE_RATE2);
1182 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE6,
1183 min(txpower, max_value));
1184
1185 /* TX_PWR_CFG_0: 18MBS, TX_PWR_CFG_1: MCS3,
1186 * TX_PWR_CFG_2: MCS11, TX_PWR_CFG_3: unknown,
1187 * TX_PWR_CFG_4: unknown */
1188 txpower = rt2x00_get_field16(eeprom,
1189 EEPROM_TXPOWER_BYRATE_RATE3);
1190 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE7,
1191 min(txpower, max_value));
1192
1193 rt2800_register_write(rt2x00dev, offset, reg);
1194
1195 /* next TX_PWR_CFG register */
1196 offset += 4;
1197 }
1149} 1198}
1150 1199
1151static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev, 1200static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev,