aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/main.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c156
1 files changed, 139 insertions, 17 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index b8b76dd2c11e..c8de50fa6378 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -51,13 +51,11 @@ static void ath_cache_conf_rate(struct ath_softc *sc,
51static void ath_update_txpow(struct ath_softc *sc) 51static void ath_update_txpow(struct ath_softc *sc)
52{ 52{
53 struct ath_hw *ah = sc->sc_ah; 53 struct ath_hw *ah = sc->sc_ah;
54 u32 txpow;
55 54
56 if (sc->curtxpow != sc->config.txpowlimit) { 55 if (sc->curtxpow != sc->config.txpowlimit) {
57 ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit); 56 ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit);
58 /* read back in case value is clamped */ 57 /* read back in case value is clamped */
59 ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow); 58 sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
60 sc->curtxpow = txpow;
61 } 59 }
62} 60}
63 61
@@ -232,6 +230,113 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
232 return r; 230 return r;
233} 231}
234 232
233static void ath_paprd_activate(struct ath_softc *sc)
234{
235 struct ath_hw *ah = sc->sc_ah;
236 int chain;
237
238 if (!ah->curchan->paprd_done)
239 return;
240
241 ath9k_ps_wakeup(sc);
242 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
243 if (!(ah->caps.tx_chainmask & BIT(chain)))
244 continue;
245
246 ar9003_paprd_populate_single_table(ah, ah->curchan, chain);
247 }
248
249 ar9003_paprd_enable(ah, true);
250 ath9k_ps_restore(sc);
251}
252
253void ath_paprd_calibrate(struct work_struct *work)
254{
255 struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work);
256 struct ieee80211_hw *hw = sc->hw;
257 struct ath_hw *ah = sc->sc_ah;
258 struct ieee80211_hdr *hdr;
259 struct sk_buff *skb = NULL;
260 struct ieee80211_tx_info *tx_info;
261 int band = hw->conf.channel->band;
262 struct ieee80211_supported_band *sband = &sc->sbands[band];
263 struct ath_tx_control txctl;
264 int qnum, ftype;
265 int chain_ok = 0;
266 int chain;
267 int len = 1800;
268 int time_left;
269 int i;
270
271 ath9k_ps_wakeup(sc);
272 skb = alloc_skb(len, GFP_KERNEL);
273 if (!skb)
274 return;
275
276 tx_info = IEEE80211_SKB_CB(skb);
277
278 skb_put(skb, len);
279 memset(skb->data, 0, len);
280 hdr = (struct ieee80211_hdr *)skb->data;
281 ftype = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC;
282 hdr->frame_control = cpu_to_le16(ftype);
283 hdr->duration_id = 10;
284 memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN);
285 memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
286 memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
287
288 memset(&txctl, 0, sizeof(txctl));
289 qnum = sc->tx.hwq_map[WME_AC_BE];
290 txctl.txq = &sc->tx.txq[qnum];
291
292 ar9003_paprd_init_table(ah);
293 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
294 if (!(ah->caps.tx_chainmask & BIT(chain)))
295 continue;
296
297 chain_ok = 0;
298 memset(tx_info, 0, sizeof(*tx_info));
299 tx_info->band = band;
300
301 for (i = 0; i < 4; i++) {
302 tx_info->control.rates[i].idx = sband->n_bitrates - 1;
303 tx_info->control.rates[i].count = 6;
304 }
305
306 init_completion(&sc->paprd_complete);
307 ar9003_paprd_setup_gain_table(ah, chain);
308 txctl.paprd = BIT(chain);
309 if (ath_tx_start(hw, skb, &txctl) != 0)
310 break;
311
312 time_left = wait_for_completion_timeout(&sc->paprd_complete,
313 100);
314 if (!time_left) {
315 ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
316 "Timeout waiting for paprd training on "
317 "TX chain %d\n",
318 chain);
319 break;
320 }
321
322 if (!ar9003_paprd_is_done(ah))
323 break;
324
325 if (ar9003_paprd_create_curve(ah, ah->curchan, chain) != 0)
326 break;
327
328 chain_ok = 1;
329 }
330 kfree_skb(skb);
331
332 if (chain_ok) {
333 ah->curchan->paprd_done = true;
334 ath_paprd_activate(sc);
335 }
336
337 ath9k_ps_restore(sc);
338}
339
235/* 340/*
236 * This routine performs the periodic noise floor calibration function 341 * This routine performs the periodic noise floor calibration function
237 * that is used to adjust and optimize the chip performance. This 342 * that is used to adjust and optimize the chip performance. This
@@ -285,7 +390,8 @@ void ath_ani_calibrate(unsigned long data)
285 } 390 }
286 391
287 /* Verify whether we must check ANI */ 392 /* Verify whether we must check ANI */
288 if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) { 393 if ((timestamp - common->ani.checkani_timer) >=
394 ah->config.ani_poll_interval) {
289 aniflag = true; 395 aniflag = true;
290 common->ani.checkani_timer = timestamp; 396 common->ani.checkani_timer = timestamp;
291 } 397 }
@@ -326,15 +432,24 @@ set_timer:
326 */ 432 */
327 cal_interval = ATH_LONG_CALINTERVAL; 433 cal_interval = ATH_LONG_CALINTERVAL;
328 if (sc->sc_ah->config.enable_ani) 434 if (sc->sc_ah->config.enable_ani)
329 cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL); 435 cal_interval = min(cal_interval,
436 (u32)ah->config.ani_poll_interval);
330 if (!common->ani.caldone) 437 if (!common->ani.caldone)
331 cal_interval = min(cal_interval, (u32)short_cal_interval); 438 cal_interval = min(cal_interval, (u32)short_cal_interval);
332 439
333 mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); 440 mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
441 if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) &&
442 !(sc->sc_flags & SC_OP_SCANNING)) {
443 if (!sc->sc_ah->curchan->paprd_done)
444 ieee80211_queue_work(sc->hw, &sc->paprd_work);
445 else
446 ath_paprd_activate(sc);
447 }
334} 448}
335 449
336static void ath_start_ani(struct ath_common *common) 450static void ath_start_ani(struct ath_common *common)
337{ 451{
452 struct ath_hw *ah = common->ah;
338 unsigned long timestamp = jiffies_to_msecs(jiffies); 453 unsigned long timestamp = jiffies_to_msecs(jiffies);
339 454
340 common->ani.longcal_timer = timestamp; 455 common->ani.longcal_timer = timestamp;
@@ -342,7 +457,8 @@ static void ath_start_ani(struct ath_common *common)
342 common->ani.checkani_timer = timestamp; 457 common->ani.checkani_timer = timestamp;
343 458
344 mod_timer(&common->ani.timer, 459 mod_timer(&common->ani.timer,
345 jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); 460 jiffies +
461 msecs_to_jiffies((u32)ah->config.ani_poll_interval));
346} 462}
347 463
348/* 464/*
@@ -804,25 +920,25 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
804 return r; 920 return r;
805} 921}
806 922
807int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) 923static int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
808{ 924{
809 int qnum; 925 int qnum;
810 926
811 switch (queue) { 927 switch (queue) {
812 case 0: 928 case 0:
813 qnum = sc->tx.hwq_map[ATH9K_WME_AC_VO]; 929 qnum = sc->tx.hwq_map[WME_AC_VO];
814 break; 930 break;
815 case 1: 931 case 1:
816 qnum = sc->tx.hwq_map[ATH9K_WME_AC_VI]; 932 qnum = sc->tx.hwq_map[WME_AC_VI];
817 break; 933 break;
818 case 2: 934 case 2:
819 qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE]; 935 qnum = sc->tx.hwq_map[WME_AC_BE];
820 break; 936 break;
821 case 3: 937 case 3:
822 qnum = sc->tx.hwq_map[ATH9K_WME_AC_BK]; 938 qnum = sc->tx.hwq_map[WME_AC_BK];
823 break; 939 break;
824 default: 940 default:
825 qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE]; 941 qnum = sc->tx.hwq_map[WME_AC_BE];
826 break; 942 break;
827 } 943 }
828 944
@@ -834,16 +950,16 @@ int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc)
834 int qnum; 950 int qnum;
835 951
836 switch (queue) { 952 switch (queue) {
837 case ATH9K_WME_AC_VO: 953 case WME_AC_VO:
838 qnum = 0; 954 qnum = 0;
839 break; 955 break;
840 case ATH9K_WME_AC_VI: 956 case WME_AC_VI:
841 qnum = 1; 957 qnum = 1;
842 break; 958 break;
843 case ATH9K_WME_AC_BE: 959 case WME_AC_BE:
844 qnum = 2; 960 qnum = 2;
845 break; 961 break;
846 case ATH9K_WME_AC_BK: 962 case WME_AC_BK:
847 qnum = 3; 963 qnum = 3;
848 break; 964 break;
849 default: 965 default:
@@ -1127,6 +1243,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
1127 1243
1128 cancel_delayed_work_sync(&sc->ath_led_blink_work); 1244 cancel_delayed_work_sync(&sc->ath_led_blink_work);
1129 cancel_delayed_work_sync(&sc->tx_complete_work); 1245 cancel_delayed_work_sync(&sc->tx_complete_work);
1246 cancel_work_sync(&sc->paprd_work);
1130 1247
1131 if (!sc->num_sec_wiphy) { 1248 if (!sc->num_sec_wiphy) {
1132 cancel_delayed_work_sync(&sc->wiphy_work); 1249 cancel_delayed_work_sync(&sc->wiphy_work);
@@ -1555,7 +1672,7 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
1555 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n"); 1672 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
1556 1673
1557 if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) 1674 if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)
1558 if ((qnum == sc->tx.hwq_map[ATH9K_WME_AC_BE]) && !ret) 1675 if ((qnum == sc->tx.hwq_map[WME_AC_BE]) && !ret)
1559 ath_beaconq_config(sc); 1676 ath_beaconq_config(sc);
1560 1677
1561 mutex_unlock(&sc->mutex); 1678 mutex_unlock(&sc->mutex);
@@ -1769,6 +1886,8 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
1769 struct ath_softc *sc = aphy->sc; 1886 struct ath_softc *sc = aphy->sc;
1770 int ret = 0; 1887 int ret = 0;
1771 1888
1889 local_bh_disable();
1890
1772 switch (action) { 1891 switch (action) {
1773 case IEEE80211_AMPDU_RX_START: 1892 case IEEE80211_AMPDU_RX_START:
1774 if (!(sc->sc_flags & SC_OP_RXAGGR)) 1893 if (!(sc->sc_flags & SC_OP_RXAGGR))
@@ -1798,6 +1917,8 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
1798 "Unknown AMPDU action\n"); 1917 "Unknown AMPDU action\n");
1799 } 1918 }
1800 1919
1920 local_bh_enable();
1921
1801 return ret; 1922 return ret;
1802} 1923}
1803 1924
@@ -1842,6 +1963,7 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
1842 ath9k_wiphy_pause_all_forced(sc, aphy); 1963 ath9k_wiphy_pause_all_forced(sc, aphy);
1843 sc->sc_flags |= SC_OP_SCANNING; 1964 sc->sc_flags |= SC_OP_SCANNING;
1844 del_timer_sync(&common->ani.timer); 1965 del_timer_sync(&common->ani.timer);
1966 cancel_work_sync(&sc->paprd_work);
1845 cancel_delayed_work_sync(&sc->tx_complete_work); 1967 cancel_delayed_work_sync(&sc->tx_complete_work);
1846 mutex_unlock(&sc->mutex); 1968 mutex_unlock(&sc->mutex);
1847} 1969}