iwlwifi: move rx queue read pointer into rxq
[deliverable/linux.git] / drivers / net / wireless / iwlwifi / iwl-rx.c
index 7cde9d76ff5df438b335996f1b602cf4e14dd9dc..48d55741b769437723c8e58a718126aeaaedd849 100644 (file)
@@ -204,7 +204,7 @@ int iwl_rx_queue_restock(struct iwl_priv *priv)
                list_del(element);
 
                /* Point to Rx buffer via next RBD in circular buffer */
-               rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(priv, rxb->dma_addr);
+               rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(priv, rxb->aligned_dma_addr);
                rxq->queue[rxq->write] = rxb;
                rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
                rxq->free_count--;
@@ -251,7 +251,7 @@ void iwl_rx_allocate(struct iwl_priv *priv)
                rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
 
                /* Alloc a new receive buffer */
-               rxb->skb = alloc_skb(priv->hw_params.rx_buf_size,
+               rxb->skb = alloc_skb(priv->hw_params.rx_buf_size + 256,
                                __GFP_NOWARN | GFP_ATOMIC);
                if (!rxb->skb) {
                        if (net_ratelimit())
@@ -266,9 +266,17 @@ void iwl_rx_allocate(struct iwl_priv *priv)
                list_del(element);
 
                /* Get physical address of RB/SKB */
-               rxb->dma_addr =
-                   pci_map_single(priv->pci_dev, rxb->skb->data,
-                          priv->hw_params.rx_buf_size, PCI_DMA_FROMDEVICE);
+               rxb->real_dma_addr = pci_map_single(
+                                       priv->pci_dev,
+                                       rxb->skb->data,
+                                       priv->hw_params.rx_buf_size + 256,
+                                       PCI_DMA_FROMDEVICE);
+               /* dma address must be no more than 36 bits */
+               BUG_ON(rxb->real_dma_addr & ~DMA_BIT_MASK(36));
+               /* and also 256 byte aligned! */
+               rxb->aligned_dma_addr = ALIGN(rxb->real_dma_addr, 256);
+               skb_reserve(rxb->skb, rxb->aligned_dma_addr - rxb->real_dma_addr);
+
                list_add_tail(&rxb->list, &rxq->rx_free);
                rxq->free_count++;
        }
@@ -300,8 +308,8 @@ void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
        for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
                if (rxq->pool[i].skb != NULL) {
                        pci_unmap_single(priv->pci_dev,
-                                        rxq->pool[i].dma_addr,
-                                        priv->hw_params.rx_buf_size,
+                                        rxq->pool[i].real_dma_addr,
+                                        priv->hw_params.rx_buf_size + 256,
                                         PCI_DMA_FROMDEVICE);
                        dev_kfree_skb(rxq->pool[i].skb);
                }
@@ -309,7 +317,10 @@ void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
 
        pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,
                            rxq->dma_addr);
+       pci_free_consistent(priv->pci_dev, sizeof(struct iwl_rb_status),
+                           rxq->rb_stts, rxq->rb_stts_dma);
        rxq->bd = NULL;
+       rxq->rb_stts  = NULL;
 }
 EXPORT_SYMBOL(iwl_rx_queue_free);
 
@@ -326,7 +337,12 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv)
        /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */
        rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr);
        if (!rxq->bd)
-               return -ENOMEM;
+               goto err_bd;
+
+       rxq->rb_stts = pci_alloc_consistent(dev, sizeof(struct iwl_rb_status),
+                                       &rxq->rb_stts_dma);
+       if (!rxq->rb_stts)
+               goto err_rb;
 
        /* Fill the rx_used queue with _all_ of the Rx buffers */
        for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
@@ -338,6 +354,12 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv)
        rxq->free_count = 0;
        rxq->need_update = 0;
        return 0;
+
+err_rb:
+       pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,
+                           rxq->dma_addr);
+err_bd:
+       return -ENOMEM;
 }
 EXPORT_SYMBOL(iwl_rx_queue_alloc);
 
@@ -354,8 +376,8 @@ void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
                 * to an SKB, so we need to unmap and free potential storage */
                if (rxq->pool[i].skb != NULL) {
                        pci_unmap_single(priv->pci_dev,
-                                        rxq->pool[i].dma_addr,
-                                        priv->hw_params.rx_buf_size,
+                                        rxq->pool[i].real_dma_addr,
+                                        priv->hw_params.rx_buf_size + 256,
                                         PCI_DMA_FROMDEVICE);
                        priv->alloc_rxb_skb--;
                        dev_kfree_skb(rxq->pool[i].skb);
@@ -404,10 +426,10 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
 
        /* Tell device where in DRAM to update its Rx status */
        iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG,
-                          (priv->shared_phys + priv->rb_closed_offset) >> 4);
+                          rxq->rb_stts_dma >> 4);
 
        /* Enable Rx DMA
-        * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set becuase of HW bug in
+        * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in
         *      the credit mechanism in 5000 HW RX FIFO
         * Direct rx interrupts to hosts
         * Rx buffer size 4 or 8k
@@ -1149,7 +1171,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
                priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
 
        /* Set "1" to report good data frames in groups of 100 */
-       /* FIXME: need to optimze the call: */
+       /* FIXME: need to optimize the call: */
        iwl_dbg_report_frame(priv, pkt, header, 1);
 
        IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n",
@@ -1160,12 +1182,12 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
         * "antenna number"
         *
         * It seems that the antenna field in the phy flags value
-        * is actually a bitfield. This is undefined by radiotap,
+        * is actually a bit field. This is undefined by radiotap,
         * it wants an actual antenna number but I always get "7"
         * for most legacy frames I receive indicating that the
         * same frame was received on all three RX chains.
         *
-        * I think this field should be removed in favour of a
+        * I think this field should be removed in favor of a
         * new 802.11n radiotap field "RX chains" that is defined
         * as a bitmask.
         */
This page took 0.026975 seconds and 5 git commands to generate.