aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorNick Kossifidis <mickflemm@gmail.com>2010-11-23 14:19:45 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-11-30 13:53:21 -0500
commiteeb8832b3181d6ca8593051b68c466e5d2653bb3 (patch)
tree3e4749a0c9ff335560b0f61df3496d576cea98d3 /drivers/net/wireless/ath
parent61cde037234c4b8e6497a23f5f236c64cbf9d41d (diff)
ath5k: Set all IFS intervals, not just slot time
* Replace set_slot_time with set_ifs_intervals that also sets the various inter-frame space intervals based on current bwmode. * Clean up AR5210 mess from reset_tx_queue, AR5210 only has one data queue and we set IFS intervals for that queue on set_ifs_intervals so there is nothing left to do for 5210 on reset_tx_queue. Signed-off-by: Nick Kossifidis <mickflemm@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h31
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c513
-rw-r--r--drivers/net/wireless/ath/ath5k/reg.h3
4 files changed, 308 insertions, 243 deletions
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 7df5b46ab69..ddbbf4c02fe 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -222,34 +222,15 @@
222 222
223/* Initial values */ 223/* Initial values */
224#define AR5K_INIT_CYCRSSI_THR1 2 224#define AR5K_INIT_CYCRSSI_THR1 2
225#define AR5K_INIT_TX_LATENCY 502 225
226#define AR5K_INIT_USEC 39 226/* Tx retry limits */
227#define AR5K_INIT_USEC_TURBO 79
228#define AR5K_INIT_USEC_32 31
229#define AR5K_INIT_SLOT_TIME_CLOCK 396
230#define AR5K_INIT_SLOT_TIME_TURBO_CLOCK 480
231#define AR5K_INIT_ACK_CTS_TIMEOUT 1024
232#define AR5K_INIT_ACK_CTS_TIMEOUT_TURBO 0x08000800
233#define AR5K_INIT_PROG_IFS 920
234#define AR5K_INIT_PROG_IFS_TURBO 960
235#define AR5K_INIT_EIFS 3440
236#define AR5K_INIT_EIFS_TURBO 6880
237#define AR5K_INIT_SIFS_CLOCK 560
238#define AR5K_INIT_SIFS_TURBO_CLOCK 480
239#define AR5K_INIT_SH_RETRY 10 227#define AR5K_INIT_SH_RETRY 10
240#define AR5K_INIT_LG_RETRY AR5K_INIT_SH_RETRY 228#define AR5K_INIT_LG_RETRY AR5K_INIT_SH_RETRY
229/* For station mode */
241#define AR5K_INIT_SSH_RETRY 32 230#define AR5K_INIT_SSH_RETRY 32
242#define AR5K_INIT_SLG_RETRY AR5K_INIT_SSH_RETRY 231#define AR5K_INIT_SLG_RETRY AR5K_INIT_SSH_RETRY
243#define AR5K_INIT_TX_RETRY 10 232#define AR5K_INIT_TX_RETRY 10
244 233
245#define AR5K_INIT_PROTO_TIME_CNTRL ( \
246 (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS << 12) | \
247 (AR5K_INIT_PROG_IFS) \
248)
249#define AR5K_INIT_PROTO_TIME_CNTRL_TURBO ( \
250 (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS_TURBO << 12) | \
251 (AR5K_INIT_PROG_IFS_TURBO) \
252)
253 234
254/* Slot time */ 235/* Slot time */
255#define AR5K_INIT_SLOT_TIME_TURBO 6 236#define AR5K_INIT_SLOT_TIME_TURBO 6
@@ -1240,6 +1221,10 @@ int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
1240 1221
1241 1222
1242/* Protocol Control Unit Functions */ 1223/* Protocol Control Unit Functions */
1224/* Helpers */
1225int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
1226 int len, struct ieee80211_rate *rate);
1227unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah);
1243extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); 1228extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode);
1244void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); 1229void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class);
1245/* RX filter control*/ 1230/* RX filter control*/
@@ -1273,7 +1258,7 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah,
1273u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue); 1258u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue);
1274void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue); 1259void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue);
1275int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue); 1260int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue);
1276int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time); 1261int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time);
1277/* Init function */ 1262/* Init function */
1278int ath5k_hw_init_queues(struct ath5k_hw *ah); 1263int ath5k_hw_init_queues(struct ath5k_hw *ah);
1279 1264
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index e7f6be9cdf1..6af9504cc7f 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -763,7 +763,7 @@ ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval)
763 * @ah: The &struct ath5k_hw 763 * @ah: The &struct ath5k_hw
764 * @coverage_class: IEEE 802.11 coverage class number 764 * @coverage_class: IEEE 802.11 coverage class number
765 * 765 *
766 * Sets slot time, ACK timeout and CTS timeout for given coverage class. 766 * Sets IFS intervals and ACK/CTS timeouts for given coverage class.
767 */ 767 */
768void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class) 768void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class)
769{ 769{
@@ -772,7 +772,7 @@ void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class)
772 int ack_timeout = ath5k_hw_get_default_sifs(ah) + slot_time; 772 int ack_timeout = ath5k_hw_get_default_sifs(ah) + slot_time;
773 int cts_timeout = ack_timeout; 773 int cts_timeout = ack_timeout;
774 774
775 ath5k_hw_set_slot_time(ah, slot_time); 775 ath5k_hw_set_ifs_intervals(ah, slot_time);
776 ath5k_hw_set_ack_timeout(ah, ack_timeout); 776 ath5k_hw_set_ack_timeout(ah, ack_timeout);
777 ath5k_hw_set_cts_timeout(ah, cts_timeout); 777 ath5k_hw_set_cts_timeout(ah, cts_timeout);
778 778
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index 6eb6838d906..e13142a3b95 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -276,8 +276,14 @@ static void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah,
276 return; 276 return;
277} 277}
278 278
279/* 279/**
280 * Set DFS properties for a transmit queue on DCU 280 * ath5k_hw_reset_tx_queue - Initialize a single hw queue
281 *
282 * @ah The &struct ath5k_hw
283 * @queue The hw queue number
284 *
285 * Set DFS properties for the given transmit queue on DCU
286 * and configures all queue-specific parameters.
281 */ 287 */
282int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) 288int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
283{ 289{
@@ -287,239 +293,216 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
287 293
288 tq = &ah->ah_txq[queue]; 294 tq = &ah->ah_txq[queue];
289 295
290 if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE) 296 /* Skip if queue inactive or if we are on AR5210
297 * that doesn't have QCU/DCU */
298 if ((ah->ah_version == AR5K_AR5210) ||
299 (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE))
291 return 0; 300 return 0;
292 301
293 if (ah->ah_version == AR5K_AR5210) { 302 /*
294 /* Only handle data queues, others will be ignored */ 303 * Set contention window (cw_min/cw_max)
295 if (tq->tqi_type != AR5K_TX_QUEUE_DATA) 304 * and arbitrated interframe space (aifs)...
296 return 0; 305 */
297 306 ath5k_hw_reg_write(ah,
298 /* Set Slot time */ 307 AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
299 ath5k_hw_reg_write(ah, (ah->ah_bwmode == AR5K_BWMODE_40MHZ) ? 308 AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
300 AR5K_INIT_SLOT_TIME_TURBO_CLOCK : 309 AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS),
301 AR5K_INIT_SLOT_TIME_CLOCK, 310 AR5K_QUEUE_DFS_LOCAL_IFS(queue));
302 AR5K_SLOT_TIME);
303 /* Set ACK_CTS timeout */
304 ath5k_hw_reg_write(ah, (ah->ah_bwmode == AR5K_BWMODE_40MHZ) ?
305 AR5K_INIT_ACK_CTS_TIMEOUT_TURBO :
306 AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME);
307
308 /* Set IFS0 */
309 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) {
310 ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO_CLOCK +
311 tq->tqi_aifs * AR5K_INIT_SLOT_TIME_TURBO_CLOCK)
312 << AR5K_IFS0_DIFS_S) |
313 AR5K_INIT_SIFS_TURBO_CLOCK,
314 AR5K_IFS0);
315 } else {
316 ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_CLOCK +
317 tq->tqi_aifs * AR5K_INIT_SLOT_TIME_CLOCK) <<
318 AR5K_IFS0_DIFS_S) |
319 AR5K_INIT_SIFS_CLOCK, AR5K_IFS0);
320 }
321
322 /* Set IFS1 */
323 ath5k_hw_reg_write(ah, (ah->ah_bwmode == AR5K_BWMODE_40MHZ) ?
324 AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
325 AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
326 } else {
327 311
328 /*===Rest is also for QCU/DCU only [5211+]===*/ 312 /*
313 * Set tx retry limits for this queue
314 */
315 ath5k_hw_set_tx_retry_limits(ah, queue);
329 316
330 /*
331 * Set contention window (cw_min/cw_max)
332 * and arbitrated interframe space (aifs)...
333 */
334 ath5k_hw_reg_write(ah,
335 AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
336 AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
337 AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS),
338 AR5K_QUEUE_DFS_LOCAL_IFS(queue));
339 317
340 /* 318 /*
341 * Set tx retry limits for this queue 319 * Set misc registers
342 */ 320 */
343 ath5k_hw_set_tx_retry_limits(ah, queue);
344 321
345 /* 322 /* Enable DCU to wait for next fragment from QCU */
346 * Set misc registers 323 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
347 */ 324 AR5K_DCU_MISC_FRAG_WAIT);
348 325
349 /* Enable DCU to wait for next fragment from QCU */ 326 /* On Maui and Spirit use the global seqnum on DCU */
327 if (ah->ah_mac_version < AR5K_SREV_AR5211)
350 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), 328 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
351 AR5K_DCU_MISC_FRAG_WAIT); 329 AR5K_DCU_MISC_SEQNUM_CTL);
352 330
353 /* On Maui and Spirit use the global seqnum on DCU */ 331 /* Constant bit rate period */
354 if (ah->ah_mac_version < AR5K_SREV_AR5211) 332 if (tq->tqi_cbr_period) {
355 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), 333 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
356 AR5K_DCU_MISC_SEQNUM_CTL); 334 AR5K_QCU_CBRCFG_INTVAL) |
357 335 AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
358 if (tq->tqi_cbr_period) { 336 AR5K_QCU_CBRCFG_ORN_THRES),
359 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period, 337 AR5K_QUEUE_CBRCFG(queue));
360 AR5K_QCU_CBRCFG_INTVAL) | 338
361 AR5K_REG_SM(tq->tqi_cbr_overflow_limit, 339 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
362 AR5K_QCU_CBRCFG_ORN_THRES), 340 AR5K_QCU_MISC_FRSHED_CBR);
363 AR5K_QUEUE_CBRCFG(queue)); 341
342 if (tq->tqi_cbr_overflow_limit)
364 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), 343 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
365 AR5K_QCU_MISC_FRSHED_CBR);
366 if (tq->tqi_cbr_overflow_limit)
367 AR5K_REG_ENABLE_BITS(ah,
368 AR5K_QUEUE_MISC(queue),
369 AR5K_QCU_MISC_CBR_THRES_ENABLE); 344 AR5K_QCU_MISC_CBR_THRES_ENABLE);
370 } 345 }
346
347 /* Ready time interval */
348 if (tq->tqi_ready_time && (tq->tqi_type != AR5K_TX_QUEUE_CAB))
349 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
350 AR5K_QCU_RDYTIMECFG_INTVAL) |
351 AR5K_QCU_RDYTIMECFG_ENABLE,
352 AR5K_QUEUE_RDYTIMECFG(queue));
353
354 if (tq->tqi_burst_time) {
355 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
356 AR5K_DCU_CHAN_TIME_DUR) |
357 AR5K_DCU_CHAN_TIME_ENABLE,
358 AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
371 359
372 if (tq->tqi_ready_time && 360 if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
373 (tq->tqi_type != AR5K_TX_QUEUE_CAB)) 361 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
374 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
375 AR5K_QCU_RDYTIMECFG_INTVAL) |
376 AR5K_QCU_RDYTIMECFG_ENABLE,
377 AR5K_QUEUE_RDYTIMECFG(queue));
378
379 if (tq->tqi_burst_time) {
380 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
381 AR5K_DCU_CHAN_TIME_DUR) |
382 AR5K_DCU_CHAN_TIME_ENABLE,
383 AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
384
385 if (tq->tqi_flags
386 & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
387 AR5K_REG_ENABLE_BITS(ah,
388 AR5K_QUEUE_MISC(queue),
389 AR5K_QCU_MISC_RDY_VEOL_POLICY); 362 AR5K_QCU_MISC_RDY_VEOL_POLICY);
390 } 363 }
391 364
392 if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE) 365 /* Enable/disable Post frame backoff */
393 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS, 366 if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
394 AR5K_QUEUE_DFS_MISC(queue)); 367 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
368 AR5K_QUEUE_DFS_MISC(queue));
395 369
396 if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) 370 /* Enable/disable fragmentation burst backoff */
397 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG, 371 if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
398 AR5K_QUEUE_DFS_MISC(queue)); 372 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
373 AR5K_QUEUE_DFS_MISC(queue));
399 374
400 /* 375 /*
401 * Set registers by queue type 376 * Set registers by queue type
402 */ 377 */
403 switch (tq->tqi_type) { 378 switch (tq->tqi_type) {
404 case AR5K_TX_QUEUE_BEACON: 379 case AR5K_TX_QUEUE_BEACON:
405 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), 380 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
406 AR5K_QCU_MISC_FRSHED_DBA_GT | 381 AR5K_QCU_MISC_FRSHED_DBA_GT |
407 AR5K_QCU_MISC_CBREXP_BCN_DIS | 382 AR5K_QCU_MISC_CBREXP_BCN_DIS |
408 AR5K_QCU_MISC_BCN_ENABLE); 383 AR5K_QCU_MISC_BCN_ENABLE);
409 384
410 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), 385 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
411 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL << 386 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
412 AR5K_DCU_MISC_ARBLOCK_CTL_S) | 387 AR5K_DCU_MISC_ARBLOCK_CTL_S) |
413 AR5K_DCU_MISC_ARBLOCK_IGNORE | 388 AR5K_DCU_MISC_ARBLOCK_IGNORE |
414 AR5K_DCU_MISC_POST_FR_BKOFF_DIS | 389 AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
415 AR5K_DCU_MISC_BCN_ENABLE); 390 AR5K_DCU_MISC_BCN_ENABLE);
416 break; 391 break;
392
393 case AR5K_TX_QUEUE_CAB:
394 /* XXX: use BCN_SENT_GT, if we can figure out how */
395 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
396 AR5K_QCU_MISC_FRSHED_DBA_GT |
397 AR5K_QCU_MISC_CBREXP_DIS |
398 AR5K_QCU_MISC_CBREXP_BCN_DIS);
399
400 ath5k_hw_reg_write(ah, ((tq->tqi_ready_time -
401 (AR5K_TUNE_SW_BEACON_RESP -
402 AR5K_TUNE_DMA_BEACON_RESP) -
403 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
404 AR5K_QCU_RDYTIMECFG_ENABLE,
405 AR5K_QUEUE_RDYTIMECFG(queue));
417 406
418 case AR5K_TX_QUEUE_CAB: 407 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
419 /* XXX: use BCN_SENT_GT, if we can figure out how */ 408 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
420 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), 409 AR5K_DCU_MISC_ARBLOCK_CTL_S));
421 AR5K_QCU_MISC_FRSHED_DBA_GT | 410 break;
422 AR5K_QCU_MISC_CBREXP_DIS |
423 AR5K_QCU_MISC_CBREXP_BCN_DIS);
424 411
425 ath5k_hw_reg_write(ah, ((tq->tqi_ready_time - 412 case AR5K_TX_QUEUE_UAPSD:
426 (AR5K_TUNE_SW_BEACON_RESP - 413 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
427 AR5K_TUNE_DMA_BEACON_RESP) - 414 AR5K_QCU_MISC_CBREXP_DIS);
428 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) | 415 break;
429 AR5K_QCU_RDYTIMECFG_ENABLE,
430 AR5K_QUEUE_RDYTIMECFG(queue));
431 416
432 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), 417 case AR5K_TX_QUEUE_DATA:
433 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL << 418 default:
434 AR5K_DCU_MISC_ARBLOCK_CTL_S));
435 break; 419 break;
420 }
436 421
437 case AR5K_TX_QUEUE_UAPSD: 422 /* TODO: Handle frame compression */
438 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
439 AR5K_QCU_MISC_CBREXP_DIS);
440 break;
441 423
442 case AR5K_TX_QUEUE_DATA: 424 /*
443 default: 425 * Enable interrupts for this tx queue
444 break; 426 * in the secondary interrupt mask registers
445 } 427 */
428 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
429 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
446 430
447 /* TODO: Handle frame compression */ 431 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
448 432 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
449 /* 433
450 * Enable interrupts for this tx queue 434 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
451 * in the secondary interrupt mask registers 435 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
452 */ 436
453 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE) 437 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
454 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue); 438 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
455 439
456 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE) 440 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
457 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue); 441 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
458 442
459 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE) 443 if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE)
460 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue); 444 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue);
461 445
462 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE) 446 if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE)
463 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue); 447 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue);
464 448
465 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE) 449 if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE)
466 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue); 450 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue);
467 451
468 if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE) 452 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE)
469 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue); 453 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue);
470 454
471 if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE) 455 /* Update secondary interrupt mask registers */
472 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue); 456
473 457 /* Filter out inactive queues */
474 if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE) 458 ah->ah_txq_imr_txok &= ah->ah_txq_status;
475 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue); 459 ah->ah_txq_imr_txerr &= ah->ah_txq_status;
476 460 ah->ah_txq_imr_txurn &= ah->ah_txq_status;
477 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE) 461 ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
478 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue); 462 ah->ah_txq_imr_txeol &= ah->ah_txq_status;
479 463 ah->ah_txq_imr_cbrorn &= ah->ah_txq_status;
480 /* Update secondary interrupt mask registers */ 464 ah->ah_txq_imr_cbrurn &= ah->ah_txq_status;
481 465 ah->ah_txq_imr_qtrig &= ah->ah_txq_status;
482 /* Filter out inactive queues */ 466 ah->ah_txq_imr_nofrm &= ah->ah_txq_status;
483 ah->ah_txq_imr_txok &= ah->ah_txq_status; 467
484 ah->ah_txq_imr_txerr &= ah->ah_txq_status; 468 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
485 ah->ah_txq_imr_txurn &= ah->ah_txq_status; 469 AR5K_SIMR0_QCU_TXOK) |
486 ah->ah_txq_imr_txdesc &= ah->ah_txq_status; 470 AR5K_REG_SM(ah->ah_txq_imr_txdesc,
487 ah->ah_txq_imr_txeol &= ah->ah_txq_status; 471 AR5K_SIMR0_QCU_TXDESC),
488 ah->ah_txq_imr_cbrorn &= ah->ah_txq_status; 472 AR5K_SIMR0);
489 ah->ah_txq_imr_cbrurn &= ah->ah_txq_status; 473
490 ah->ah_txq_imr_qtrig &= ah->ah_txq_status; 474 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
491 ah->ah_txq_imr_nofrm &= ah->ah_txq_status; 475 AR5K_SIMR1_QCU_TXERR) |
492 476 AR5K_REG_SM(ah->ah_txq_imr_txeol,
493 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok, 477 AR5K_SIMR1_QCU_TXEOL),
494 AR5K_SIMR0_QCU_TXOK) | 478 AR5K_SIMR1);
495 AR5K_REG_SM(ah->ah_txq_imr_txdesc, 479
496 AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0); 480 /* Update SIMR2 but don't overwrite rest simr2 settings */
497 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr, 481 AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN);
498 AR5K_SIMR1_QCU_TXERR) | 482 AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2,
499 AR5K_REG_SM(ah->ah_txq_imr_txeol, 483 AR5K_REG_SM(ah->ah_txq_imr_txurn,
500 AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1); 484 AR5K_SIMR2_QCU_TXURN));
501 /* Update simr2 but don't overwrite rest simr2 settings */ 485
502 AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN); 486 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn,
503 AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2, 487 AR5K_SIMR3_QCBRORN) |
504 AR5K_REG_SM(ah->ah_txq_imr_txurn, 488 AR5K_REG_SM(ah->ah_txq_imr_cbrurn,
505 AR5K_SIMR2_QCU_TXURN)); 489 AR5K_SIMR3_QCBRURN),
506 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn, 490 AR5K_SIMR3);
507 AR5K_SIMR3_QCBRORN) | 491
508 AR5K_REG_SM(ah->ah_txq_imr_cbrurn, 492 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig,
509 AR5K_SIMR3_QCBRURN), AR5K_SIMR3); 493 AR5K_SIMR4_QTRIG), AR5K_SIMR4);
510 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig, 494
511 AR5K_SIMR4_QTRIG), AR5K_SIMR4); 495 /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */
512 /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */ 496 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm,
513 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm, 497 AR5K_TXNOFRM_QCU), AR5K_TXNOFRM);
514 AR5K_TXNOFRM_QCU), AR5K_TXNOFRM); 498
515 /* No queue has TXNOFRM enabled, disable the interrupt 499 /* No queue has TXNOFRM enabled, disable the interrupt
516 * by setting AR5K_TXNOFRM to zero */ 500 * by setting AR5K_TXNOFRM to zero */
517 if (ah->ah_txq_imr_nofrm == 0) 501 if (ah->ah_txq_imr_nofrm == 0)
518 ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM); 502 ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);
519 503
520 /* Set QCU mask for this DCU to save power */ 504 /* Set QCU mask for this DCU to save power */
521 AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue); 505 AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);
522 }
523 506
524 return 0; 507 return 0;
525} 508}
@@ -529,24 +512,114 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
529* Global QCU/DCU functions * 512* Global QCU/DCU functions *
530\**************************/ 513\**************************/
531 514
532/* 515/**
533 * Set slot time on DCU 516 * ath5k_hw_set_ifs_intervals - Set global inter-frame spaces on DCU
517 *
518 * @ah The &struct ath5k_hw
519 * @slot_time Slot time in us
520 *
521 * Sets the global IFS intervals on DCU (also works on AR5210) for
522 * the given slot time and the current bwmode.
534 */ 523 */
535int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) 524int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)
536{ 525{
526 struct ieee80211_channel *channel = ah->ah_current_channel;
527 struct ath5k_softc *sc = ah->ah_sc;
528 struct ieee80211_rate *rate;
529 u32 ack_tx_time, eifs, eifs_clock, sifs, sifs_clock;
537 u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time); 530 u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time);
538 531
539 if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX) 532 if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX)
540 return -EINVAL; 533 return -EINVAL;
541 534
542 if (ah->ah_version == AR5K_AR5210) 535 sifs = ath5k_hw_get_default_sifs(ah);
543 ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME); 536 sifs_clock = ath5k_hw_htoclock(ah, sifs);
537
538 /* EIFS
539 * Txtime of ack at lowest rate + SIFS + DIFS
540 * (DIFS = SIFS + 2 * Slot time)
541 *
542 * Note: HAL has some predefined values for EIFS
543 * Turbo: (37 + 2 * 6)
544 * Default: (74 + 2 * 9)
545 * Half: (149 + 2 * 13)
546 * Quarter: (298 + 2 * 21)
547 *
548 * (74 + 2 * 6) for AR5210 default and turbo !
549 *
550 * According to the formula we have
551 * ack_tx_time = 25 for turbo and
552 * ack_tx_time = 42.5 * clock multiplier
553 * for default/half/quarter.
554 *
555 * This can't be right, 42 is what we would get
556 * from ath5k_hw_get_frame_dur_for_bwmode or
557 * ieee80211_generic_frame_duration for zero frame
558 * length and without SIFS !
559 *
560 * Also we have different lowest rate for 802.11a
561 */
562 if (channel->hw_value & CHANNEL_5GHZ)
563 rate = &sc->sbands[IEEE80211_BAND_5GHZ].bitrates[0];
544 else 564 else
545 ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT); 565 rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[0];
566
567 ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate);
568
569 /* ack_tx_time includes an SIFS already */
570 eifs = ack_tx_time + sifs + 2 * slot_time;
571 eifs_clock = ath5k_hw_htoclock(ah, eifs);
572
573 /* Set IFS settings on AR5210 */
574 if (ah->ah_version == AR5K_AR5210) {
575 u32 pifs, pifs_clock, difs, difs_clock;
576
577 /* Set slot time */
578 ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME);
579
580 /* Set EIFS */
581 eifs_clock = AR5K_REG_SM(eifs_clock, AR5K_IFS1_EIFS);
582
583 /* PIFS = Slot time + SIFS */
584 pifs = slot_time + sifs;
585 pifs_clock = ath5k_hw_htoclock(ah, pifs);
586 pifs_clock = AR5K_REG_SM(pifs_clock, AR5K_IFS1_PIFS);
587
588 /* DIFS = SIFS + 2 * Slot time */
589 difs = sifs + 2 * slot_time;
590 difs_clock = ath5k_hw_htoclock(ah, difs);
591
592 /* Set SIFS/DIFS */
593 ath5k_hw_reg_write(ah, (difs_clock <<
594 AR5K_IFS0_DIFS_S) | sifs_clock,
595 AR5K_IFS0);
596
597 /* Set PIFS/EIFS and preserve AR5K_INIT_CARR_SENSE_EN */
598 ath5k_hw_reg_write(ah, pifs_clock | eifs_clock |
599 (AR5K_INIT_CARR_SENSE_EN << AR5K_IFS1_CS_EN_S),
600 AR5K_IFS1);
601
602 return 0;
603 }
604
605 /* Set IFS slot time */
606 ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT);
607
608 /* Set EIFS interval */
609 ath5k_hw_reg_write(ah, eifs_clock, AR5K_DCU_GBL_IFS_EIFS);
610
611 /* Set SIFS interval in usecs */
612 AR5K_REG_WRITE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,
613 AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC,
614 sifs);
615
616 /* Set SIFS interval in clock cycles */
617 ath5k_hw_reg_write(ah, sifs_clock, AR5K_DCU_GBL_IFS_SIFS);
546 618
547 return 0; 619 return 0;
548} 620}
549 621
622
550int ath5k_hw_init_queues(struct ath5k_hw *ah) 623int ath5k_hw_init_queues(struct ath5k_hw *ah)
551{ 624{
552 int i, ret; 625 int i, ret;
@@ -559,14 +632,20 @@ int ath5k_hw_init_queues(struct ath5k_hw *ah)
559 * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping 632 * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping
560 * Note: If we want we can assign multiple qcus on one dcu. 633 * Note: If we want we can assign multiple qcus on one dcu.
561 */ 634 */
562 for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) { 635 if (ah->ah_version != AR5K_AR5210)
563 ret = ath5k_hw_reset_tx_queue(ah, i); 636 for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
564 if (ret) { 637 ret = ath5k_hw_reset_tx_queue(ah, i);
565 ATH5K_ERR(ah->ah_sc, 638 if (ret) {
566 "failed to reset TX queue #%d\n", i); 639 ATH5K_ERR(ah->ah_sc,
567 return ret; 640 "failed to reset TX queue #%d\n", i);
641 return ret;
642 }
568 } 643 }
569 } 644 else
645 /* No QCU/DCU on AR5210, just set tx
646 * retry limits. We set IFS parameters
647 * on ath5k_hw_set_ifs_intervals */
648 ath5k_hw_set_tx_retry_limits(ah, 0);
570 649
571 return 0; 650 return 0;
572} 651}
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
index dc213bb121e..8516728a407 100644
--- a/drivers/net/wireless/ath/ath5k/reg.h
+++ b/drivers/net/wireless/ath/ath5k/reg.h
@@ -787,6 +787,7 @@
787#define AR5K_DCU_GBL_IFS_MISC_LFSR_SLICE 0x00000007 /* LFSR Slice Select */ 787#define AR5K_DCU_GBL_IFS_MISC_LFSR_SLICE 0x00000007 /* LFSR Slice Select */
788#define AR5K_DCU_GBL_IFS_MISC_TURBO_MODE 0x00000008 /* Turbo mode */ 788#define AR5K_DCU_GBL_IFS_MISC_TURBO_MODE 0x00000008 /* Turbo mode */
789#define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC 0x000003f0 /* SIFS Duration mask */ 789#define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC 0x000003f0 /* SIFS Duration mask */
790#define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC_S 4
790#define AR5K_DCU_GBL_IFS_MISC_USEC_DUR 0x000ffc00 /* USEC Duration mask */ 791#define AR5K_DCU_GBL_IFS_MISC_USEC_DUR 0x000ffc00 /* USEC Duration mask */
791#define AR5K_DCU_GBL_IFS_MISC_USEC_DUR_S 10 792#define AR5K_DCU_GBL_IFS_MISC_USEC_DUR_S 10
792#define AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY 0x00300000 /* DCU Arbiter delay mask */ 793#define AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY 0x00300000 /* DCU Arbiter delay mask */
@@ -1311,7 +1312,7 @@
1311#define AR5K_IFS1_EIFS 0x03fff000 1312#define AR5K_IFS1_EIFS 0x03fff000
1312#define AR5K_IFS1_EIFS_S 12 1313#define AR5K_IFS1_EIFS_S 12
1313#define AR5K_IFS1_CS_EN 0x04000000 1314#define AR5K_IFS1_CS_EN 0x04000000
1314 1315#define AR5K_IFS1_CS_EN_S 26
1315 1316
1316/* 1317/*
1317 * CFP duration register 1318 * CFP duration register