diff options
author | Helmut Schaa <helmut.schaa@googlemail.com> | 2010-07-11 06:23:09 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-07-12 16:05:32 -0400 |
commit | 5e846004914d2295e020edd48a828b653323f93e (patch) | |
tree | 2a5d150d952cb42c5d798d19e3caad9b50c55c2d /drivers/net/wireless/rt2x00 | |
parent | 8b967e41e0f75328150b7cddf79de4ee57616f01 (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.h | 20 | ||||
-rw-r--r-- | 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 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 | ||
1088 | static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, | 1088 | static 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, ®); | 1106 | /* |
1100 | rt2x00_set_field32(®, TX_PWR_CFG_0_1MBS, value); | 1107 | * The eeprom contains the tx power values for each rate. These |
1101 | rt2x00_set_field32(®, TX_PWR_CFG_0_2MBS, value); | 1108 | * values map to 100% tx power. Each 16bit word contains four tx |
1102 | rt2x00_set_field32(®, 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(®, TX_PWR_CFG_0_11MBS, value); | 1110 | * registers. |
1104 | rt2x00_set_field32(®, TX_PWR_CFG_0_6MBS, value); | 1111 | */ |
1105 | rt2x00_set_field32(®, TX_PWR_CFG_0_9MBS, value); | 1112 | offset = TX_PWR_CFG_0; |
1106 | rt2x00_set_field32(®, TX_PWR_CFG_0_12MBS, value); | 1113 | |
1107 | rt2x00_set_field32(®, 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, ®); | 1117 | break; |
1111 | rt2x00_set_field32(®, TX_PWR_CFG_1_24MBS, value); | 1118 | |
1112 | rt2x00_set_field32(®, TX_PWR_CFG_1_36MBS, value); | 1119 | rt2800_register_read(rt2x00dev, offset, ®); |
1113 | rt2x00_set_field32(®, TX_PWR_CFG_1_48MBS, value); | 1120 | |
1114 | rt2x00_set_field32(®, TX_PWR_CFG_1_54MBS, value); | 1121 | /* read the next four txpower values */ |
1115 | rt2x00_set_field32(®, TX_PWR_CFG_1_MCS0, value); | 1122 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i, |
1116 | rt2x00_set_field32(®, TX_PWR_CFG_1_MCS1, value); | 1123 | &eeprom); |
1117 | rt2x00_set_field32(®, TX_PWR_CFG_1_MCS2, value); | 1124 | |
1118 | rt2x00_set_field32(®, 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, ®); | 1128 | txpower = rt2x00_get_field16(eeprom, |
1122 | rt2x00_set_field32(®, TX_PWR_CFG_2_MCS4, value); | 1129 | EEPROM_TXPOWER_BYRATE_RATE0); |
1123 | rt2x00_set_field32(®, TX_PWR_CFG_2_MCS5, value); | 1130 | rt2x00_set_field32(®, TX_PWR_CFG_RATE0, |
1124 | rt2x00_set_field32(®, TX_PWR_CFG_2_MCS6, value); | 1131 | min(txpower, max_value)); |
1125 | rt2x00_set_field32(®, TX_PWR_CFG_2_MCS7, value); | 1132 | |
1126 | rt2x00_set_field32(®, TX_PWR_CFG_2_MCS8, value); | 1133 | /* TX_PWR_CFG_0: 2MBS, TX_PWR_CFG_1: 36MBS, |
1127 | rt2x00_set_field32(®, TX_PWR_CFG_2_MCS9, value); | 1134 | * TX_PWR_CFG_2: MCS5, TX_PWR_CFG_3: MCS13, |
1128 | rt2x00_set_field32(®, TX_PWR_CFG_2_MCS10, value); | 1135 | * TX_PWR_CFG_4: unknown */ |
1129 | rt2x00_set_field32(®, 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(®, TX_PWR_CFG_RATE1, | |
1132 | rt2800_register_read(rt2x00dev, TX_PWR_CFG_3, ®); | 1139 | min(txpower, max_value)); |
1133 | rt2x00_set_field32(®, TX_PWR_CFG_3_MCS12, value); | 1140 | |
1134 | rt2x00_set_field32(®, TX_PWR_CFG_3_MCS13, value); | 1141 | /* TX_PWR_CFG_0: 55MBS, TX_PWR_CFG_1: 48MBS, |
1135 | rt2x00_set_field32(®, TX_PWR_CFG_3_MCS14, value); | 1142 | * TX_PWR_CFG_2: MCS6, TX_PWR_CFG_3: MCS14, |
1136 | rt2x00_set_field32(®, TX_PWR_CFG_3_MCS15, value); | 1143 | * TX_PWR_CFG_4: unknown */ |
1137 | rt2x00_set_field32(®, TX_PWR_CFG_3_UKNOWN1, value); | 1144 | txpower = rt2x00_get_field16(eeprom, |
1138 | rt2x00_set_field32(®, TX_PWR_CFG_3_UKNOWN2, value); | 1145 | EEPROM_TXPOWER_BYRATE_RATE2); |
1139 | rt2x00_set_field32(®, TX_PWR_CFG_3_UKNOWN3, value); | 1146 | rt2x00_set_field32(®, TX_PWR_CFG_RATE2, |
1140 | rt2x00_set_field32(®, 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, ®); | 1150 | * TX_PWR_CFG_2: MCS7, TX_PWR_CFG_3: MCS15, |
1144 | rt2x00_set_field32(®, TX_PWR_CFG_4_UKNOWN5, value); | 1151 | * TX_PWR_CFG_4: unknown */ |
1145 | rt2x00_set_field32(®, TX_PWR_CFG_4_UKNOWN6, value); | 1152 | txpower = rt2x00_get_field16(eeprom, |
1146 | rt2x00_set_field32(®, TX_PWR_CFG_4_UKNOWN7, value); | 1153 | EEPROM_TXPOWER_BYRATE_RATE3); |
1147 | rt2x00_set_field32(®, TX_PWR_CFG_4_UKNOWN8, value); | 1154 | rt2x00_set_field32(®, 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(®, 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(®, 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(®, 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(®, 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 | ||
1151 | static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev, | 1200 | static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev, |