diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-tx.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-tx.c | 59 |
1 files changed, 49 insertions, 10 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 6aa309032f4e..343d81ad2653 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -433,6 +433,26 @@ out_free_arrays: | |||
433 | } | 433 | } |
434 | EXPORT_SYMBOL(iwl_tx_queue_init); | 434 | EXPORT_SYMBOL(iwl_tx_queue_init); |
435 | 435 | ||
436 | void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, | ||
437 | int slots_num, u32 txq_id) | ||
438 | { | ||
439 | int actual_slots = slots_num; | ||
440 | |||
441 | if (txq_id == IWL_CMD_QUEUE_NUM) | ||
442 | actual_slots++; | ||
443 | |||
444 | memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots); | ||
445 | |||
446 | txq->need_update = 0; | ||
447 | |||
448 | /* Initialize queue's high/low-water marks, and head/tail indexes */ | ||
449 | iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); | ||
450 | |||
451 | /* Tell device where to find queue */ | ||
452 | priv->cfg->ops->lib->txq_init(priv, txq); | ||
453 | } | ||
454 | EXPORT_SYMBOL(iwl_tx_queue_reset); | ||
455 | |||
436 | /** | 456 | /** |
437 | * iwl_hw_txq_ctx_free - Free TXQ Context | 457 | * iwl_hw_txq_ctx_free - Free TXQ Context |
438 | * | 458 | * |
@@ -444,8 +464,7 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv) | |||
444 | 464 | ||
445 | /* Tx queues */ | 465 | /* Tx queues */ |
446 | if (priv->txq) { | 466 | if (priv->txq) { |
447 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; | 467 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) |
448 | txq_id++) | ||
449 | if (txq_id == IWL_CMD_QUEUE_NUM) | 468 | if (txq_id == IWL_CMD_QUEUE_NUM) |
450 | iwl_cmd_queue_free(priv); | 469 | iwl_cmd_queue_free(priv); |
451 | else | 470 | else |
@@ -461,15 +480,15 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv) | |||
461 | EXPORT_SYMBOL(iwl_hw_txq_ctx_free); | 480 | EXPORT_SYMBOL(iwl_hw_txq_ctx_free); |
462 | 481 | ||
463 | /** | 482 | /** |
464 | * iwl_txq_ctx_reset - Reset TX queue context | 483 | * iwl_txq_ctx_alloc - allocate TX queue context |
465 | * Destroys all DMA structures and initialize them again | 484 | * Allocate all Tx DMA structures and initialize them |
466 | * | 485 | * |
467 | * @param priv | 486 | * @param priv |
468 | * @return error code | 487 | * @return error code |
469 | */ | 488 | */ |
470 | int iwl_txq_ctx_reset(struct iwl_priv *priv) | 489 | int iwl_txq_ctx_alloc(struct iwl_priv *priv) |
471 | { | 490 | { |
472 | int ret = 0; | 491 | int ret; |
473 | int txq_id, slots_num; | 492 | int txq_id, slots_num; |
474 | unsigned long flags; | 493 | unsigned long flags; |
475 | 494 | ||
@@ -527,8 +546,31 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv) | |||
527 | return ret; | 546 | return ret; |
528 | } | 547 | } |
529 | 548 | ||
549 | void iwl_txq_ctx_reset(struct iwl_priv *priv) | ||
550 | { | ||
551 | int txq_id, slots_num; | ||
552 | unsigned long flags; | ||
553 | |||
554 | spin_lock_irqsave(&priv->lock, flags); | ||
555 | |||
556 | /* Turn off all Tx DMA fifos */ | ||
557 | priv->cfg->ops->lib->txq_set_sched(priv, 0); | ||
558 | |||
559 | /* Tell NIC where to find the "keep warm" buffer */ | ||
560 | iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4); | ||
561 | |||
562 | spin_unlock_irqrestore(&priv->lock, flags); | ||
563 | |||
564 | /* Alloc and init all Tx queues, including the command queue (#4) */ | ||
565 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { | ||
566 | slots_num = txq_id == IWL_CMD_QUEUE_NUM ? | ||
567 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; | ||
568 | iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id); | ||
569 | } | ||
570 | } | ||
571 | |||
530 | /** | 572 | /** |
531 | * iwl_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory | 573 | * iwl_txq_ctx_stop - Stop all Tx DMA channels |
532 | */ | 574 | */ |
533 | void iwl_txq_ctx_stop(struct iwl_priv *priv) | 575 | void iwl_txq_ctx_stop(struct iwl_priv *priv) |
534 | { | 576 | { |
@@ -548,9 +590,6 @@ void iwl_txq_ctx_stop(struct iwl_priv *priv) | |||
548 | 1000); | 590 | 1000); |
549 | } | 591 | } |
550 | spin_unlock_irqrestore(&priv->lock, flags); | 592 | spin_unlock_irqrestore(&priv->lock, flags); |
551 | |||
552 | /* Deallocate memory for all Tx queues */ | ||
553 | iwl_hw_txq_ctx_free(priv); | ||
554 | } | 593 | } |
555 | EXPORT_SYMBOL(iwl_txq_ctx_stop); | 594 | EXPORT_SYMBOL(iwl_txq_ctx_stop); |
556 | 595 | ||