aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-tx.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c59
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}
434EXPORT_SYMBOL(iwl_tx_queue_init); 434EXPORT_SYMBOL(iwl_tx_queue_init);
435 435
436void 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}
454EXPORT_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)
461EXPORT_SYMBOL(iwl_hw_txq_ctx_free); 480EXPORT_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 */
470int iwl_txq_ctx_reset(struct iwl_priv *priv) 489int 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
549void 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 */
533void iwl_txq_ctx_stop(struct iwl_priv *priv) 575void 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}
555EXPORT_SYMBOL(iwl_txq_ctx_stop); 594EXPORT_SYMBOL(iwl_txq_ctx_stop);
556 595