aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath5k/phy.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/phy.c')
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c493
1 files changed, 464 insertions, 29 deletions
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index b48b29dca3d2..d0d1c350025a 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -168,9 +168,6 @@ int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah)
168 * tx power and a Peak to Average Power Detector (PAPD) will try 168 * tx power and a Peak to Average Power Detector (PAPD) will try
169 * to measure the gain. 169 * to measure the gain.
170 * 170 *
171 * TODO: Use propper tx power setting for the probe packet so
172 * that we don't observe a serious power drop on the receiver
173 *
174 * XXX: How about forcing a tx packet (bypassing PCU arbitrator etc) 171 * XXX: How about forcing a tx packet (bypassing PCU arbitrator etc)
175 * just after we enable the probe so that we don't mess with 172 * just after we enable the probe so that we don't mess with
176 * standard traffic ? Maybe it's time to use sw interrupts and 173 * standard traffic ? Maybe it's time to use sw interrupts and
@@ -186,7 +183,7 @@ static void ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah)
186 183
187 /* Send the packet with 2dB below max power as 184 /* Send the packet with 2dB below max power as
188 * patent doc suggest */ 185 * patent doc suggest */
189 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max_pwr - 4, 186 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_ofdm - 4,
190 AR5K_PHY_PAPD_PROBE_TXPOWER) | 187 AR5K_PHY_PAPD_PROBE_TXPOWER) |
191 AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE); 188 AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
192 189
@@ -1356,6 +1353,257 @@ int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
1356 return ret; 1353 return ret;
1357} 1354}
1358 1355
1356/***************************\
1357* Spur mitigation functions *
1358\***************************/
1359
1360bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
1361 struct ieee80211_channel *channel)
1362{
1363 u8 refclk_freq;
1364
1365 if ((ah->ah_radio == AR5K_RF5112) ||
1366 (ah->ah_radio == AR5K_RF5413) ||
1367 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
1368 refclk_freq = 40;
1369 else
1370 refclk_freq = 32;
1371
1372 if ((channel->center_freq % refclk_freq != 0) &&
1373 ((channel->center_freq % refclk_freq < 10) ||
1374 (channel->center_freq % refclk_freq > 22)))
1375 return true;
1376 else
1377 return false;
1378}
1379
1380void
1381ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
1382 struct ieee80211_channel *channel)
1383{
1384 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1385 u32 mag_mask[4] = {0, 0, 0, 0};
1386 u32 pilot_mask[2] = {0, 0};
1387 /* Note: fbin values are scaled up by 2 */
1388 u16 spur_chan_fbin, chan_fbin, symbol_width, spur_detection_window;
1389 s32 spur_delta_phase, spur_freq_sigma_delta;
1390 s32 spur_offset, num_symbols_x16;
1391 u8 num_symbol_offsets, i, freq_band;
1392
1393 /* Convert current frequency to fbin value (the same way channels
1394 * are stored on EEPROM, check out ath5k_eeprom_bin2freq) and scale
1395 * up by 2 so we can compare it later */
1396 if (channel->hw_value & CHANNEL_2GHZ) {
1397 chan_fbin = (channel->center_freq - 2300) * 10;
1398 freq_band = AR5K_EEPROM_BAND_2GHZ;
1399 } else {
1400 chan_fbin = (channel->center_freq - 4900) * 10;
1401 freq_band = AR5K_EEPROM_BAND_5GHZ;
1402 }
1403
1404 /* Check if any spur_chan_fbin from EEPROM is
1405 * within our current channel's spur detection range */
1406 spur_chan_fbin = AR5K_EEPROM_NO_SPUR;
1407 spur_detection_window = AR5K_SPUR_CHAN_WIDTH;
1408 /* XXX: Half/Quarter channels ?*/
1409 if (channel->hw_value & CHANNEL_TURBO)
1410 spur_detection_window *= 2;
1411
1412 for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) {
1413 spur_chan_fbin = ee->ee_spur_chans[i][freq_band];
1414
1415 /* Note: mask cleans AR5K_EEPROM_NO_SPUR flag
1416 * so it's zero if we got nothing from EEPROM */
1417 if (spur_chan_fbin == AR5K_EEPROM_NO_SPUR) {
1418 spur_chan_fbin &= AR5K_EEPROM_SPUR_CHAN_MASK;
1419 break;
1420 }
1421
1422 if ((chan_fbin - spur_detection_window <=
1423 (spur_chan_fbin & AR5K_EEPROM_SPUR_CHAN_MASK)) &&
1424 (chan_fbin + spur_detection_window >=
1425 (spur_chan_fbin & AR5K_EEPROM_SPUR_CHAN_MASK))) {
1426 spur_chan_fbin &= AR5K_EEPROM_SPUR_CHAN_MASK;
1427 break;
1428 }
1429 }
1430
1431 /* We need to enable spur filter for this channel */
1432 if (spur_chan_fbin) {
1433 spur_offset = spur_chan_fbin - chan_fbin;
1434 /*
1435 * Calculate deltas:
1436 * spur_freq_sigma_delta -> spur_offset / sample_freq << 21
1437 * spur_delta_phase -> spur_offset / chip_freq << 11
1438 * Note: Both values have 100KHz resolution
1439 */
1440 /* XXX: Half/Quarter rate channels ? */
1441 switch (channel->hw_value) {
1442 case CHANNEL_A:
1443 /* Both sample_freq and chip_freq are 40MHz */
1444 spur_delta_phase = (spur_offset << 17) / 25;
1445 spur_freq_sigma_delta = (spur_delta_phase >> 10);
1446 symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
1447 break;
1448 case CHANNEL_G:
1449 /* sample_freq -> 40MHz chip_freq -> 44MHz
1450 * (for b compatibility) */
1451 spur_freq_sigma_delta = (spur_offset << 8) / 55;
1452 spur_delta_phase = (spur_offset << 17) / 25;
1453 symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
1454 break;
1455 case CHANNEL_T:
1456 case CHANNEL_TG:
1457 /* Both sample_freq and chip_freq are 80MHz */
1458 spur_delta_phase = (spur_offset << 16) / 25;
1459 spur_freq_sigma_delta = (spur_delta_phase >> 10);
1460 symbol_width = AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz;
1461 break;
1462 default:
1463 return;
1464 }
1465
1466 /* Calculate pilot and magnitude masks */
1467
1468 /* Scale up spur_offset by 1000 to switch to 100HZ resolution
1469 * and divide by symbol_width to find how many symbols we have
1470 * Note: number of symbols is scaled up by 16 */
1471 num_symbols_x16 = ((spur_offset * 1000) << 4) / symbol_width;
1472
1473 /* Spur is on a symbol if num_symbols_x16 % 16 is zero */
1474 if (!(num_symbols_x16 & 0xF))
1475 /* _X_ */
1476 num_symbol_offsets = 3;
1477 else
1478 /* _xx_ */
1479 num_symbol_offsets = 4;
1480
1481 for (i = 0; i < num_symbol_offsets; i++) {
1482
1483 /* Calculate pilot mask */
1484 s32 curr_sym_off =
1485 (num_symbols_x16 / 16) + i + 25;
1486
1487 /* Pilot magnitude mask seems to be a way to
1488 * declare the boundaries for our detection
1489 * window or something, it's 2 for the middle
1490 * value(s) where the symbol is expected to be
1491 * and 1 on the boundary values */
1492 u8 plt_mag_map =
1493 (i == 0 || i == (num_symbol_offsets - 1))
1494 ? 1 : 2;
1495
1496 if (curr_sym_off >= 0 && curr_sym_off <= 32) {
1497 if (curr_sym_off <= 25)
1498 pilot_mask[0] |= 1 << curr_sym_off;
1499 else if (curr_sym_off >= 27)
1500 pilot_mask[0] |= 1 << (curr_sym_off - 1);
1501 } else if (curr_sym_off >= 33 && curr_sym_off <= 52)
1502 pilot_mask[1] |= 1 << (curr_sym_off - 33);
1503
1504 /* Calculate magnitude mask (for viterbi decoder) */
1505 if (curr_sym_off >= -1 && curr_sym_off <= 14)
1506 mag_mask[0] |=
1507 plt_mag_map << (curr_sym_off + 1) * 2;
1508 else if (curr_sym_off >= 15 && curr_sym_off <= 30)
1509 mag_mask[1] |=
1510 plt_mag_map << (curr_sym_off - 15) * 2;
1511 else if (curr_sym_off >= 31 && curr_sym_off <= 46)
1512 mag_mask[2] |=
1513 plt_mag_map << (curr_sym_off - 31) * 2;
1514 else if (curr_sym_off >= 46 && curr_sym_off <= 53)
1515 mag_mask[3] |=
1516 plt_mag_map << (curr_sym_off - 47) * 2;
1517
1518 }
1519
1520 /* Write settings on hw to enable spur filter */
1521 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
1522 AR5K_PHY_BIN_MASK_CTL_RATE, 0xff);
1523 /* XXX: Self correlator also ? */
1524 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
1525 AR5K_PHY_IQ_PILOT_MASK_EN |
1526 AR5K_PHY_IQ_CHAN_MASK_EN |
1527 AR5K_PHY_IQ_SPUR_FILT_EN);
1528
1529 /* Set delta phase and freq sigma delta */
1530 ath5k_hw_reg_write(ah,
1531 AR5K_REG_SM(spur_delta_phase,
1532 AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE) |
1533 AR5K_REG_SM(spur_freq_sigma_delta,
1534 AR5K_PHY_TIMING_11_SPUR_FREQ_SD) |
1535 AR5K_PHY_TIMING_11_USE_SPUR_IN_AGC,
1536 AR5K_PHY_TIMING_11);
1537
1538 /* Write pilot masks */
1539 ath5k_hw_reg_write(ah, pilot_mask[0], AR5K_PHY_TIMING_7);
1540 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_8,
1541 AR5K_PHY_TIMING_8_PILOT_MASK_2,
1542 pilot_mask[1]);
1543
1544 ath5k_hw_reg_write(ah, pilot_mask[0], AR5K_PHY_TIMING_9);
1545 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_10,
1546 AR5K_PHY_TIMING_10_PILOT_MASK_2,
1547 pilot_mask[1]);
1548
1549 /* Write magnitude masks */
1550 ath5k_hw_reg_write(ah, mag_mask[0], AR5K_PHY_BIN_MASK_1);
1551 ath5k_hw_reg_write(ah, mag_mask[1], AR5K_PHY_BIN_MASK_2);
1552 ath5k_hw_reg_write(ah, mag_mask[2], AR5K_PHY_BIN_MASK_3);
1553 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
1554 AR5K_PHY_BIN_MASK_CTL_MASK_4,
1555 mag_mask[3]);
1556
1557 ath5k_hw_reg_write(ah, mag_mask[0], AR5K_PHY_BIN_MASK2_1);
1558 ath5k_hw_reg_write(ah, mag_mask[1], AR5K_PHY_BIN_MASK2_2);
1559 ath5k_hw_reg_write(ah, mag_mask[2], AR5K_PHY_BIN_MASK2_3);
1560 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK2_4,
1561 AR5K_PHY_BIN_MASK2_4_MASK_4,
1562 mag_mask[3]);
1563
1564 } else if (ath5k_hw_reg_read(ah, AR5K_PHY_IQ) &
1565 AR5K_PHY_IQ_SPUR_FILT_EN) {
1566 /* Clean up spur mitigation settings and disable fliter */
1567 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
1568 AR5K_PHY_BIN_MASK_CTL_RATE, 0);
1569 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_IQ,
1570 AR5K_PHY_IQ_PILOT_MASK_EN |
1571 AR5K_PHY_IQ_CHAN_MASK_EN |
1572 AR5K_PHY_IQ_SPUR_FILT_EN);
1573 ath5k_hw_reg_write(ah, 0, AR5K_PHY_TIMING_11);
1574
1575 /* Clear pilot masks */
1576 ath5k_hw_reg_write(ah, 0, AR5K_PHY_TIMING_7);
1577 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_8,
1578 AR5K_PHY_TIMING_8_PILOT_MASK_2,
1579 0);
1580
1581 ath5k_hw_reg_write(ah, 0, AR5K_PHY_TIMING_9);
1582 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_10,
1583 AR5K_PHY_TIMING_10_PILOT_MASK_2,
1584 0);
1585
1586 /* Clear magnitude masks */
1587 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK_1);
1588 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK_2);
1589 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK_3);
1590 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
1591 AR5K_PHY_BIN_MASK_CTL_MASK_4,
1592 0);
1593
1594 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK2_1);
1595 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK2_2);
1596 ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK2_3);
1597 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK2_4,
1598 AR5K_PHY_BIN_MASK2_4_MASK_4,
1599 0);
1600 }
1601}
1602
1603/********************\
1604 Misc PHY functions
1605\********************/
1606
1359int ath5k_hw_phy_disable(struct ath5k_hw *ah) 1607int ath5k_hw_phy_disable(struct ath5k_hw *ah)
1360{ 1608{
1361 ATH5K_TRACE(ah->ah_sc); 1609 ATH5K_TRACE(ah->ah_sc);
@@ -1365,10 +1613,6 @@ int ath5k_hw_phy_disable(struct ath5k_hw *ah)
1365 return 0; 1613 return 0;
1366} 1614}
1367 1615
1368/********************\
1369 Misc PHY functions
1370\********************/
1371
1372/* 1616/*
1373 * Get the PHY Chip revision 1617 * Get the PHY Chip revision
1374 */ 1618 */
@@ -1417,25 +1661,189 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
1417 return ret; 1661 return ret;
1418} 1662}
1419 1663
1664/*****************\
1665* Antenna control *
1666\*****************/
1667
1420void /*TODO:Boundary check*/ 1668void /*TODO:Boundary check*/
1421ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant) 1669ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant)
1422{ 1670{
1423 ATH5K_TRACE(ah->ah_sc); 1671 ATH5K_TRACE(ah->ah_sc);
1424 /*Just a try M.F.*/ 1672
1425 if (ah->ah_version != AR5K_AR5210) 1673 if (ah->ah_version != AR5K_AR5210)
1426 ath5k_hw_reg_write(ah, ant, AR5K_DEFAULT_ANTENNA); 1674 ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA);
1427} 1675}
1428 1676
1429unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah) 1677unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah)
1430{ 1678{
1431 ATH5K_TRACE(ah->ah_sc); 1679 ATH5K_TRACE(ah->ah_sc);
1432 /*Just a try M.F.*/ 1680
1433 if (ah->ah_version != AR5K_AR5210) 1681 if (ah->ah_version != AR5K_AR5210)
1434 return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA); 1682 return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA) & 0x7;
1435 1683
1436 return false; /*XXX: What do we return for 5210 ?*/ 1684 return false; /*XXX: What do we return for 5210 ?*/
1437} 1685}
1438 1686
1687/*
1688 * Enable/disable fast rx antenna diversity
1689 */
1690static void
1691ath5k_hw_set_fast_div(struct ath5k_hw *ah, u8 ee_mode, bool enable)
1692{
1693 switch (ee_mode) {
1694 case AR5K_EEPROM_MODE_11G:
1695 /* XXX: This is set to
1696 * disabled on initvals !!! */
1697 case AR5K_EEPROM_MODE_11A:
1698 if (enable)
1699 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGCCTL,
1700 AR5K_PHY_AGCCTL_OFDM_DIV_DIS);
1701 else
1702 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
1703 AR5K_PHY_AGCCTL_OFDM_DIV_DIS);
1704 break;
1705 case AR5K_EEPROM_MODE_11B:
1706 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
1707 AR5K_PHY_AGCCTL_OFDM_DIV_DIS);
1708 break;
1709 default:
1710 return;
1711 }
1712
1713 if (enable) {
1714 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART,
1715 AR5K_PHY_RESTART_DIV_GC, 0xc);
1716
1717 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV,
1718 AR5K_PHY_FAST_ANT_DIV_EN);
1719 } else {
1720 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART,
1721 AR5K_PHY_RESTART_DIV_GC, 0x8);
1722
1723 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV,
1724 AR5K_PHY_FAST_ANT_DIV_EN);
1725 }
1726}
1727
1728/*
1729 * Set antenna operating mode
1730 */
1731void
1732ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
1733{
1734 struct ieee80211_channel *channel = &ah->ah_current_channel;
1735 bool use_def_for_tx, update_def_on_tx, use_def_for_rts, fast_div;
1736 bool use_def_for_sg;
1737 u8 def_ant, tx_ant, ee_mode;
1738 u32 sta_id1 = 0;
1739
1740 def_ant = ah->ah_def_ant;
1741
1742 ATH5K_TRACE(ah->ah_sc);
1743
1744 switch (channel->hw_value & CHANNEL_MODES) {
1745 case CHANNEL_A:
1746 case CHANNEL_T:
1747 case CHANNEL_XR:
1748 ee_mode = AR5K_EEPROM_MODE_11A;
1749 break;
1750 case CHANNEL_G:
1751 case CHANNEL_TG:
1752 ee_mode = AR5K_EEPROM_MODE_11G;
1753 break;
1754 case CHANNEL_B:
1755 ee_mode = AR5K_EEPROM_MODE_11B;
1756 break;
1757 default:
1758 ATH5K_ERR(ah->ah_sc,
1759 "invalid channel: %d\n", channel->center_freq);
1760 return;
1761 }
1762
1763 switch (ant_mode) {
1764 case AR5K_ANTMODE_DEFAULT:
1765 tx_ant = 0;
1766 use_def_for_tx = false;
1767 update_def_on_tx = false;
1768 use_def_for_rts = false;
1769 use_def_for_sg = false;
1770 fast_div = true;
1771 break;
1772 case AR5K_ANTMODE_FIXED_A:
1773 def_ant = 1;
1774 tx_ant = 0;
1775 use_def_for_tx = true;
1776 update_def_on_tx = false;
1777 use_def_for_rts = true;
1778 use_def_for_sg = true;
1779 fast_div = false;
1780 break;
1781 case AR5K_ANTMODE_FIXED_B:
1782 def_ant = 2;
1783 tx_ant = 0;
1784 use_def_for_tx = true;
1785 update_def_on_tx = false;
1786 use_def_for_rts = true;
1787 use_def_for_sg = true;
1788 fast_div = false;
1789 break;
1790 case AR5K_ANTMODE_SINGLE_AP:
1791 def_ant = 1; /* updated on tx */
1792 tx_ant = 0;
1793 use_def_for_tx = true;
1794 update_def_on_tx = true;
1795 use_def_for_rts = true;
1796 use_def_for_sg = true;
1797 fast_div = true;
1798 break;
1799 case AR5K_ANTMODE_SECTOR_AP:
1800 tx_ant = 1; /* variable */
1801 use_def_for_tx = false;
1802 update_def_on_tx = false;
1803 use_def_for_rts = true;
1804 use_def_for_sg = false;
1805 fast_div = false;
1806 break;
1807 case AR5K_ANTMODE_SECTOR_STA:
1808 tx_ant = 1; /* variable */
1809 use_def_for_tx = true;
1810 update_def_on_tx = false;
1811 use_def_for_rts = true;
1812 use_def_for_sg = false;
1813 fast_div = true;
1814 break;
1815 case AR5K_ANTMODE_DEBUG:
1816 def_ant = 1;
1817 tx_ant = 2;
1818 use_def_for_tx = false;
1819 update_def_on_tx = false;
1820 use_def_for_rts = false;
1821 use_def_for_sg = false;
1822 fast_div = false;
1823 break;
1824 default:
1825 return;
1826 }
1827
1828 ah->ah_tx_ant = tx_ant;
1829 ah->ah_ant_mode = ant_mode;
1830
1831 sta_id1 |= use_def_for_tx ? AR5K_STA_ID1_DEFAULT_ANTENNA : 0;
1832 sta_id1 |= update_def_on_tx ? AR5K_STA_ID1_DESC_ANTENNA : 0;
1833 sta_id1 |= use_def_for_rts ? AR5K_STA_ID1_RTS_DEF_ANTENNA : 0;
1834 sta_id1 |= use_def_for_sg ? AR5K_STA_ID1_SELFGEN_DEF_ANT : 0;
1835
1836 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_ANTENNA_SETTINGS);
1837
1838 if (sta_id1)
1839 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, sta_id1);
1840
1841 /* Note: set diversity before default antenna
1842 * because it won't work correctly */
1843 ath5k_hw_set_fast_div(ah, ee_mode, fast_div);
1844 ath5k_hw_set_def_antenna(ah, def_ant);
1845}
1846
1439 1847
1440/****************\ 1848/****************\
1441* TX power setup * 1849* TX power setup *
@@ -1750,8 +2158,6 @@ done:
1750 * Get the max edge power for this channel if 2158 * Get the max edge power for this channel if
1751 * we have such data from EEPROM's Conformance Test 2159 * we have such data from EEPROM's Conformance Test
1752 * Limits (CTL), and limit max power if needed. 2160 * Limits (CTL), and limit max power if needed.
1753 *
1754 * FIXME: Only works for world regulatory domains
1755 */ 2161 */
1756static void 2162static void
1757ath5k_get_max_ctl_power(struct ath5k_hw *ah, 2163ath5k_get_max_ctl_power(struct ath5k_hw *ah,
@@ -1767,26 +2173,23 @@ ath5k_get_max_ctl_power(struct ath5k_hw *ah,
1767 u8 ctl_idx = 0xFF; 2173 u8 ctl_idx = 0xFF;
1768 u32 target = channel->center_freq; 2174 u32 target = channel->center_freq;
1769 2175
1770 /* Find out a CTL for our mode that's not mapped 2176 ctl_mode = ath_regd_get_band_ctl(&ah->ah_regulatory, channel->band);
1771 * on a specific reg domain. 2177
1772 *
1773 * TODO: Map our current reg domain to one of the 3 available
1774 * reg domain ids so that we can support more CTLs. */
1775 switch (channel->hw_value & CHANNEL_MODES) { 2178 switch (channel->hw_value & CHANNEL_MODES) {
1776 case CHANNEL_A: 2179 case CHANNEL_A:
1777 ctl_mode = AR5K_CTL_11A | AR5K_CTL_NO_REGDOMAIN; 2180 ctl_mode |= AR5K_CTL_11A;
1778 break; 2181 break;
1779 case CHANNEL_G: 2182 case CHANNEL_G:
1780 ctl_mode = AR5K_CTL_11G | AR5K_CTL_NO_REGDOMAIN; 2183 ctl_mode |= AR5K_CTL_11G;
1781 break; 2184 break;
1782 case CHANNEL_B: 2185 case CHANNEL_B:
1783 ctl_mode = AR5K_CTL_11B | AR5K_CTL_NO_REGDOMAIN; 2186 ctl_mode |= AR5K_CTL_11B;
1784 break; 2187 break;
1785 case CHANNEL_T: 2188 case CHANNEL_T:
1786 ctl_mode = AR5K_CTL_TURBO | AR5K_CTL_NO_REGDOMAIN; 2189 ctl_mode |= AR5K_CTL_TURBO;
1787 break; 2190 break;
1788 case CHANNEL_TG: 2191 case CHANNEL_TG:
1789 ctl_mode = AR5K_CTL_TURBOG | AR5K_CTL_NO_REGDOMAIN; 2192 ctl_mode |= AR5K_CTL_TURBOG;
1790 break; 2193 break;
1791 case CHANNEL_XR: 2194 case CHANNEL_XR:
1792 /* Fall through */ 2195 /* Fall through */
@@ -2482,8 +2885,19 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
2482 for (i = 8; i <= 15; i++) 2885 for (i = 8; i <= 15; i++)
2483 rates[i] -= ah->ah_txpower.txp_cck_ofdm_gainf_delta; 2886 rates[i] -= ah->ah_txpower.txp_cck_ofdm_gainf_delta;
2484 2887
2485 ah->ah_txpower.txp_min_pwr = rates[7]; 2888 /* Now that we have all rates setup use table offset to
2486 ah->ah_txpower.txp_max_pwr = rates[0]; 2889 * match the power range set by user with the power indices
2890 * on PCDAC/PDADC table */
2891 for (i = 0; i < 16; i++) {
2892 rates[i] += ah->ah_txpower.txp_offset;
2893 /* Don't get out of bounds */
2894 if (rates[i] > 63)
2895 rates[i] = 63;
2896 }
2897
2898 /* Min/max in 0.25dB units */
2899 ah->ah_txpower.txp_min_pwr = 2 * rates[7];
2900 ah->ah_txpower.txp_max_pwr = 2 * rates[0];
2487 ah->ah_txpower.txp_ofdm = rates[7]; 2901 ah->ah_txpower.txp_ofdm = rates[7];
2488} 2902}
2489 2903
@@ -2591,16 +3005,37 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
2591 return 0; 3005 return 0;
2592} 3006}
2593 3007
2594int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 mode, u8 txpower) 3008int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
2595{ 3009{
2596 /*Just a try M.F.*/ 3010 /*Just a try M.F.*/
2597 struct ieee80211_channel *channel = &ah->ah_current_channel; 3011 struct ieee80211_channel *channel = &ah->ah_current_channel;
3012 u8 ee_mode;
2598 3013
2599 ATH5K_TRACE(ah->ah_sc); 3014 ATH5K_TRACE(ah->ah_sc);
3015
3016 switch (channel->hw_value & CHANNEL_MODES) {
3017 case CHANNEL_A:
3018 case CHANNEL_T:
3019 case CHANNEL_XR:
3020 ee_mode = AR5K_EEPROM_MODE_11A;
3021 break;
3022 case CHANNEL_G:
3023 case CHANNEL_TG:
3024 ee_mode = AR5K_EEPROM_MODE_11G;
3025 break;
3026 case CHANNEL_B:
3027 ee_mode = AR5K_EEPROM_MODE_11B;
3028 break;
3029 default:
3030 ATH5K_ERR(ah->ah_sc,
3031 "invalid channel: %d\n", channel->center_freq);
3032 return -EINVAL;
3033 }
3034
2600 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER, 3035 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,
2601 "changing txpower to %d\n", txpower); 3036 "changing txpower to %d\n", txpower);
2602 3037
2603 return ath5k_hw_txpower(ah, channel, mode, txpower); 3038 return ath5k_hw_txpower(ah, channel, ee_mode, txpower);
2604} 3039}
2605 3040
2606#undef _ATH5K_PHY 3041#undef _ATH5K_PHY