Index: chromeos/compat-wireless/drivers/net/wireless/ath/ath9k/main.c |
diff --git a/chromeos/compat-wireless/drivers/net/wireless/ath/ath9k/main.c b/chromeos/compat-wireless/drivers/net/wireless/ath/ath9k/main.c |
index 819928575d57ea791bfd7bc158857451f02f1604..fffbd5ef7783a95864a7a5db647502bde24163a9 100644 |
--- a/chromeos/compat-wireless/drivers/net/wireless/ath/ath9k/main.c |
+++ b/chromeos/compat-wireless/drivers/net/wireless/ath/ath9k/main.c |
@@ -290,6 +290,42 @@ static void ath_paprd_activate(struct ath_softc *sc) |
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_print(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); |
@@ -297,28 +333,23 @@ void ath_paprd_calibrate(struct work_struct *work) |
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; |
+ if (ar9003_paprd_init_table(ah) < 0) |
+ return; |
+ |
skb = alloc_skb(len, GFP_KERNEL); |
if (!skb) |
return; |
- tx_info = IEEE80211_SKB_CB(skb); |
- |
skb_put(skb, len); |
memset(skb->data, 0, len); |
hdr = (struct ieee80211_hdr *)skb->data; |
@@ -329,39 +360,25 @@ void ath_paprd_calibrate(struct work_struct *work) |
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++) { |
if (!(common->tx_chainmask & BIT(chain))) |
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_print(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); |
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)); |
- if (!time_left) { |
- ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, |
- "Timeout waiting for paprd training on " |
- "TX chain %d\n", |
- chain); |
+ ath_print(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; |
@@ -486,7 +503,7 @@ set_timer: |
if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) { |
if (!ah->caldata->paprd_done) |
ieee80211_queue_work(sc->hw, &sc->paprd_work); |
- else |
+ else if (!ah->paprd_table_write_done) |
ath_paprd_activate(sc); |
} |
} |