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 | |
| 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')
| -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, |
