aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ar9170/phy.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/wireless/ath/ar9170/phy.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/wireless/ath/ar9170/phy.c')
-rw-r--r--drivers/net/wireless/ath/ar9170/phy.c99
1 files changed, 82 insertions, 17 deletions
diff --git a/drivers/net/wireless/ath/ar9170/phy.c b/drivers/net/wireless/ath/ar9170/phy.c
index dbd488da18b1..45a415ea809a 100644
--- a/drivers/net/wireless/ath/ar9170/phy.c
+++ b/drivers/net/wireless/ath/ar9170/phy.c
@@ -1239,9 +1239,6 @@ static u8 ar9170_get_max_edge_power(struct ar9170 *ar,
1239 struct ar9170_calctl_edges edges[], 1239 struct ar9170_calctl_edges edges[],
1240 u32 freq) 1240 u32 freq)
1241{ 1241{
1242/* TODO: move somewhere else */
1243#define AR5416_MAX_RATE_POWER 63
1244
1245 int i; 1242 int i;
1246 u8 rc = AR5416_MAX_RATE_POWER; 1243 u8 rc = AR5416_MAX_RATE_POWER;
1247 u8 f; 1244 u8 f;
@@ -1259,10 +1256,11 @@ static u8 ar9170_get_max_edge_power(struct ar9170 *ar,
1259 break; 1256 break;
1260 } 1257 }
1261 if (i > 0 && f < edges[i].channel) { 1258 if (i > 0 && f < edges[i].channel) {
1262 if (f > edges[i-1].channel && 1259 if (f > edges[i - 1].channel &&
1263 edges[i-1].power_flags & AR9170_CALCTL_EDGE_FLAGS) { 1260 edges[i - 1].power_flags &
1261 AR9170_CALCTL_EDGE_FLAGS) {
1264 /* lower channel has the inband flag set */ 1262 /* lower channel has the inband flag set */
1265 rc = edges[i-1].power_flags & 1263 rc = edges[i - 1].power_flags &
1266 ~AR9170_CALCTL_EDGE_FLAGS; 1264 ~AR9170_CALCTL_EDGE_FLAGS;
1267 } 1265 }
1268 break; 1266 break;
@@ -1270,18 +1268,48 @@ static u8 ar9170_get_max_edge_power(struct ar9170 *ar,
1270 } 1268 }
1271 1269
1272 if (i == AR5416_NUM_BAND_EDGES) { 1270 if (i == AR5416_NUM_BAND_EDGES) {
1273 if (f > edges[i-1].channel && 1271 if (f > edges[i - 1].channel &&
1274 edges[i-1].power_flags & AR9170_CALCTL_EDGE_FLAGS) { 1272 edges[i - 1].power_flags & AR9170_CALCTL_EDGE_FLAGS) {
1275 /* lower channel has the inband flag set */ 1273 /* lower channel has the inband flag set */
1276 rc = edges[i-1].power_flags & 1274 rc = edges[i - 1].power_flags &
1277 ~AR9170_CALCTL_EDGE_FLAGS; 1275 ~AR9170_CALCTL_EDGE_FLAGS;
1278 } 1276 }
1279 } 1277 }
1280 return rc; 1278 return rc;
1281} 1279}
1282 1280
1283/* calculate the conformance test limits and apply them to ar->power* 1281static u8 ar9170_get_heavy_clip(struct ar9170 *ar,
1284 * (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)
1285 */ 1313 */
1286static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw) 1314static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
1287{ 1315{
@@ -1295,7 +1323,8 @@ static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
1295 int pwr_cal_len; 1323 int pwr_cal_len;
1296 } *modes; 1324 } *modes;
1297 1325
1298 /* order is relevant in the mode_list_*: we fall back to the 1326 /*
1327 * order is relevant in the mode_list_*: we fall back to the
1299 * lower indices if any mode is missed in the EEPROM. 1328 * lower indices if any mode is missed in the EEPROM.
1300 */ 1329 */
1301 struct ctl_modes mode_list_2ghz[] = { 1330 struct ctl_modes mode_list_2ghz[] = {
@@ -1313,7 +1342,10 @@ static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
1313 1342
1314#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])
1315 1344
1316 /* TODO: investigate the differences between OTUS' 1345 ar->phy_heavy_clip = 0;
1346
1347 /*
1348 * TODO: investigate the differences between OTUS'
1317 * hpreg.c::zfHpGetRegulatoryDomain() and 1349 * hpreg.c::zfHpGetRegulatoryDomain() and
1318 * ath/regd.c::ath_regd_get_band_ctl() - 1350 * ath/regd.c::ath_regd_get_band_ctl() -
1319 * e.g. for FCC3_WORLD the OTUS procedure 1351 * e.g. for FCC3_WORLD the OTUS procedure
@@ -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) {
@@ -1360,13 +1401,15 @@ static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
1360 ar9170_get_max_edge_power(ar, EDGES(ctl_idx, 1), 1401 ar9170_get_max_edge_power(ar, EDGES(ctl_idx, 1),
1361 freq+f_off); 1402 freq+f_off);
1362 1403
1363 /* TODO: check if the regulatory max. power is 1404 /*
1405 * TODO: check if the regulatory max. power is
1364 * controlled by cfg80211 for DFS 1406 * controlled by cfg80211 for DFS
1365 * (hpmain applies it to max_power itself for DFS freq) 1407 * (hpmain applies it to max_power itself for DFS freq)
1366 */ 1408 */
1367 1409
1368 } else { 1410 } else {
1369 /* Workaround in otus driver, hpmain.c, line 3906: 1411 /*
1412 * Workaround in otus driver, hpmain.c, line 3906:
1370 * if no data for 5GHT20 are found, take the 1413 * if no data for 5GHT20 are found, take the
1371 * legacy 5G value. 1414 * legacy 5G value.
1372 * We extend this here to fallback from any other *HT or 1415 * We extend this here to fallback from any other *HT or
@@ -1390,6 +1433,19 @@ static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
1390 modes[i].max_power); 1433 modes[i].max_power);
1391 } 1434 }
1392 } 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
1393#undef EDGES 1449#undef EDGES
1394} 1450}
1395 1451
@@ -1499,8 +1555,6 @@ static int ar9170_set_power_cal(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
1499 /* calc. conformance test limits and apply to ar->power*[] */ 1555 /* calc. conformance test limits and apply to ar->power*[] */
1500 ar9170_calc_ctl(ar, freq, bw); 1556 ar9170_calc_ctl(ar, freq, bw);
1501 1557
1502 /* TODO: (heavy clip) regulatory domain power level fine-tuning. */
1503
1504 /* set ACK/CTS TX power */ 1558 /* set ACK/CTS TX power */
1505 ar9170_regwrite_begin(ar); 1559 ar9170_regwrite_begin(ar);
1506 1560
@@ -1643,6 +1697,17 @@ int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1643 if (err) 1697 if (err)
1644 return err; 1698 return err;
1645 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
1646 for (i = 0; i < 2; i++) { 1711 for (i = 0; i < 2; i++) {
1647 ar->noise[i] = ar9170_calc_noise_dbm( 1712 ar->noise[i] = ar9170_calc_noise_dbm(
1648 (le32_to_cpu(vals[2 + i]) >> 19) & 0x1ff); 1713 (le32_to_cpu(vals[2 + i]) >> 19) & 0x1ff);