iwl3945: Use iwlcore TX queue management routines
[linux-2.6-block.git] / drivers / net / wireless / iwlwifi / iwl3945-base.c
index bc10e2ae597d1adca0d1eec81145c24a0c079719..14f95238059a192be42324442a8e81bf959c5107 100644 (file)
@@ -93,210 +93,6 @@ struct iwl_mod_params iwl3945_mod_params = {
        /* the rest are 0 by default */
 };
 
-/*************** DMA-QUEUE-GENERAL-FUNCTIONS  *****
- * DMA services
- *
- * Theory of operation
- *
- * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer
- * of buffer descriptors, each of which points to one or more data buffers for
- * the device to read from or fill.  Driver and device exchange status of each
- * queue via "read" and "write" pointers.  Driver keeps minimum of 2 empty
- * entries in each circular buffer, to protect against confusing empty and full
- * queue states.
- *
- * The device reads or writes the data in the queues via the device's several
- * DMA/FIFO channels.  Each queue is mapped to a single DMA channel.
- *
- * For Tx queue, there are low mark and high mark limits. If, after queuing
- * the packet for Tx, free space become < low mark, Tx queue stopped. When
- * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
- * Tx queue resumed.
- *
- * The 3945 operates with six queues:  One receive queue, one transmit queue
- * (#4) for sending commands to the device firmware, and four transmit queues
- * (#0-3) for data tx via EDCA.  An additional 2 HCCA queues are unused.
- ***************************************************/
-
-/**
- * iwl3945_queue_init - Initialize queue's high/low-water and read/write indexes
- */
-static int iwl3945_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
-                         int count, int slots_num, u32 id)
-{
-       q->n_bd = count;
-       q->n_window = slots_num;
-       q->id = id;
-
-       /* count must be power-of-two size, otherwise iwl_queue_inc_wrap
-        * and iwl_queue_dec_wrap are broken. */
-       BUG_ON(!is_power_of_2(count));
-
-       /* slots_num must be power-of-two size, otherwise
-        * get_cmd_index is broken. */
-       BUG_ON(!is_power_of_2(slots_num));
-
-       q->low_mark = q->n_window / 4;
-       if (q->low_mark < 4)
-               q->low_mark = 4;
-
-       q->high_mark = q->n_window / 8;
-       if (q->high_mark < 2)
-               q->high_mark = 2;
-
-       q->write_ptr = q->read_ptr = 0;
-
-       return 0;
-}
-
-/**
- * iwl3945_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue
- */
-static int iwl3945_tx_queue_alloc(struct iwl_priv *priv,
-                             struct iwl_tx_queue *txq, u32 id)
-{
-       struct pci_dev *dev = priv->pci_dev;
-
-       /* Driver private data, only for Tx (not command) queues,
-        * not shared with device. */
-       if (id != IWL_CMD_QUEUE_NUM) {
-               txq->txb = kmalloc(sizeof(txq->txb[0]) *
-                                  TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
-               if (!txq->txb) {
-                       IWL_ERR(priv, "kmalloc for auxiliary BD "
-                                 "structures failed\n");
-                       goto error;
-               }
-       } else
-               txq->txb = NULL;
-
-       /* Circular buffer of transmit frame descriptors (TFDs),
-        * shared with device */
-       txq->tfds = pci_alloc_consistent(dev,
-                               sizeof(struct iwl3945_tfd) * TFD_QUEUE_SIZE_MAX,
-                               &txq->q.dma_addr);
-
-       if (!txq->tfds) {
-               IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n",
-                         sizeof(struct iwl3945_tfd) * TFD_QUEUE_SIZE_MAX);
-               goto error;
-       }
-       txq->q.id = id;
-
-       return 0;
-
- error:
-       kfree(txq->txb);
-       txq->txb = NULL;
-
-       return -ENOMEM;
-}
-
-/**
- * iwl3945_tx_queue_init - Allocate and initialize one tx/cmd queue
- */
-int iwl3945_tx_queue_init(struct iwl_priv *priv,
-                     struct iwl_tx_queue *txq, int slots_num, u32 txq_id)
-{
-       int len, i;
-       int rc = 0;
-
-       /*
-        * Alloc buffer array for commands (Tx or other types of commands).
-        * For the command queue (#4), allocate command space + one big
-        * command for scan, since scan command is very huge; the system will
-        * not have two scans at the same time, so only one is needed.
-        * For data Tx queues (all other queues), no super-size command
-        * space is needed.
-        */
-       len = sizeof(struct iwl_cmd);
-       for (i = 0; i <= slots_num; i++) {
-               if (i == slots_num) {
-                       if (txq_id == IWL_CMD_QUEUE_NUM)
-                               len += IWL_MAX_SCAN_SIZE;
-                       else
-                               continue;
-               }
-
-               txq->cmd[i] = kmalloc(len, GFP_KERNEL);
-               if (!txq->cmd[i])
-                       goto err;
-       }
-
-       /* Alloc driver data array and TFD circular buffer */
-       rc = iwl3945_tx_queue_alloc(priv, txq, txq_id);
-       if (rc)
-               goto err;
-
-       txq->need_update = 0;
-
-       /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
-        * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
-       BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
-
-       /* Initialize queue high/low-water, head/tail indexes */
-       iwl3945_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
-
-       /* Tell device where to find queue, enable DMA channel. */
-       iwl3945_hw_tx_queue_init(priv, txq);
-
-       return 0;
-err:
-       for (i = 0; i < slots_num; i++) {
-               kfree(txq->cmd[i]);
-               txq->cmd[i] = NULL;
-       }
-
-       if (txq_id == IWL_CMD_QUEUE_NUM) {
-               kfree(txq->cmd[slots_num]);
-               txq->cmd[slots_num] = NULL;
-       }
-       return -ENOMEM;
-}
-
-/**
- * iwl3945_tx_queue_free - Deallocate DMA queue.
- * @txq: Transmit queue to deallocate.
- *
- * Empty queue by removing and destroying all BD's.
- * Free all buffers.
- * 0-fill, but do not free "txq" descriptor structure.
- */
-void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq)
-{
-       struct iwl_queue *q = &txq->q;
-       struct pci_dev *dev = priv->pci_dev;
-       int len, i;
-
-       if (q->n_bd == 0)
-               return;
-
-       /* first, empty all BD's */
-       for (; q->write_ptr != q->read_ptr;
-            q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
-               priv->cfg->ops->lib->txq_free_tfd(priv, txq);
-
-       len = sizeof(struct iwl_cmd) * q->n_window;
-       if (q->id == IWL_CMD_QUEUE_NUM)
-               len += IWL_MAX_SCAN_SIZE;
-
-       /* De-alloc array of command/tx buffers */
-       for (i = 0; i < TFD_TX_CMD_SLOTS; i++)
-               kfree(txq->cmd[i]);
-
-       /* De-alloc circular buffer of TFDs */
-       if (txq->q.n_bd)
-               pci_free_consistent(dev, sizeof(struct iwl3945_tfd) *
-                                   txq->q.n_bd, txq->tfds, txq->q.dma_addr);
-
-       /* De-alloc array of per-TFD driver data */
-       kfree(txq->txb);
-       txq->txb = NULL;
-
-       /* 0-fill queue descriptor structure */
-       memset(txq, 0, sizeof(*txq));
-}
-
 /*************** STATION TABLE MANAGEMENT ****
  * mac80211 should be examined to determine if sta_info is duplicating
  * the functionality provided here