aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath5k
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath5k')
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h37
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c1
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c210
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c73
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.h46
-rw-r--r--drivers/net/wireless/ath/ath5k/led.c6
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c6
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c493
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c7
-rw-r--r--drivers/net/wireless/ath/ath5k/reg.h9
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c70
11 files changed, 755 insertions, 203 deletions
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 60c6d2edc4b9..813718210338 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -209,7 +209,6 @@
209#define AR5K_TUNE_MAX_TXPOWER 63 209#define AR5K_TUNE_MAX_TXPOWER 63
210#define AR5K_TUNE_DEFAULT_TXPOWER 25 210#define AR5K_TUNE_DEFAULT_TXPOWER 25
211#define AR5K_TUNE_TPC_TXPOWER false 211#define AR5K_TUNE_TPC_TXPOWER false
212#define AR5K_TUNE_ANT_DIVERSITY true
213#define AR5K_TUNE_HWTXTRIES 4 212#define AR5K_TUNE_HWTXTRIES 4
214 213
215#define AR5K_INIT_CARR_SENSE_EN 1 214#define AR5K_INIT_CARR_SENSE_EN 1
@@ -420,6 +419,17 @@ enum ath5k_driver_mode {
420 AR5K_MODE_MAX = 5 419 AR5K_MODE_MAX = 5
421}; 420};
422 421
422enum ath5k_ant_mode {
423 AR5K_ANTMODE_DEFAULT = 0, /* default antenna setup */
424 AR5K_ANTMODE_FIXED_A = 1, /* only antenna A is present */
425 AR5K_ANTMODE_FIXED_B = 2, /* only antenna B is present */
426 AR5K_ANTMODE_SINGLE_AP = 3, /* sta locked on a single ap */
427 AR5K_ANTMODE_SECTOR_AP = 4, /* AP with tx antenna set on tx desc */
428 AR5K_ANTMODE_SECTOR_STA = 5, /* STA with tx antenna set on tx desc */
429 AR5K_ANTMODE_DEBUG = 6, /* Debug mode -A -> Rx, B-> Tx- */
430 AR5K_ANTMODE_MAX,
431};
432
423 433
424/****************\ 434/****************\
425 TX DEFINITIONS 435 TX DEFINITIONS
@@ -1051,8 +1061,11 @@ struct ath5k_hw {
1051 bool ah_software_retry; 1061 bool ah_software_retry;
1052 u32 ah_limit_tx_retries; 1062 u32 ah_limit_tx_retries;
1053 1063
1054 u32 ah_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; 1064 /* Antenna Control */
1055 bool ah_ant_diversity; 1065 u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
1066 u8 ah_ant_mode;
1067 u8 ah_tx_ant;
1068 u8 ah_def_ant;
1056 1069
1057 u8 ah_sta_id[ETH_ALEN]; 1070 u8 ah_sta_id[ETH_ALEN];
1058 1071
@@ -1100,11 +1113,12 @@ struct ath5k_hw {
1100 /* Values in 0.25dB units */ 1113 /* Values in 0.25dB units */
1101 s16 txp_min_pwr; 1114 s16 txp_min_pwr;
1102 s16 txp_max_pwr; 1115 s16 txp_max_pwr;
1116 /* Values in 0.5dB units */
1103 s16 txp_offset; 1117 s16 txp_offset;
1104 s16 txp_ofdm; 1118 s16 txp_ofdm;
1105 /* Values in dB units */
1106 s16 txp_cck_ofdm_pwr_delta;
1107 s16 txp_cck_ofdm_gainf_delta; 1119 s16 txp_cck_ofdm_gainf_delta;
1120 /* Value in dB units */
1121 s16 txp_cck_ofdm_pwr_delta;
1108 } ah_txpower; 1122 } ah_txpower;
1109 1123
1110 struct { 1124 struct {
@@ -1264,14 +1278,21 @@ extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *chann
1264/* PHY calibration */ 1278/* PHY calibration */
1265extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel); 1279extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel);
1266extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq); 1280extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq);
1281/* Spur mitigation */
1282bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
1283 struct ieee80211_channel *channel);
1284void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
1285 struct ieee80211_channel *channel);
1267/* Misc PHY functions */ 1286/* Misc PHY functions */
1268extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan); 1287extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
1269extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant);
1270extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
1271extern int ath5k_hw_phy_disable(struct ath5k_hw *ah); 1288extern int ath5k_hw_phy_disable(struct ath5k_hw *ah);
1289/* Antenna control */
1290extern void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode);
1291extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant);
1292extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
1272/* TX power setup */ 1293/* TX power setup */
1273extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower); 1294extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower);
1274extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 ee_mode, u8 txpower); 1295extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
1275 1296
1276/* 1297/*
1277 * Functions used internaly 1298 * Functions used internaly
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index 70d376c63aac..c41ef58393e7 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -133,7 +133,6 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
133 ah->ah_cw_min = AR5K_TUNE_CWMIN; 133 ah->ah_cw_min = AR5K_TUNE_CWMIN;
134 ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; 134 ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
135 ah->ah_software_retry = false; 135 ah->ah_software_retry = false;
136 ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
137 136
138 /* 137 /*
139 * Set the mac version based on the pci id 138 * Set the mac version based on the pci id
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index c8c658bfcf9d..6789c5dfcc76 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -227,9 +227,6 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
227static void ath5k_remove_interface(struct ieee80211_hw *hw, 227static void ath5k_remove_interface(struct ieee80211_hw *hw,
228 struct ieee80211_if_init_conf *conf); 228 struct ieee80211_if_init_conf *conf);
229static int ath5k_config(struct ieee80211_hw *hw, u32 changed); 229static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
230static int ath5k_config_interface(struct ieee80211_hw *hw,
231 struct ieee80211_vif *vif,
232 struct ieee80211_if_conf *conf);
233static void ath5k_configure_filter(struct ieee80211_hw *hw, 230static void ath5k_configure_filter(struct ieee80211_hw *hw,
234 unsigned int changed_flags, 231 unsigned int changed_flags,
235 unsigned int *new_flags, 232 unsigned int *new_flags,
@@ -259,7 +256,6 @@ static const struct ieee80211_ops ath5k_hw_ops = {
259 .add_interface = ath5k_add_interface, 256 .add_interface = ath5k_add_interface,
260 .remove_interface = ath5k_remove_interface, 257 .remove_interface = ath5k_remove_interface,
261 .config = ath5k_config, 258 .config = ath5k_config,
262 .config_interface = ath5k_config_interface,
263 .configure_filter = ath5k_configure_filter, 259 .configure_filter = ath5k_configure_filter,
264 .set_key = ath5k_set_key, 260 .set_key = ath5k_set_key,
265 .get_stats = ath5k_get_stats, 261 .get_stats = ath5k_get_stats,
@@ -520,6 +516,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
520 IEEE80211_HW_NOISE_DBM; 516 IEEE80211_HW_NOISE_DBM;
521 517
522 hw->wiphy->interface_modes = 518 hw->wiphy->interface_modes =
519 BIT(NL80211_IFTYPE_AP) |
523 BIT(NL80211_IFTYPE_STATION) | 520 BIT(NL80211_IFTYPE_STATION) |
524 BIT(NL80211_IFTYPE_ADHOC) | 521 BIT(NL80211_IFTYPE_ADHOC) |
525 BIT(NL80211_IFTYPE_MESH_POINT); 522 BIT(NL80211_IFTYPE_MESH_POINT);
@@ -1282,7 +1279,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
1282 ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, 1279 ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
1283 (sc->power_level * 2), 1280 (sc->power_level * 2),
1284 hw_rate, 1281 hw_rate,
1285 info->control.rates[0].count, keyidx, 0, flags, 1282 info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags,
1286 cts_rate, duration); 1283 cts_rate, duration);
1287 if (ret) 1284 if (ret)
1288 goto err_unmap; 1285 goto err_unmap;
@@ -1742,35 +1739,6 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
1742 } 1739 }
1743} 1740}
1744 1741
1745static void ath5k_tasklet_beacon(unsigned long data)
1746{
1747 struct ath5k_softc *sc = (struct ath5k_softc *) data;
1748
1749 /*
1750 * Software beacon alert--time to send a beacon.
1751 *
1752 * In IBSS mode we use this interrupt just to
1753 * keep track of the next TBTT (target beacon
1754 * transmission time) in order to detect wether
1755 * automatic TSF updates happened.
1756 */
1757 if (sc->opmode == NL80211_IFTYPE_ADHOC) {
1758 /* XXX: only if VEOL suppported */
1759 u64 tsf = ath5k_hw_get_tsf64(sc->ah);
1760 sc->nexttbtt += sc->bintval;
1761 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
1762 "SWBA nexttbtt: %x hw_tu: %x "
1763 "TSF: %llx\n",
1764 sc->nexttbtt,
1765 TSF_TO_TU(tsf),
1766 (unsigned long long) tsf);
1767 } else {
1768 spin_lock(&sc->block);
1769 ath5k_beacon_send(sc);
1770 spin_unlock(&sc->block);
1771 }
1772}
1773
1774static void 1742static void
1775ath5k_tasklet_rx(unsigned long data) 1743ath5k_tasklet_rx(unsigned long data)
1776{ 1744{
@@ -2041,7 +2009,8 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
2041 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2009 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2042 struct ath5k_hw *ah = sc->ah; 2010 struct ath5k_hw *ah = sc->ah;
2043 struct ath5k_desc *ds; 2011 struct ath5k_desc *ds;
2044 int ret, antenna = 0; 2012 int ret = 0;
2013 u8 antenna;
2045 u32 flags; 2014 u32 flags;
2046 2015
2047 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, 2016 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
@@ -2055,23 +2024,35 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
2055 } 2024 }
2056 2025
2057 ds = bf->desc; 2026 ds = bf->desc;
2027 antenna = ah->ah_tx_ant;
2058 2028
2059 flags = AR5K_TXDESC_NOACK; 2029 flags = AR5K_TXDESC_NOACK;
2060 if (sc->opmode == NL80211_IFTYPE_ADHOC && ath5k_hw_hasveol(ah)) { 2030 if (sc->opmode == NL80211_IFTYPE_ADHOC && ath5k_hw_hasveol(ah)) {
2061 ds->ds_link = bf->daddr; /* self-linked */ 2031 ds->ds_link = bf->daddr; /* self-linked */
2062 flags |= AR5K_TXDESC_VEOL; 2032 flags |= AR5K_TXDESC_VEOL;
2063 /* 2033 } else
2064 * Let hardware handle antenna switching if txantenna is not set
2065 */
2066 } else {
2067 ds->ds_link = 0; 2034 ds->ds_link = 0;
2068 /* 2035
2069 * Switch antenna every 4 beacons if txantenna is not set 2036 /*
2070 * XXX assumes two antennas 2037 * If we use multiple antennas on AP and use
2071 */ 2038 * the Sectored AP scenario, switch antenna every
2072 if (antenna == 0) 2039 * 4 beacons to make sure everybody hears our AP.
2073 antenna = sc->bsent & 4 ? 2 : 1; 2040 * When a client tries to associate, hw will keep
2074 } 2041 * track of the tx antenna to be used for this client
2042 * automaticaly, based on ACKed packets.
2043 *
2044 * Note: AP still listens and transmits RTS on the
2045 * default antenna which is supposed to be an omni.
2046 *
2047 * Note2: On sectored scenarios it's possible to have
2048 * multiple antennas (1omni -the default- and 14 sectors)
2049 * so if we choose to actually support this mode we need
2050 * to allow user to set how many antennas we have and tweak
2051 * the code below to send beacons on all of them.
2052 */
2053 if (ah->ah_ant_mode == AR5K_ANTMODE_SECTOR_AP)
2054 antenna = sc->bsent & 4 ? 2 : 1;
2055
2075 2056
2076 /* FIXME: If we are in g mode and rate is a CCK rate 2057 /* FIXME: If we are in g mode and rate is a CCK rate
2077 * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta 2058 * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
@@ -2124,7 +2105,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
2124 sc->bmisscount++; 2105 sc->bmisscount++;
2125 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, 2106 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
2126 "missed %u consecutive beacons\n", sc->bmisscount); 2107 "missed %u consecutive beacons\n", sc->bmisscount);
2127 if (sc->bmisscount > 3) { /* NB: 3 is a guess */ 2108 if (sc->bmisscount > 10) { /* NB: 10 is a guess */
2128 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, 2109 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
2129 "stuck beacon time (%u missed)\n", 2110 "stuck beacon time (%u missed)\n",
2130 sc->bmisscount); 2111 sc->bmisscount);
@@ -2145,10 +2126,12 @@ ath5k_beacon_send(struct ath5k_softc *sc)
2145 * are still pending on the queue. 2126 * are still pending on the queue.
2146 */ 2127 */
2147 if (unlikely(ath5k_hw_stop_tx_dma(ah, sc->bhalq))) { 2128 if (unlikely(ath5k_hw_stop_tx_dma(ah, sc->bhalq))) {
2148 ATH5K_WARN(sc, "beacon queue %u didn't stop?\n", sc->bhalq); 2129 ATH5K_WARN(sc, "beacon queue %u didn't start/stop ?\n", sc->bhalq);
2149 /* NB: hw still stops DMA, so proceed */ 2130 /* NB: hw still stops DMA, so proceed */
2150 } 2131 }
2151 2132
2133 /* Note: Beacon buffer is updated on beacon_update when mac80211
2134 * calls config_interface */
2152 ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); 2135 ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
2153 ath5k_hw_start_tx_dma(ah, sc->bhalq); 2136 ath5k_hw_start_tx_dma(ah, sc->bhalq);
2154 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", 2137 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
@@ -2305,6 +2288,35 @@ ath5k_beacon_config(struct ath5k_softc *sc)
2305 ath5k_hw_set_imr(ah, sc->imask); 2288 ath5k_hw_set_imr(ah, sc->imask);
2306} 2289}
2307 2290
2291static void ath5k_tasklet_beacon(unsigned long data)
2292{
2293 struct ath5k_softc *sc = (struct ath5k_softc *) data;
2294
2295 /*
2296 * Software beacon alert--time to send a beacon.
2297 *
2298 * In IBSS mode we use this interrupt just to
2299 * keep track of the next TBTT (target beacon
2300 * transmission time) in order to detect wether
2301 * automatic TSF updates happened.
2302 */
2303 if (sc->opmode == NL80211_IFTYPE_ADHOC) {
2304 /* XXX: only if VEOL suppported */
2305 u64 tsf = ath5k_hw_get_tsf64(sc->ah);
2306 sc->nexttbtt += sc->bintval;
2307 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
2308 "SWBA nexttbtt: %x hw_tu: %x "
2309 "TSF: %llx\n",
2310 sc->nexttbtt,
2311 TSF_TO_TU(tsf),
2312 (unsigned long long) tsf);
2313 } else {
2314 spin_lock(&sc->block);
2315 ath5k_beacon_send(sc);
2316 spin_unlock(&sc->block);
2317 }
2318}
2319
2308 2320
2309/********************\ 2321/********************\
2310* Interrupt handling * 2322* Interrupt handling *
@@ -2509,7 +2521,7 @@ ath5k_intr(int irq, void *dev_id)
2509 ath5k_hw_update_mib_counters(ah, &sc->ll_stats); 2521 ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
2510 } 2522 }
2511 } 2523 }
2512 } while (ath5k_hw_is_intr_pending(ah) && counter-- > 0); 2524 } while (ath5k_hw_is_intr_pending(ah) && --counter > 0);
2513 2525
2514 if (unlikely(!counter)) 2526 if (unlikely(!counter))
2515 ATH5K_WARN(sc, "too many interrupts, giving up for now\n"); 2527 ATH5K_WARN(sc, "too many interrupts, giving up for now\n");
@@ -2751,56 +2763,47 @@ static int
2751ath5k_config(struct ieee80211_hw *hw, u32 changed) 2763ath5k_config(struct ieee80211_hw *hw, u32 changed)
2752{ 2764{
2753 struct ath5k_softc *sc = hw->priv; 2765 struct ath5k_softc *sc = hw->priv;
2766 struct ath5k_hw *ah = sc->ah;
2754 struct ieee80211_conf *conf = &hw->conf; 2767 struct ieee80211_conf *conf = &hw->conf;
2755 int ret; 2768 int ret = 0;
2756 2769
2757 mutex_lock(&sc->lock); 2770 mutex_lock(&sc->lock);
2758 2771
2759 sc->bintval = conf->beacon_int; 2772 sc->bintval = conf->beacon_int;
2760 sc->power_level = conf->power_level;
2761 2773
2762 ret = ath5k_chan_set(sc, conf->channel); 2774 ret = ath5k_chan_set(sc, conf->channel);
2775 if (ret < 0)
2776 return ret;
2763 2777
2764 mutex_unlock(&sc->lock); 2778 if ((changed & IEEE80211_CONF_CHANGE_POWER) &&
2765 return ret; 2779 (sc->power_level != conf->power_level)) {
2766} 2780 sc->power_level = conf->power_level;
2767
2768static int
2769ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2770 struct ieee80211_if_conf *conf)
2771{
2772 struct ath5k_softc *sc = hw->priv;
2773 struct ath5k_hw *ah = sc->ah;
2774 int ret = 0;
2775 2781
2776 mutex_lock(&sc->lock); 2782 /* Half dB steps */
2777 if (sc->vif != vif) { 2783 ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2));
2778 ret = -EIO;
2779 goto unlock;
2780 }
2781 if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) {
2782 /* Cache for later use during resets */
2783 memcpy(ah->ah_bssid, conf->bssid, ETH_ALEN);
2784 /* XXX: assoc id is set to 0 for now, mac80211 doesn't have
2785 * a clean way of letting us retrieve this yet. */
2786 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
2787 mmiowb();
2788 }
2789 if (conf->changed & IEEE80211_IFCC_BEACON &&
2790 (vif->type == NL80211_IFTYPE_ADHOC ||
2791 vif->type == NL80211_IFTYPE_MESH_POINT ||
2792 vif->type == NL80211_IFTYPE_AP)) {
2793 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
2794 if (!beacon) {
2795 ret = -ENOMEM;
2796 goto unlock;
2797 }
2798 ath5k_beacon_update(sc, beacon);
2799 } 2784 }
2800 2785
2801unlock: 2786 /* TODO:
2787 * 1) Move this on config_interface and handle each case
2788 * separately eg. when we have only one STA vif, use
2789 * AR5K_ANTMODE_SINGLE_AP
2790 *
2791 * 2) Allow the user to change antenna mode eg. when only
2792 * one antenna is present
2793 *
2794 * 3) Allow the user to set default/tx antenna when possible
2795 *
2796 * 4) Default mode should handle 90% of the cases, together
2797 * with fixed a/b and single AP modes we should be able to
2798 * handle 99%. Sectored modes are extreme cases and i still
2799 * haven't found a usage for them. If we decide to support them,
2800 * then we must allow the user to set how many tx antennas we
2801 * have available
2802 */
2803 ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT);
2804
2802 mutex_unlock(&sc->lock); 2805 mutex_unlock(&sc->lock);
2803 return ret; 2806 return 0;
2804} 2807}
2805 2808
2806#define SUPPORTED_FIF_FLAGS \ 2809#define SUPPORTED_FIF_FLAGS \
@@ -3083,11 +3086,40 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
3083 u32 changes) 3086 u32 changes)
3084{ 3087{
3085 struct ath5k_softc *sc = hw->priv; 3088 struct ath5k_softc *sc = hw->priv;
3089 struct ath5k_hw *ah = sc->ah;
3090
3091 mutex_lock(&sc->lock);
3092 if (WARN_ON(sc->vif != vif))
3093 goto unlock;
3094
3095 if (changes & BSS_CHANGED_BSSID) {
3096 /* Cache for later use during resets */
3097 memcpy(ah->ah_bssid, bss_conf->bssid, ETH_ALEN);
3098 /* XXX: assoc id is set to 0 for now, mac80211 doesn't have
3099 * a clean way of letting us retrieve this yet. */
3100 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
3101 mmiowb();
3102 }
3103
3104 if (changes & BSS_CHANGED_BEACON_INT)
3105 sc->bintval = bss_conf->beacon_int;
3106
3086 if (changes & BSS_CHANGED_ASSOC) { 3107 if (changes & BSS_CHANGED_ASSOC) {
3087 mutex_lock(&sc->lock);
3088 sc->assoc = bss_conf->assoc; 3108 sc->assoc = bss_conf->assoc;
3089 if (sc->opmode == NL80211_IFTYPE_STATION) 3109 if (sc->opmode == NL80211_IFTYPE_STATION)
3090 set_beacon_filter(hw, sc->assoc); 3110 set_beacon_filter(hw, sc->assoc);
3091 mutex_unlock(&sc->lock);
3092 } 3111 }
3112
3113 if (changes & BSS_CHANGED_BEACON &&
3114 (vif->type == NL80211_IFTYPE_ADHOC ||
3115 vif->type == NL80211_IFTYPE_MESH_POINT ||
3116 vif->type == NL80211_IFTYPE_AP)) {
3117 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
3118
3119 if (beacon)
3120 ath5k_beacon_update(sc, beacon);
3121 }
3122
3123 unlock:
3124 mutex_unlock(&sc->lock);
3093} 3125}
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index c0fb3b09ba45..c56b494d417a 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -156,6 +156,17 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
156 ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7; 156 ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
157 } 157 }
158 158
159 AR5K_EEPROM_READ(AR5K_EEPROM_IS_HB63, val);
160
161 if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && val)
162 ee->ee_is_hb63 = true;
163 else
164 ee->ee_is_hb63 = false;
165
166 AR5K_EEPROM_READ(AR5K_EEPROM_RFKILL, val);
167 ee->ee_rfkill_pin = (u8) AR5K_REG_MS(val, AR5K_EEPROM_RFKILL_GPIO_SEL);
168 ee->ee_rfkill_pol = val & AR5K_EEPROM_RFKILL_POLARITY ? true : false;
169
159 return 0; 170 return 0;
160} 171}
161 172
@@ -197,16 +208,16 @@ static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
197 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f; 208 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
198 ee->ee_ant_control[mode][i++] = val & 0x3f; 209 ee->ee_ant_control[mode][i++] = val & 0x3f;
199 210
200 /* Get antenna modes */ 211 /* Get antenna switch tables */
201 ah->ah_antenna[mode][0] = 212 ah->ah_ant_ctl[mode][AR5K_ANT_CTL] =
202 (ee->ee_ant_control[mode][0] << 4); 213 (ee->ee_ant_control[mode][0] << 4);
203 ah->ah_antenna[mode][AR5K_ANT_FIXED_A] = 214 ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_A] =
204 ee->ee_ant_control[mode][1] | 215 ee->ee_ant_control[mode][1] |
205 (ee->ee_ant_control[mode][2] << 6) | 216 (ee->ee_ant_control[mode][2] << 6) |
206 (ee->ee_ant_control[mode][3] << 12) | 217 (ee->ee_ant_control[mode][3] << 12) |
207 (ee->ee_ant_control[mode][4] << 18) | 218 (ee->ee_ant_control[mode][4] << 18) |
208 (ee->ee_ant_control[mode][5] << 24); 219 (ee->ee_ant_control[mode][5] << 24);
209 ah->ah_antenna[mode][AR5K_ANT_FIXED_B] = 220 ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_B] =
210 ee->ee_ant_control[mode][6] | 221 ee->ee_ant_control[mode][6] |
211 (ee->ee_ant_control[mode][7] << 6) | 222 (ee->ee_ant_control[mode][7] << 6) |
212 (ee->ee_ant_control[mode][8] << 12) | 223 (ee->ee_ant_control[mode][8] << 12) |
@@ -640,9 +651,9 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
640static inline void 651static inline void
641ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp) 652ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
642{ 653{
643 const static u16 intercepts3[] = 654 static const u16 intercepts3[] =
644 { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 }; 655 { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
645 const static u16 intercepts3_2[] = 656 static const u16 intercepts3_2[] =
646 { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 }; 657 { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
647 const u16 *ip; 658 const u16 *ip;
648 int i; 659 int i;
@@ -1694,9 +1705,40 @@ ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
1694 return 0; 1705 return 0;
1695} 1706}
1696 1707
1708static int
1709ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah)
1710{
1711 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1712 u32 offset;
1713 u16 val;
1714 int ret = 0, i;
1715
1716 offset = AR5K_EEPROM_CTL(ee->ee_version) +
1717 AR5K_EEPROM_N_CTLS(ee->ee_version);
1718
1719 if (ee->ee_version < AR5K_EEPROM_VERSION_5_3) {
1720 /* No spur info for 5GHz */
1721 ee->ee_spur_chans[0][0] = AR5K_EEPROM_NO_SPUR;
1722 /* 2 channels for 2GHz (2464/2420) */
1723 ee->ee_spur_chans[0][1] = AR5K_EEPROM_5413_SPUR_CHAN_1;
1724 ee->ee_spur_chans[1][1] = AR5K_EEPROM_5413_SPUR_CHAN_2;
1725 ee->ee_spur_chans[2][1] = AR5K_EEPROM_NO_SPUR;
1726 } else if (ee->ee_version >= AR5K_EEPROM_VERSION_5_3) {
1727 for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) {
1728 AR5K_EEPROM_READ(offset, val);
1729 ee->ee_spur_chans[i][0] = val;
1730 AR5K_EEPROM_READ(offset + AR5K_EEPROM_N_SPUR_CHANS,
1731 val);
1732 ee->ee_spur_chans[i][1] = val;
1733 offset++;
1734 }
1735 }
1736
1737 return ret;
1738}
1697 1739
1698/* 1740/*
1699 * Initialize eeprom power tables 1741 * Initialize eeprom data structure
1700 */ 1742 */
1701int 1743int
1702ath5k_eeprom_init(struct ath5k_hw *ah) 1744ath5k_eeprom_init(struct ath5k_hw *ah)
@@ -1719,6 +1761,10 @@ ath5k_eeprom_init(struct ath5k_hw *ah)
1719 if (err < 0) 1761 if (err < 0)
1720 return err; 1762 return err;
1721 1763
1764 err = ath5k_eeprom_read_spur_chans(ah);
1765 if (err < 0)
1766 return err;
1767
1722 return 0; 1768 return 0;
1723} 1769}
1724 1770
@@ -1754,16 +1800,3 @@ int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
1754 1800
1755 return 0; 1801 return 0;
1756} 1802}
1757
1758bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah)
1759{
1760 u16 data;
1761
1762 ath5k_hw_eeprom_read(ah, AR5K_EEPROM_IS_HB63, &data);
1763
1764 if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && data)
1765 return true;
1766 else
1767 return false;
1768}
1769
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h
index b0c0606dea0b..64be73a5edae 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.h
+++ b/drivers/net/wireless/ath/ath5k/eeprom.h
@@ -26,6 +26,13 @@
26#define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */ 26#define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */
27 27
28#define AR5K_EEPROM_IS_HB63 0x000b /* Talon detect */ 28#define AR5K_EEPROM_IS_HB63 0x000b /* Talon detect */
29
30#define AR5K_EEPROM_RFKILL 0x0f
31#define AR5K_EEPROM_RFKILL_GPIO_SEL 0x0000001c
32#define AR5K_EEPROM_RFKILL_GPIO_SEL_S 2
33#define AR5K_EEPROM_RFKILL_POLARITY 0x00000002
34#define AR5K_EEPROM_RFKILL_POLARITY_S 1
35
29#define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */ 36#define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */
30#define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */ 37#define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */
31#define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */ 38#define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */
@@ -66,11 +73,6 @@
66#define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */ 73#define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */
67#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz */ 74#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz */
68 75
69#define AR5K_EEPROM_RFKILL_GPIO_SEL 0x0000001c
70#define AR5K_EEPROM_RFKILL_GPIO_SEL_S 2
71#define AR5K_EEPROM_RFKILL_POLARITY 0x00000002
72#define AR5K_EEPROM_RFKILL_POLARITY_S 1
73
74/* Newer EEPROMs are using a different offset */ 76/* Newer EEPROMs are using a different offset */
75#define AR5K_EEPROM_OFF(_v, _v3_0, _v3_3) \ 77#define AR5K_EEPROM_OFF(_v, _v3_0, _v3_3) \
76 (((_v) >= AR5K_EEPROM_VERSION_3_3) ? _v3_3 : _v3_0) 78 (((_v) >= AR5K_EEPROM_VERSION_3_3) ? _v3_3 : _v3_0)
@@ -211,6 +213,23 @@
211#define AR5K_EEPROM_I_GAIN 10 213#define AR5K_EEPROM_I_GAIN 10
212#define AR5K_EEPROM_CCK_OFDM_DELTA 15 214#define AR5K_EEPROM_CCK_OFDM_DELTA 15
213#define AR5K_EEPROM_N_IQ_CAL 2 215#define AR5K_EEPROM_N_IQ_CAL 2
216/* 5GHz/2GHz */
217enum ath5k_eeprom_freq_bands{
218 AR5K_EEPROM_BAND_5GHZ = 0,
219 AR5K_EEPROM_BAND_2GHZ = 1,
220 AR5K_EEPROM_N_FREQ_BANDS,
221};
222/* Spur chans per freq band */
223#define AR5K_EEPROM_N_SPUR_CHANS 5
224/* fbin value for chan 2464 x2 */
225#define AR5K_EEPROM_5413_SPUR_CHAN_1 1640
226/* fbin value for chan 2420 x2 */
227#define AR5K_EEPROM_5413_SPUR_CHAN_2 1200
228#define AR5K_EEPROM_SPUR_CHAN_MASK 0x3FFF
229#define AR5K_EEPROM_NO_SPUR 0x8000
230#define AR5K_SPUR_CHAN_WIDTH 87
231#define AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz 3125
232#define AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz 6250
214 233
215#define AR5K_EEPROM_READ(_o, _v) do { \ 234#define AR5K_EEPROM_READ(_o, _v) do { \
216 ret = ath5k_hw_eeprom_read(ah, (_o), &(_v)); \ 235 ret = ath5k_hw_eeprom_read(ah, (_o), &(_v)); \
@@ -221,11 +240,11 @@
221#define AR5K_EEPROM_READ_HDR(_o, _v) \ 240#define AR5K_EEPROM_READ_HDR(_o, _v) \
222 AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v); \ 241 AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v); \
223 242
224enum ath5k_ant_setting { 243enum ath5k_ant_table {
225 AR5K_ANT_VARIABLE = 0, /* variable by programming */ 244 AR5K_ANT_CTL = 0, /* Idle switch table settings */
226 AR5K_ANT_FIXED_A = 1, /* fixed to 11a frequencies */ 245 AR5K_ANT_SWTABLE_A = 1, /* Switch table for antenna A */
227 AR5K_ANT_FIXED_B = 2, /* fixed to 11b frequencies */ 246 AR5K_ANT_SWTABLE_B = 2, /* Switch table for antenna B */
228 AR5K_ANT_MAX = 3, 247 AR5K_ANT_MAX,
229}; 248};
230 249
231enum ath5k_ctl_mode { 250enum ath5k_ctl_mode {
@@ -369,6 +388,9 @@ struct ath5k_eeprom_info {
369 u16 ee_version; 388 u16 ee_version;
370 u16 ee_header; 389 u16 ee_header;
371 u16 ee_ant_gain; 390 u16 ee_ant_gain;
391 u8 ee_rfkill_pin;
392 bool ee_rfkill_pol;
393 bool ee_is_hb63;
372 u16 ee_misc0; 394 u16 ee_misc0;
373 u16 ee_misc1; 395 u16 ee_misc1;
374 u16 ee_misc2; 396 u16 ee_misc2;
@@ -436,6 +458,10 @@ struct ath5k_eeprom_info {
436 s8 ee_pga_desired_size_turbo[AR5K_EEPROM_N_MODES]; 458 s8 ee_pga_desired_size_turbo[AR5K_EEPROM_N_MODES];
437 s8 ee_pd_gain_overlap; 459 s8 ee_pd_gain_overlap;
438 460
461 /* Spur mitigation data (fbin values for spur channels) */
462 u16 ee_spur_chans[AR5K_EEPROM_N_SPUR_CHANS][AR5K_EEPROM_N_FREQ_BANDS];
463
464 /* Antenna raw switch tables */
439 u32 ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; 465 u32 ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
440}; 466};
441 467
diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
index cbdc0b308429..876725f08b6c 100644
--- a/drivers/net/wireless/ath/ath5k/led.c
+++ b/drivers/net/wireless/ath/ath5k/led.c
@@ -53,8 +53,6 @@
53 53
54/* Devices we match on for LED config info (typically laptops) */ 54/* Devices we match on for LED config info (typically laptops) */
55static const struct pci_device_id ath5k_led_devices[] = { 55static const struct pci_device_id ath5k_led_devices[] = {
56 /* IBM-specific AR5212 */
57 { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) },
58 /* AR5211 */ 56 /* AR5211 */
59 { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5211), ATH_LED(0, 0) }, 57 { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5211), ATH_LED(0, 0) },
60 /* HP Compaq nc6xx, nc4000, nx6000 */ 58 /* HP Compaq nc6xx, nc4000, nx6000 */
@@ -69,6 +67,10 @@ static const struct pci_device_id ath5k_led_devices[] = {
69 { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0105), ATH_LED(3, 0) }, 67 { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0105), ATH_LED(3, 0) },
70 /* Fukato Datacask Jupiter 1014a (mrb74@gmx.at) */ 68 /* Fukato Datacask Jupiter 1014a (mrb74@gmx.at) */
71 { ATH_SDEVICE(PCI_VENDOR_ID_AZWAVE, 0x1026), ATH_LED(3, 0) }, 69 { ATH_SDEVICE(PCI_VENDOR_ID_AZWAVE, 0x1026), ATH_LED(3, 0) },
70 /* IBM ThinkPad AR5BXB6 (legovini@spiro.fisica.unipd.it) */
71 { ATH_SDEVICE(PCI_VENDOR_ID_IBM, 0x058a), ATH_LED(1, 0) },
72 /* IBM-specific AR5212 (all others) */
73 { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) },
72 { } 74 { }
73}; 75};
74 76
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 55122f1e1986..579aa0a96ab8 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -736,8 +736,8 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
736 /* When in AP mode zero timer0 to start TSF */ 736 /* When in AP mode zero timer0 to start TSF */
737 if (ah->ah_op_mode == NL80211_IFTYPE_AP) 737 if (ah->ah_op_mode == NL80211_IFTYPE_AP)
738 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0); 738 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
739 else 739
740 ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0); 740 ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
741 ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1); 741 ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1);
742 ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2); 742 ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2);
743 ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3); 743 ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3);
@@ -1003,7 +1003,7 @@ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
1003 * Note2: Windows driver (ndiswrapper) sets this to 1003 * Note2: Windows driver (ndiswrapper) sets this to
1004 * 0x00000714 instead of 0x00000007 1004 * 0x00000714 instead of 0x00000007
1005 */ 1005 */
1006 if (ah->ah_version > AR5K_AR5211) { 1006 if (ah->ah_version >= AR5K_AR5211) {
1007 ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL, 1007 ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
1008 AR5K_KEYTABLE_TYPE(entry)); 1008 AR5K_KEYTABLE_TYPE(entry));
1009 1009
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
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index 5094c394a4b2..73407b3f53ef 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -160,7 +160,8 @@ u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
160 if (ah->ah_version == AR5K_AR5210) 160 if (ah->ah_version == AR5K_AR5210)
161 return false; 161 return false;
162 162
163 pending = (AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT); 163 pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue));
164 pending &= AR5K_QCU_STS_FRMPENDCNT;
164 165
165 /* It's possible to have no frames pending even if TXE 166 /* It's possible to have no frames pending even if TXE
166 * is set. To indicate that q has not stopped return 167 * is set. To indicate that q has not stopped return
@@ -401,14 +402,16 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
401 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), 402 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
402 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL << 403 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
403 AR5K_DCU_MISC_ARBLOCK_CTL_S) | 404 AR5K_DCU_MISC_ARBLOCK_CTL_S) |
405 AR5K_DCU_MISC_ARBLOCK_IGNORE |
404 AR5K_DCU_MISC_POST_FR_BKOFF_DIS | 406 AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
405 AR5K_DCU_MISC_BCN_ENABLE); 407 AR5K_DCU_MISC_BCN_ENABLE);
406 break; 408 break;
407 409
408 case AR5K_TX_QUEUE_CAB: 410 case AR5K_TX_QUEUE_CAB:
409 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), 411 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
410 AR5K_QCU_MISC_FRSHED_DBA_GT | 412 AR5K_QCU_MISC_FRSHED_BCN_SENT_GT |
411 AR5K_QCU_MISC_CBREXP_DIS | 413 AR5K_QCU_MISC_CBREXP_DIS |
414 AR5K_QCU_MISC_RDY_VEOL_POLICY |
412 AR5K_QCU_MISC_CBREXP_BCN_DIS); 415 AR5K_QCU_MISC_CBREXP_BCN_DIS);
413 416
414 ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL - 417 ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
index 7070d1543cdc..6809b54a2ad7 100644
--- a/drivers/net/wireless/ath/ath5k/reg.h
+++ b/drivers/net/wireless/ath/ath5k/reg.h
@@ -1148,6 +1148,11 @@
1148#define AR5K_STA_ID1_CBCIV_ENDIAN 0x40000000 /* ??? */ 1148#define AR5K_STA_ID1_CBCIV_ENDIAN 0x40000000 /* ??? */
1149#define AR5K_STA_ID1_KEYSRCH_MCAST 0x80000000 /* Do key cache search for mcast frames */ 1149#define AR5K_STA_ID1_KEYSRCH_MCAST 0x80000000 /* Do key cache search for mcast frames */
1150 1150
1151#define AR5K_STA_ID1_ANTENNA_SETTINGS (AR5K_STA_ID1_DEFAULT_ANTENNA | \
1152 AR5K_STA_ID1_DESC_ANTENNA | \
1153 AR5K_STA_ID1_RTS_DEF_ANTENNA | \
1154 AR5K_STA_ID1_SELFGEN_DEF_ANT)
1155
1151/* 1156/*
1152 * First BSSID register (MAC address, lower 32bits) 1157 * First BSSID register (MAC address, lower 32bits)
1153 */ 1158 */
@@ -2028,7 +2033,9 @@
2028#define AR5K_PHY_AGCCTL 0x9860 /* Register address */ 2033#define AR5K_PHY_AGCCTL 0x9860 /* Register address */
2029#define AR5K_PHY_AGCCTL_CAL 0x00000001 /* Enable PHY calibration */ 2034#define AR5K_PHY_AGCCTL_CAL 0x00000001 /* Enable PHY calibration */
2030#define AR5K_PHY_AGCCTL_NF 0x00000002 /* Enable Noise Floor calibration */ 2035#define AR5K_PHY_AGCCTL_NF 0x00000002 /* Enable Noise Floor calibration */
2036#define AR5K_PHY_AGCCTL_OFDM_DIV_DIS 0x00000008 /* Disable antenna diversity on OFDM modes */
2031#define AR5K_PHY_AGCCTL_NF_EN 0x00008000 /* Enable nf calibration to happen (?) */ 2037#define AR5K_PHY_AGCCTL_NF_EN 0x00008000 /* Enable nf calibration to happen (?) */
2038#define AR5K_PHY_AGCTL_FLTR_CAL 0x00010000 /* Allow filter calibration (?) */
2032#define AR5K_PHY_AGCCTL_NF_NOUPDATE 0x00020000 /* Don't update nf automaticaly */ 2039#define AR5K_PHY_AGCCTL_NF_NOUPDATE 0x00020000 /* Don't update nf automaticaly */
2033 2040
2034/* 2041/*
@@ -2528,7 +2535,7 @@
2528 * PHY CCK Cross-correlator Barker RSSI threshold register [5212+] 2535 * PHY CCK Cross-correlator Barker RSSI threshold register [5212+]
2529 */ 2536 */
2530#define AR5K_PHY_CCK_CROSSCORR 0xa208 2537#define AR5K_PHY_CCK_CROSSCORR 0xa208
2531#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR 0x0000000f 2538#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR 0x0000003f
2532#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR_S 0 2539#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR_S 0
2533 2540
2534/* Same address is used for antenna diversity activation */ 2541/* Same address is used for antenna diversity activation */
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 775fdf78554b..c1862f8a2e7b 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -507,7 +507,7 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
507 507
508 if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)) 508 if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
509 scal = AR5K_PHY_SCAL_32MHZ_2417; 509 scal = AR5K_PHY_SCAL_32MHZ_2417;
510 else if (ath5k_eeprom_is_hb63(ah)) 510 else if (ee->ee_is_hb63)
511 scal = AR5K_PHY_SCAL_32MHZ_HB63; 511 scal = AR5K_PHY_SCAL_32MHZ_HB63;
512 else 512 else
513 scal = AR5K_PHY_SCAL_32MHZ; 513 scal = AR5K_PHY_SCAL_32MHZ;
@@ -536,26 +536,6 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
536 return; 536 return;
537} 537}
538 538
539static bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
540 struct ieee80211_channel *channel)
541{
542 u8 refclk_freq;
543
544 if ((ah->ah_radio == AR5K_RF5112) ||
545 (ah->ah_radio == AR5K_RF5413) ||
546 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
547 refclk_freq = 40;
548 else
549 refclk_freq = 32;
550
551 if ((channel->center_freq % refclk_freq != 0) &&
552 ((channel->center_freq % refclk_freq < 10) ||
553 (channel->center_freq % refclk_freq > 22)))
554 return true;
555 else
556 return false;
557}
558
559/* TODO: Half/Quarter rate */ 539/* TODO: Half/Quarter rate */
560static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah, 540static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
561 struct ieee80211_channel *channel) 541 struct ieee80211_channel *channel)
@@ -598,9 +578,10 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
598 /* Set DAC/ADC delays */ 578 /* Set DAC/ADC delays */
599 if (ah->ah_version == AR5K_AR5212) { 579 if (ah->ah_version == AR5K_AR5212) {
600 u32 scal; 580 u32 scal;
581 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
601 if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)) 582 if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
602 scal = AR5K_PHY_SCAL_32MHZ_2417; 583 scal = AR5K_PHY_SCAL_32MHZ_2417;
603 else if (ath5k_eeprom_is_hb63(ah)) 584 else if (ee->ee_is_hb63)
604 scal = AR5K_PHY_SCAL_32MHZ_HB63; 585 scal = AR5K_PHY_SCAL_32MHZ_HB63;
605 else 586 else
606 scal = AR5K_PHY_SCAL_32MHZ; 587 scal = AR5K_PHY_SCAL_32MHZ;
@@ -697,13 +678,13 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
697 /* Set antenna idle switch table */ 678 /* Set antenna idle switch table */
698 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL, 679 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL,
699 AR5K_PHY_ANT_CTL_SWTABLE_IDLE, 680 AR5K_PHY_ANT_CTL_SWTABLE_IDLE,
700 (ah->ah_antenna[ee_mode][0] | 681 (ah->ah_ant_ctl[ee_mode][0] |
701 AR5K_PHY_ANT_CTL_TXRX_EN)); 682 AR5K_PHY_ANT_CTL_TXRX_EN));
702 683
703 /* Set antenna switch table */ 684 /* Set antenna switch tables */
704 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]], 685 ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant[0]],
705 AR5K_PHY_ANT_SWITCH_TABLE_0); 686 AR5K_PHY_ANT_SWITCH_TABLE_0);
706 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]], 687 ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant[1]],
707 AR5K_PHY_ANT_SWITCH_TABLE_1); 688 AR5K_PHY_ANT_SWITCH_TABLE_1);
708 689
709 /* Noise floor threshold */ 690 /* Noise floor threshold */
@@ -997,10 +978,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
997 ath5k_hw_tweak_initval_settings(ah, channel); 978 ath5k_hw_tweak_initval_settings(ah, channel);
998 979
999 /* 980 /*
1000 * Set TX power (FIXME) 981 * Set TX power
1001 */ 982 */
1002 ret = ath5k_hw_txpower(ah, channel, ee_mode, 983 ret = ath5k_hw_txpower(ah, channel, ee_mode,
1003 AR5K_TUNE_DEFAULT_TXPOWER); 984 ah->ah_txpower.txp_max_pwr / 2);
1004 if (ret) 985 if (ret)
1005 return ret; 986 return ret;
1006 987
@@ -1023,9 +1004,22 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1023 /* Write OFDM timings on 5212*/ 1004 /* Write OFDM timings on 5212*/
1024 if (ah->ah_version == AR5K_AR5212 && 1005 if (ah->ah_version == AR5K_AR5212 &&
1025 channel->hw_value & CHANNEL_OFDM) { 1006 channel->hw_value & CHANNEL_OFDM) {
1007 struct ath5k_eeprom_info *ee =
1008 &ah->ah_capabilities.cap_eeprom;
1009
1026 ret = ath5k_hw_write_ofdm_timings(ah, channel); 1010 ret = ath5k_hw_write_ofdm_timings(ah, channel);
1027 if (ret) 1011 if (ret)
1028 return ret; 1012 return ret;
1013
1014 /* Note: According to docs we can have a newer
1015 * EEPROM on old hardware, so we need to verify
1016 * that our hardware is new enough to have spur
1017 * mitigation registers (delta phase etc) */
1018 if (ah->ah_mac_srev >= AR5K_SREV_AR5424 ||
1019 (ah->ah_mac_srev >= AR5K_SREV_AR5424 &&
1020 ee->ee_version >= AR5K_EEPROM_VERSION_5_3))
1021 ath5k_hw_set_spur_mitigation_filter(ah,
1022 channel);
1029 } 1023 }
1030 1024
1031 /*Enable/disable 802.11b mode on 5111 1025 /*Enable/disable 802.11b mode on 5111
@@ -1041,17 +1035,15 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1041 1035
1042 /* 1036 /*
1043 * In case a fixed antenna was set as default 1037 * In case a fixed antenna was set as default
1044 * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE 1038 * use the same switch table twice.
1045 * registers.
1046 */ 1039 */
1047 if (s_ant != 0) { 1040 if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_A)
1048 if (s_ant == AR5K_ANT_FIXED_A) /* 1 - Main */ 1041 ant[0] = ant[1] = AR5K_ANT_SWTABLE_A;
1049 ant[0] = ant[1] = AR5K_ANT_FIXED_A; 1042 else if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_B)
1050 else /* 2 - Aux */ 1043 ant[0] = ant[1] = AR5K_ANT_SWTABLE_B;
1051 ant[0] = ant[1] = AR5K_ANT_FIXED_B; 1044 else {
1052 } else { 1045 ant[0] = AR5K_ANT_SWTABLE_A;
1053 ant[0] = AR5K_ANT_FIXED_A; 1046 ant[1] = AR5K_ANT_SWTABLE_B;
1054 ant[1] = AR5K_ANT_FIXED_B;
1055 } 1047 }
1056 1048
1057 /* Commit values from EEPROM */ 1049 /* Commit values from EEPROM */
@@ -1259,6 +1251,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1259 */ 1251 */
1260 ath5k_hw_noise_floor_calibration(ah, channel->center_freq); 1252 ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
1261 1253
1254 /* Restore antenna mode */
1255 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
1262 1256
1263 /* 1257 /*
1264 * Configure QCUs/DCUs 1258 * Configure QCUs/DCUs