diff options
author | Nick Kossifidis <mick@madwifi-project.org> | 2009-04-30 15:55:49 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-05-06 15:14:56 -0400 |
commit | 2bed03ebf62f9d013a455209bf30d7e086120443 (patch) | |
tree | 35592ca12f0e4425213e317895612c3ce15ad3a5 /drivers/net/wireless/ath/ath5k/phy.c | |
parent | 6f5f39c95af519c24c0187950147eb79d07d1940 (diff) |
ath5k: Implement antenna control
* Add code to support the various antenna scenarios supported by hw
* For now hardcode the default scenario (single or dual omnis with
tx/rx diversity working and tx antenna handled by session -hw keeps
track on which antenna it got ack from each ap/station and maps each
ap/station to one of the antennas-).
Signed-off-by: Nick Kossifidis <mickflemm@gmail.com>
Signed-off-by: Bob Copeland <me@bobcopeland.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/phy.c')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/phy.c | 174 |
1 files changed, 169 insertions, 5 deletions
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index bb61b8e2dce9..fd93c4e20214 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c | |||
@@ -1414,25 +1414,189 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan) | |||
1414 | return ret; | 1414 | return ret; |
1415 | } | 1415 | } |
1416 | 1416 | ||
1417 | /*****************\ | ||
1418 | * Antenna control * | ||
1419 | \*****************/ | ||
1420 | |||
1417 | void /*TODO:Boundary check*/ | 1421 | void /*TODO:Boundary check*/ |
1418 | ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant) | 1422 | ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant) |
1419 | { | 1423 | { |
1420 | ATH5K_TRACE(ah->ah_sc); | 1424 | ATH5K_TRACE(ah->ah_sc); |
1421 | /*Just a try M.F.*/ | 1425 | |
1422 | if (ah->ah_version != AR5K_AR5210) | 1426 | if (ah->ah_version != AR5K_AR5210) |
1423 | ath5k_hw_reg_write(ah, ant, AR5K_DEFAULT_ANTENNA); | 1427 | ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA); |
1424 | } | 1428 | } |
1425 | 1429 | ||
1426 | unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah) | 1430 | unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah) |
1427 | { | 1431 | { |
1428 | ATH5K_TRACE(ah->ah_sc); | 1432 | ATH5K_TRACE(ah->ah_sc); |
1429 | /*Just a try M.F.*/ | 1433 | |
1430 | if (ah->ah_version != AR5K_AR5210) | 1434 | if (ah->ah_version != AR5K_AR5210) |
1431 | return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA); | 1435 | return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA) & 0x7; |
1432 | 1436 | ||
1433 | return false; /*XXX: What do we return for 5210 ?*/ | 1437 | return false; /*XXX: What do we return for 5210 ?*/ |
1434 | } | 1438 | } |
1435 | 1439 | ||
1440 | /* | ||
1441 | * Enable/disable fast rx antenna diversity | ||
1442 | */ | ||
1443 | static void | ||
1444 | ath5k_hw_set_fast_div(struct ath5k_hw *ah, u8 ee_mode, bool enable) | ||
1445 | { | ||
1446 | switch (ee_mode) { | ||
1447 | case AR5K_EEPROM_MODE_11G: | ||
1448 | /* XXX: This is set to | ||
1449 | * disabled on initvals !!! */ | ||
1450 | case AR5K_EEPROM_MODE_11A: | ||
1451 | if (enable) | ||
1452 | AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGCCTL, | ||
1453 | AR5K_PHY_AGCCTL_OFDM_DIV_DIS); | ||
1454 | else | ||
1455 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, | ||
1456 | AR5K_PHY_AGCCTL_OFDM_DIV_DIS); | ||
1457 | break; | ||
1458 | case AR5K_EEPROM_MODE_11B: | ||
1459 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, | ||
1460 | AR5K_PHY_AGCCTL_OFDM_DIV_DIS); | ||
1461 | break; | ||
1462 | default: | ||
1463 | return; | ||
1464 | } | ||
1465 | |||
1466 | if (enable) { | ||
1467 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART, | ||
1468 | AR5K_PHY_RESTART_DIV_GC, 0xc); | ||
1469 | |||
1470 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV, | ||
1471 | AR5K_PHY_FAST_ANT_DIV_EN); | ||
1472 | } else { | ||
1473 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART, | ||
1474 | AR5K_PHY_RESTART_DIV_GC, 0x8); | ||
1475 | |||
1476 | AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV, | ||
1477 | AR5K_PHY_FAST_ANT_DIV_EN); | ||
1478 | } | ||
1479 | } | ||
1480 | |||
1481 | /* | ||
1482 | * Set antenna operating mode | ||
1483 | */ | ||
1484 | void | ||
1485 | ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) | ||
1486 | { | ||
1487 | struct ieee80211_channel *channel = &ah->ah_current_channel; | ||
1488 | bool use_def_for_tx, update_def_on_tx, use_def_for_rts, fast_div; | ||
1489 | bool use_def_for_sg; | ||
1490 | u8 def_ant, tx_ant, ee_mode; | ||
1491 | u32 sta_id1 = 0; | ||
1492 | |||
1493 | def_ant = ah->ah_def_ant; | ||
1494 | |||
1495 | ATH5K_TRACE(ah->ah_sc); | ||
1496 | |||
1497 | switch (channel->hw_value & CHANNEL_MODES) { | ||
1498 | case CHANNEL_A: | ||
1499 | case CHANNEL_T: | ||
1500 | case CHANNEL_XR: | ||
1501 | ee_mode = AR5K_EEPROM_MODE_11A; | ||
1502 | break; | ||
1503 | case CHANNEL_G: | ||
1504 | case CHANNEL_TG: | ||
1505 | ee_mode = AR5K_EEPROM_MODE_11G; | ||
1506 | break; | ||
1507 | case CHANNEL_B: | ||
1508 | ee_mode = AR5K_EEPROM_MODE_11B; | ||
1509 | break; | ||
1510 | default: | ||
1511 | ATH5K_ERR(ah->ah_sc, | ||
1512 | "invalid channel: %d\n", channel->center_freq); | ||
1513 | return; | ||
1514 | } | ||
1515 | |||
1516 | switch (ant_mode) { | ||
1517 | case AR5K_ANTMODE_DEFAULT: | ||
1518 | tx_ant = 0; | ||
1519 | use_def_for_tx = false; | ||
1520 | update_def_on_tx = false; | ||
1521 | use_def_for_rts = false; | ||
1522 | use_def_for_sg = false; | ||
1523 | fast_div = true; | ||
1524 | break; | ||
1525 | case AR5K_ANTMODE_FIXED_A: | ||
1526 | def_ant = 1; | ||
1527 | tx_ant = 0; | ||
1528 | use_def_for_tx = true; | ||
1529 | update_def_on_tx = false; | ||
1530 | use_def_for_rts = true; | ||
1531 | use_def_for_sg = true; | ||
1532 | fast_div = false; | ||
1533 | break; | ||
1534 | case AR5K_ANTMODE_FIXED_B: | ||
1535 | def_ant = 2; | ||
1536 | tx_ant = 0; | ||
1537 | use_def_for_tx = true; | ||
1538 | update_def_on_tx = false; | ||
1539 | use_def_for_rts = true; | ||
1540 | use_def_for_sg = true; | ||
1541 | fast_div = false; | ||
1542 | break; | ||
1543 | case AR5K_ANTMODE_SINGLE_AP: | ||
1544 | def_ant = 1; /* updated on tx */ | ||
1545 | tx_ant = 0; | ||
1546 | use_def_for_tx = true; | ||
1547 | update_def_on_tx = true; | ||
1548 | use_def_for_rts = true; | ||
1549 | use_def_for_sg = true; | ||
1550 | fast_div = true; | ||
1551 | break; | ||
1552 | case AR5K_ANTMODE_SECTOR_AP: | ||
1553 | tx_ant = 1; /* variable */ | ||
1554 | use_def_for_tx = false; | ||
1555 | update_def_on_tx = false; | ||
1556 | use_def_for_rts = true; | ||
1557 | use_def_for_sg = false; | ||
1558 | fast_div = false; | ||
1559 | break; | ||
1560 | case AR5K_ANTMODE_SECTOR_STA: | ||
1561 | tx_ant = 1; /* variable */ | ||
1562 | use_def_for_tx = true; | ||
1563 | update_def_on_tx = false; | ||
1564 | use_def_for_rts = true; | ||
1565 | use_def_for_sg = false; | ||
1566 | fast_div = true; | ||
1567 | break; | ||
1568 | case AR5K_ANTMODE_DEBUG: | ||
1569 | def_ant = 1; | ||
1570 | tx_ant = 2; | ||
1571 | use_def_for_tx = false; | ||
1572 | update_def_on_tx = false; | ||
1573 | use_def_for_rts = false; | ||
1574 | use_def_for_sg = false; | ||
1575 | fast_div = false; | ||
1576 | break; | ||
1577 | default: | ||
1578 | return; | ||
1579 | } | ||
1580 | |||
1581 | ah->ah_tx_ant = tx_ant; | ||
1582 | ah->ah_ant_mode = ant_mode; | ||
1583 | |||
1584 | sta_id1 |= use_def_for_tx ? AR5K_STA_ID1_DEFAULT_ANTENNA : 0; | ||
1585 | sta_id1 |= update_def_on_tx ? AR5K_STA_ID1_DESC_ANTENNA : 0; | ||
1586 | sta_id1 |= use_def_for_rts ? AR5K_STA_ID1_RTS_DEF_ANTENNA : 0; | ||
1587 | sta_id1 |= use_def_for_sg ? AR5K_STA_ID1_SELFGEN_DEF_ANT : 0; | ||
1588 | |||
1589 | AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_ANTENNA_SETTINGS); | ||
1590 | |||
1591 | if (sta_id1) | ||
1592 | AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, sta_id1); | ||
1593 | |||
1594 | /* Note: set diversity before default antenna | ||
1595 | * because it won't work correctly */ | ||
1596 | ath5k_hw_set_fast_div(ah, ee_mode, fast_div); | ||
1597 | ath5k_hw_set_def_antenna(ah, def_ant); | ||
1598 | } | ||
1599 | |||
1436 | 1600 | ||
1437 | /****************\ | 1601 | /****************\ |
1438 | * TX power setup * | 1602 | * TX power setup * |