diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-rx.c')
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-rx.c | 26 | 
1 files changed, 17 insertions, 9 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 7cde9d76ff5..0509c16dbe7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -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);  		} @@ -354,8 +362,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);  |