--- 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 at ath9k_ps_restore(sc); } +static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int chain) +{ + struct ieee80211_hw *hw = sc->hw; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ath_tx_control txctl; + int time_left; + + memset(&txctl, 0, sizeof(txctl)); + txctl.txq = sc->tx.txq_map[WME_AC_BE]; + + memset(tx_info, 0, sizeof(*tx_info)); + tx_info->band = hw->conf.channel->band; + tx_info->flags |= IEEE80211_TX_CTL_NO_ACK; + tx_info->control.rates[0].idx = 0; + tx_info->control.rates[0].count = 1; + tx_info->control.rates[0].flags = IEEE80211_TX_RC_MCS; + tx_info->control.rates[1].idx = -1; + + init_completion(&sc->paprd_complete); + sc->paprd_pending = true; + txctl.paprd = BIT(chain); + if (ath_tx_start(hw, skb, &txctl) != 0) + return false; + + time_left = wait_for_completion_timeout(&sc->paprd_complete, + msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); + sc->paprd_pending = false; + + if (!time_left) + ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CALIBRATE, + "Timeout waiting for paprd training on TX chain %d\n", + chain); + + return !!time_left; +} + void ath_paprd_calibrate(struct work_struct *work) { struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work); @@ -327,18 +363,12 @@ void ath_paprd_calibrate(struct work_str struct ath_hw *ah = sc->sc_ah; struct ieee80211_hdr *hdr; struct sk_buff *skb = NULL; - struct ieee80211_tx_info *tx_info; - int band = hw->conf.channel->band; - struct ieee80211_supported_band *sband = &sc->sbands[band]; - struct ath_tx_control txctl; struct ath9k_hw_cal_data *caldata = ah->caldata; struct ath_common *common = ath9k_hw_common(ah); int ftype; int chain_ok = 0; int chain; int len = 1800; - int time_left; - int i; if (!caldata) return; @@ -347,8 +377,6 @@ void ath_paprd_calibrate(struct work_str if (!skb) return; - tx_info = IEEE80211_SKB_CB(skb); - skb_put(skb, len); memset(skb->data, 0, len); hdr = (struct ieee80211_hdr *)skb->data; @@ -359,9 +387,6 @@ void ath_paprd_calibrate(struct work_str memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); - memset(&txctl, 0, sizeof(txctl)); - txctl.txq = sc->tx.txq_map[WME_AC_BE]; - ath9k_ps_wakeup(sc); ar9003_paprd_init_table(ah); for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { @@ -369,30 +394,19 @@ void ath_paprd_calibrate(struct work_str continue; chain_ok = 0; - memset(tx_info, 0, sizeof(*tx_info)); - tx_info->band = band; - for (i = 0; i < 4; i++) { - tx_info->control.rates[i].idx = sband->n_bitrates - 1; - tx_info->control.rates[i].count = 6; - } + ath_dbg(common, ATH_DBG_CALIBRATE, + "Sending PAPRD frame for thermal measurement " + "on chain %d\n", chain); + if (!ath_paprd_send_frame(sc, skb, chain)) + goto fail_paprd; - init_completion(&sc->paprd_complete); - sc->paprd_pending = true; ar9003_paprd_setup_gain_table(ah, chain); - txctl.paprd = BIT(chain); - if (ath_tx_start(hw, skb, &txctl) != 0) - break; - time_left = wait_for_completion_timeout(&sc->paprd_complete, - msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); - sc->paprd_pending = false; - if (!time_left) { - ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, - "Timeout waiting for paprd training on TX chain %d\n", - chain); + ath_dbg(common, ATH_DBG_CALIBRATE, + "Sending PAPRD training frame on chain %d\n", chain); + if (!ath_paprd_send_frame(sc, skb, chain)) goto fail_paprd; - } if (!ar9003_paprd_is_done(ah)) break;