diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath5k')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/ath5k.h | 37 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/attach.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.c | 210 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/eeprom.c | 73 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/eeprom.h | 46 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/led.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/pcu.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/phy.c | 493 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/qcu.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/reg.h | 9 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/reset.c | 70 |
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 | ||
422 | enum 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 */ |
1265 | extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel); | 1279 | extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel); |
1266 | extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq); | 1280 | extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq); |
1281 | /* Spur mitigation */ | ||
1282 | bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, | ||
1283 | struct ieee80211_channel *channel); | ||
1284 | void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, | ||
1285 | struct ieee80211_channel *channel); | ||
1267 | /* Misc PHY functions */ | 1286 | /* Misc PHY functions */ |
1268 | extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan); | 1287 | extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan); |
1269 | extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant); | ||
1270 | extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah); | ||
1271 | extern int ath5k_hw_phy_disable(struct ath5k_hw *ah); | 1288 | extern int ath5k_hw_phy_disable(struct ath5k_hw *ah); |
1289 | /* Antenna control */ | ||
1290 | extern void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode); | ||
1291 | extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant); | ||
1292 | extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah); | ||
1272 | /* TX power setup */ | 1293 | /* TX power setup */ |
1273 | extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower); | 1294 | extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower); |
1274 | extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 ee_mode, u8 txpower); | 1295 | extern 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, | |||
227 | static void ath5k_remove_interface(struct ieee80211_hw *hw, | 227 | static void ath5k_remove_interface(struct ieee80211_hw *hw, |
228 | struct ieee80211_if_init_conf *conf); | 228 | struct ieee80211_if_init_conf *conf); |
229 | static int ath5k_config(struct ieee80211_hw *hw, u32 changed); | 229 | static int ath5k_config(struct ieee80211_hw *hw, u32 changed); |
230 | static int ath5k_config_interface(struct ieee80211_hw *hw, | ||
231 | struct ieee80211_vif *vif, | ||
232 | struct ieee80211_if_conf *conf); | ||
233 | static void ath5k_configure_filter(struct ieee80211_hw *hw, | 230 | static 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 | ||
1745 | static 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 | |||
1774 | static void | 1742 | static void |
1775 | ath5k_tasklet_rx(unsigned long data) | 1743 | ath5k_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 | ||
2291 | static 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 | |||
2751 | ath5k_config(struct ieee80211_hw *hw, u32 changed) | 2763 | ath5k_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 | |||
2768 | static int | ||
2769 | ath5k_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 | ||
2801 | unlock: | 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) | |||
640 | static inline void | 651 | static inline void |
641 | ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp) | 652 | ath5k_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 | ||
1708 | static int | ||
1709 | ath5k_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 | */ |
1701 | int | 1743 | int |
1702 | ath5k_eeprom_init(struct ath5k_hw *ah) | 1744 | ath5k_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 | |||
1758 | bool 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 */ | ||
217 | enum 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 | ||
224 | enum ath5k_ant_setting { | 243 | enum 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 | ||
231 | enum ath5k_ctl_mode { | 250 | enum 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) */ |
55 | static const struct pci_device_id ath5k_led_devices[] = { | 55 | static 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 | |||
1360 | bool 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 | |||
1380 | void | ||
1381 | ath5k_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 | |||
1359 | int ath5k_hw_phy_disable(struct ath5k_hw *ah) | 1607 | int 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 | |||
1420 | void /*TODO:Boundary check*/ | 1668 | void /*TODO:Boundary check*/ |
1421 | ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant) | 1669 | ath5k_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 | ||
1429 | unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah) | 1677 | unsigned 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 | */ | ||
1690 | static void | ||
1691 | ath5k_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 | */ | ||
1731 | void | ||
1732 | ath5k_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 | */ |
1756 | static void | 2162 | static void |
1757 | ath5k_get_max_ctl_power(struct ath5k_hw *ah, | 2163 | ath5k_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 | ||
2594 | int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 mode, u8 txpower) | 3008 | int 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 | ||
539 | static 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 */ |
560 | static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah, | 540 | static 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 |