diff options
author | Joerg Albert <jal2@gmx.de> | 2009-09-15 16:23:06 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-10-07 16:39:38 -0400 |
commit | 7c52c07de8bd0433db6b3e0147544e5a2f01b786 (patch) | |
tree | 1888ac9a234eb64fb53dd1d0f8b84be9d040b138 | |
parent | 90f2908d3263e5c84c8408ce382a669b528b10e3 (diff) |
ar9170: add heavy clip handling
add heavy clip handling for 2.4GHz only (similar to the vendor driver).
Signed-off-by: Joerg Albert <jal2@gmx.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/ath/ar9170/ar9170.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ar9170/phy.c | 71 |
2 files changed, 69 insertions, 4 deletions
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h index c5576eec12ae..ec034af26980 100644 --- a/drivers/net/wireless/ath/ar9170/ar9170.h +++ b/drivers/net/wireless/ath/ar9170/ar9170.h | |||
@@ -202,6 +202,8 @@ struct ar9170 { | |||
202 | u8 power_2G_ht20[8]; | 202 | u8 power_2G_ht20[8]; |
203 | u8 power_2G_ht40[8]; | 203 | u8 power_2G_ht40[8]; |
204 | 204 | ||
205 | u8 phy_heavy_clip; | ||
206 | |||
205 | #ifdef CONFIG_AR9170_LEDS | 207 | #ifdef CONFIG_AR9170_LEDS |
206 | struct delayed_work led_work; | 208 | struct delayed_work led_work; |
207 | struct ar9170_led leds[AR9170_NUM_LEDS]; | 209 | struct ar9170_led leds[AR9170_NUM_LEDS]; |
diff --git a/drivers/net/wireless/ath/ar9170/phy.c b/drivers/net/wireless/ath/ar9170/phy.c index 07625a97851c..45a415ea809a 100644 --- a/drivers/net/wireless/ath/ar9170/phy.c +++ b/drivers/net/wireless/ath/ar9170/phy.c | |||
@@ -1278,8 +1278,38 @@ static u8 ar9170_get_max_edge_power(struct ar9170 *ar, | |||
1278 | return rc; | 1278 | return rc; |
1279 | } | 1279 | } |
1280 | 1280 | ||
1281 | /* calculate the conformance test limits and apply them to ar->power* | 1281 | static u8 ar9170_get_heavy_clip(struct ar9170 *ar, |
1282 | * (derived from otus hal/hpmain.c, line 3706 ff.) | 1282 | struct ar9170_calctl_edges edges[], |
1283 | u32 freq, enum ar9170_bw bw) | ||
1284 | { | ||
1285 | u8 f; | ||
1286 | int i; | ||
1287 | u8 rc = 0; | ||
1288 | |||
1289 | if (freq < 3000) | ||
1290 | f = freq - 2300; | ||
1291 | else | ||
1292 | f = (freq - 4800) / 5; | ||
1293 | |||
1294 | if (bw == AR9170_BW_40_BELOW || bw == AR9170_BW_40_ABOVE) | ||
1295 | rc |= 0xf0; | ||
1296 | |||
1297 | for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) { | ||
1298 | if (edges[i].channel == 0xff) | ||
1299 | break; | ||
1300 | if (f == edges[i].channel) { | ||
1301 | if (!(edges[i].power_flags & AR9170_CALCTL_EDGE_FLAGS)) | ||
1302 | rc |= 0x0f; | ||
1303 | break; | ||
1304 | } | ||
1305 | } | ||
1306 | |||
1307 | return rc; | ||
1308 | } | ||
1309 | |||
1310 | /* | ||
1311 | * calculate the conformance test limits and the heavy clip parameter | ||
1312 | * and apply them to ar->power* (derived from otus hal/hpmain.c, line 3706) | ||
1283 | */ | 1313 | */ |
1284 | static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw) | 1314 | static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw) |
1285 | { | 1315 | { |
@@ -1312,6 +1342,8 @@ static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw) | |||
1312 | 1342 | ||
1313 | #define EDGES(c, n) (ar->eeprom.ctl_data[c].control_edges[n]) | 1343 | #define EDGES(c, n) (ar->eeprom.ctl_data[c].control_edges[n]) |
1314 | 1344 | ||
1345 | ar->phy_heavy_clip = 0; | ||
1346 | |||
1315 | /* | 1347 | /* |
1316 | * TODO: investigate the differences between OTUS' | 1348 | * TODO: investigate the differences between OTUS' |
1317 | * hpreg.c::zfHpGetRegulatoryDomain() and | 1349 | * hpreg.c::zfHpGetRegulatoryDomain() and |
@@ -1347,6 +1379,15 @@ static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw) | |||
1347 | if (ctl_idx < AR5416_NUM_CTLS) { | 1379 | if (ctl_idx < AR5416_NUM_CTLS) { |
1348 | int f_off = 0; | 1380 | int f_off = 0; |
1349 | 1381 | ||
1382 | /* determine heav clip parameter from | ||
1383 | the 11G edges array */ | ||
1384 | if (modes[i].ctl_mode == CTL_11G) { | ||
1385 | ar->phy_heavy_clip = | ||
1386 | ar9170_get_heavy_clip(ar, | ||
1387 | EDGES(ctl_idx, 1), | ||
1388 | freq, bw); | ||
1389 | } | ||
1390 | |||
1350 | /* adjust freq for 40MHz */ | 1391 | /* adjust freq for 40MHz */ |
1351 | if (modes[i].ctl_mode == CTL_2GHT40 || | 1392 | if (modes[i].ctl_mode == CTL_2GHT40 || |
1352 | modes[i].ctl_mode == CTL_5GHT40) { | 1393 | modes[i].ctl_mode == CTL_5GHT40) { |
@@ -1392,6 +1433,19 @@ static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw) | |||
1392 | modes[i].max_power); | 1433 | modes[i].max_power); |
1393 | } | 1434 | } |
1394 | } | 1435 | } |
1436 | |||
1437 | if (ar->phy_heavy_clip & 0xf0) { | ||
1438 | ar->power_2G_ht40[0]--; | ||
1439 | ar->power_2G_ht40[1]--; | ||
1440 | ar->power_2G_ht40[2]--; | ||
1441 | } | ||
1442 | if (ar->phy_heavy_clip & 0xf) { | ||
1443 | ar->power_2G_ht20[0]++; | ||
1444 | ar->power_2G_ht20[1]++; | ||
1445 | ar->power_2G_ht20[2]++; | ||
1446 | } | ||
1447 | |||
1448 | |||
1395 | #undef EDGES | 1449 | #undef EDGES |
1396 | } | 1450 | } |
1397 | 1451 | ||
@@ -1501,8 +1555,6 @@ static int ar9170_set_power_cal(struct ar9170 *ar, u32 freq, enum ar9170_bw bw) | |||
1501 | /* calc. conformance test limits and apply to ar->power*[] */ | 1555 | /* calc. conformance test limits and apply to ar->power*[] */ |
1502 | ar9170_calc_ctl(ar, freq, bw); | 1556 | ar9170_calc_ctl(ar, freq, bw); |
1503 | 1557 | ||
1504 | /* TODO: (heavy clip) regulatory domain power level fine-tuning. */ | ||
1505 | |||
1506 | /* set ACK/CTS TX power */ | 1558 | /* set ACK/CTS TX power */ |
1507 | ar9170_regwrite_begin(ar); | 1559 | ar9170_regwrite_begin(ar); |
1508 | 1560 | ||
@@ -1645,6 +1697,17 @@ int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, | |||
1645 | if (err) | 1697 | if (err) |
1646 | return err; | 1698 | return err; |
1647 | 1699 | ||
1700 | if (ar->phy_heavy_clip) { | ||
1701 | err = ar9170_write_reg(ar, 0x1c59e0, | ||
1702 | 0x200 | ar->phy_heavy_clip); | ||
1703 | if (err) { | ||
1704 | if (ar9170_nag_limiter(ar)) | ||
1705 | printk(KERN_ERR "%s: failed to set " | ||
1706 | "heavy clip\n", | ||
1707 | wiphy_name(ar->hw->wiphy)); | ||
1708 | } | ||
1709 | } | ||
1710 | |||
1648 | for (i = 0; i < 2; i++) { | 1711 | for (i = 0; i < 2; i++) { |
1649 | ar->noise[i] = ar9170_calc_noise_dbm( | 1712 | ar->noise[i] = ar9170_calc_noise_dbm( |
1650 | (le32_to_cpu(vals[2 + i]) >> 19) & 0x1ff); | 1713 | (le32_to_cpu(vals[2 + i]) >> 19) & 0x1ff); |