diff options
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 74 |
1 files changed, 44 insertions, 30 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 5b4ef81318f5..d49dacbc96a7 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -320,6 +320,42 @@ static void ath_paprd_activate(struct ath_softc *sc) | |||
320 | ath9k_ps_restore(sc); | 320 | ath9k_ps_restore(sc); |
321 | } | 321 | } |
322 | 322 | ||
323 | static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int chain) | ||
324 | { | ||
325 | struct ieee80211_hw *hw = sc->hw; | ||
326 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
327 | struct ath_tx_control txctl; | ||
328 | int time_left; | ||
329 | |||
330 | memset(&txctl, 0, sizeof(txctl)); | ||
331 | txctl.txq = sc->tx.txq_map[WME_AC_BE]; | ||
332 | |||
333 | memset(tx_info, 0, sizeof(*tx_info)); | ||
334 | tx_info->band = hw->conf.channel->band; | ||
335 | tx_info->flags |= IEEE80211_TX_CTL_NO_ACK; | ||
336 | tx_info->control.rates[0].idx = 0; | ||
337 | tx_info->control.rates[0].count = 1; | ||
338 | tx_info->control.rates[0].flags = IEEE80211_TX_RC_MCS; | ||
339 | tx_info->control.rates[1].idx = -1; | ||
340 | |||
341 | init_completion(&sc->paprd_complete); | ||
342 | sc->paprd_pending = true; | ||
343 | txctl.paprd = BIT(chain); | ||
344 | if (ath_tx_start(hw, skb, &txctl) != 0) | ||
345 | return false; | ||
346 | |||
347 | time_left = wait_for_completion_timeout(&sc->paprd_complete, | ||
348 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); | ||
349 | sc->paprd_pending = false; | ||
350 | |||
351 | if (!time_left) | ||
352 | ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CALIBRATE, | ||
353 | "Timeout waiting for paprd training on TX chain %d\n", | ||
354 | chain); | ||
355 | |||
356 | return !!time_left; | ||
357 | } | ||
358 | |||
323 | void ath_paprd_calibrate(struct work_struct *work) | 359 | void ath_paprd_calibrate(struct work_struct *work) |
324 | { | 360 | { |
325 | struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work); | 361 | struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work); |
@@ -327,18 +363,12 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
327 | struct ath_hw *ah = sc->sc_ah; | 363 | struct ath_hw *ah = sc->sc_ah; |
328 | struct ieee80211_hdr *hdr; | 364 | struct ieee80211_hdr *hdr; |
329 | struct sk_buff *skb = NULL; | 365 | struct sk_buff *skb = NULL; |
330 | struct ieee80211_tx_info *tx_info; | ||
331 | int band = hw->conf.channel->band; | ||
332 | struct ieee80211_supported_band *sband = &sc->sbands[band]; | ||
333 | struct ath_tx_control txctl; | ||
334 | struct ath9k_hw_cal_data *caldata = ah->caldata; | 366 | struct ath9k_hw_cal_data *caldata = ah->caldata; |
335 | struct ath_common *common = ath9k_hw_common(ah); | 367 | struct ath_common *common = ath9k_hw_common(ah); |
336 | int ftype; | 368 | int ftype; |
337 | int chain_ok = 0; | 369 | int chain_ok = 0; |
338 | int chain; | 370 | int chain; |
339 | int len = 1800; | 371 | int len = 1800; |
340 | int time_left; | ||
341 | int i; | ||
342 | 372 | ||
343 | if (!caldata) | 373 | if (!caldata) |
344 | return; | 374 | return; |
@@ -347,8 +377,6 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
347 | if (!skb) | 377 | if (!skb) |
348 | return; | 378 | return; |
349 | 379 | ||
350 | tx_info = IEEE80211_SKB_CB(skb); | ||
351 | |||
352 | skb_put(skb, len); | 380 | skb_put(skb, len); |
353 | memset(skb->data, 0, len); | 381 | memset(skb->data, 0, len); |
354 | hdr = (struct ieee80211_hdr *)skb->data; | 382 | hdr = (struct ieee80211_hdr *)skb->data; |
@@ -359,9 +387,6 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
359 | memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); | 387 | memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); |
360 | memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); | 388 | memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); |
361 | 389 | ||
362 | memset(&txctl, 0, sizeof(txctl)); | ||
363 | txctl.txq = sc->tx.txq_map[WME_AC_BE]; | ||
364 | |||
365 | ath9k_ps_wakeup(sc); | 390 | ath9k_ps_wakeup(sc); |
366 | ar9003_paprd_init_table(ah); | 391 | ar9003_paprd_init_table(ah); |
367 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { | 392 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { |
@@ -369,30 +394,19 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
369 | continue; | 394 | continue; |
370 | 395 | ||
371 | chain_ok = 0; | 396 | chain_ok = 0; |
372 | memset(tx_info, 0, sizeof(*tx_info)); | ||
373 | tx_info->band = band; | ||
374 | 397 | ||
375 | for (i = 0; i < 4; i++) { | 398 | ath_dbg(common, ATH_DBG_CALIBRATE, |
376 | tx_info->control.rates[i].idx = sband->n_bitrates - 1; | 399 | "Sending PAPRD frame for thermal measurement " |
377 | tx_info->control.rates[i].count = 6; | 400 | "on chain %d\n", chain); |
378 | } | 401 | if (!ath_paprd_send_frame(sc, skb, chain)) |
402 | goto fail_paprd; | ||
379 | 403 | ||
380 | init_completion(&sc->paprd_complete); | ||
381 | sc->paprd_pending = true; | ||
382 | ar9003_paprd_setup_gain_table(ah, chain); | 404 | ar9003_paprd_setup_gain_table(ah, chain); |
383 | txctl.paprd = BIT(chain); | ||
384 | if (ath_tx_start(hw, skb, &txctl) != 0) | ||
385 | break; | ||
386 | 405 | ||
387 | time_left = wait_for_completion_timeout(&sc->paprd_complete, | 406 | ath_dbg(common, ATH_DBG_CALIBRATE, |
388 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); | 407 | "Sending PAPRD training frame on chain %d\n", chain); |
389 | sc->paprd_pending = false; | 408 | if (!ath_paprd_send_frame(sc, skb, chain)) |
390 | if (!time_left) { | ||
391 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, | ||
392 | "Timeout waiting for paprd training on TX chain %d\n", | ||
393 | chain); | ||
394 | goto fail_paprd; | 409 | goto fail_paprd; |
395 | } | ||
396 | 410 | ||
397 | if (!ar9003_paprd_is_done(ah)) | 411 | if (!ar9003_paprd_is_done(ah)) |
398 | break; | 412 | break; |