diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/mac.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/mac.c | 71 |
1 files changed, 9 insertions, 62 deletions
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 58aaf9ab092..cb5d81426d5 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
@@ -171,84 +171,31 @@ void ath9k_hw_abort_tx_dma(struct ath_hw *ah) | |||
171 | } | 171 | } |
172 | EXPORT_SYMBOL(ath9k_hw_abort_tx_dma); | 172 | EXPORT_SYMBOL(ath9k_hw_abort_tx_dma); |
173 | 173 | ||
174 | bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q) | 174 | bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q) |
175 | { | 175 | { |
176 | #define ATH9K_TX_STOP_DMA_TIMEOUT 4000 /* usec */ | 176 | #define ATH9K_TX_STOP_DMA_TIMEOUT 1000 /* usec */ |
177 | #define ATH9K_TIME_QUANTUM 100 /* usec */ | 177 | #define ATH9K_TIME_QUANTUM 100 /* usec */ |
178 | struct ath_common *common = ath9k_hw_common(ah); | 178 | int wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM; |
179 | struct ath9k_hw_capabilities *pCap = &ah->caps; | 179 | int wait; |
180 | struct ath9k_tx_queue_info *qi; | ||
181 | u32 tsfLow, j, wait; | ||
182 | u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM; | ||
183 | |||
184 | if (q >= pCap->total_queues) { | ||
185 | ath_dbg(common, ATH_DBG_QUEUE, | ||
186 | "Stopping TX DMA, invalid queue: %u\n", q); | ||
187 | return false; | ||
188 | } | ||
189 | |||
190 | qi = &ah->txq[q]; | ||
191 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { | ||
192 | ath_dbg(common, ATH_DBG_QUEUE, | ||
193 | "Stopping TX DMA, inactive queue: %u\n", q); | ||
194 | return false; | ||
195 | } | ||
196 | 180 | ||
197 | REG_WRITE(ah, AR_Q_TXD, 1 << q); | 181 | REG_WRITE(ah, AR_Q_TXD, 1 << q); |
198 | 182 | ||
199 | for (wait = wait_time; wait != 0; wait--) { | 183 | for (wait = wait_time; wait != 0; wait--) { |
200 | if (ath9k_hw_numtxpending(ah, q) == 0) | 184 | if (wait != wait_time) |
201 | break; | ||
202 | udelay(ATH9K_TIME_QUANTUM); | ||
203 | } | ||
204 | |||
205 | if (ath9k_hw_numtxpending(ah, q)) { | ||
206 | ath_dbg(common, ATH_DBG_QUEUE, | ||
207 | "%s: Num of pending TX Frames %d on Q %d\n", | ||
208 | __func__, ath9k_hw_numtxpending(ah, q), q); | ||
209 | |||
210 | for (j = 0; j < 2; j++) { | ||
211 | tsfLow = REG_READ(ah, AR_TSF_L32); | ||
212 | REG_WRITE(ah, AR_QUIET2, | ||
213 | SM(10, AR_QUIET2_QUIET_DUR)); | ||
214 | REG_WRITE(ah, AR_QUIET_PERIOD, 100); | ||
215 | REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10); | ||
216 | REG_SET_BIT(ah, AR_TIMER_MODE, | ||
217 | AR_QUIET_TIMER_EN); | ||
218 | |||
219 | if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10)) | ||
220 | break; | ||
221 | |||
222 | ath_dbg(common, ATH_DBG_QUEUE, | ||
223 | "TSF has moved while trying to set quiet time TSF: 0x%08x\n", | ||
224 | tsfLow); | ||
225 | } | ||
226 | |||
227 | REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); | ||
228 | |||
229 | udelay(200); | ||
230 | REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN); | ||
231 | |||
232 | wait = wait_time; | ||
233 | while (ath9k_hw_numtxpending(ah, q)) { | ||
234 | if ((--wait) == 0) { | ||
235 | ath_err(common, | ||
236 | "Failed to stop TX DMA in 100 msec after killing last frame\n"); | ||
237 | break; | ||
238 | } | ||
239 | udelay(ATH9K_TIME_QUANTUM); | 185 | udelay(ATH9K_TIME_QUANTUM); |
240 | } | ||
241 | 186 | ||
242 | REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); | 187 | if (ath9k_hw_numtxpending(ah, q) == 0) |
188 | break; | ||
243 | } | 189 | } |
244 | 190 | ||
245 | REG_WRITE(ah, AR_Q_TXD, 0); | 191 | REG_WRITE(ah, AR_Q_TXD, 0); |
192 | |||
246 | return wait != 0; | 193 | return wait != 0; |
247 | 194 | ||
248 | #undef ATH9K_TX_STOP_DMA_TIMEOUT | 195 | #undef ATH9K_TX_STOP_DMA_TIMEOUT |
249 | #undef ATH9K_TIME_QUANTUM | 196 | #undef ATH9K_TIME_QUANTUM |
250 | } | 197 | } |
251 | EXPORT_SYMBOL(ath9k_hw_stoptxdma); | 198 | EXPORT_SYMBOL(ath9k_hw_stop_dma_queue); |
252 | 199 | ||
253 | void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs) | 200 | void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs) |
254 | { | 201 | { |