diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-rx.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-rx.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index b3c35c64d042..876afd4cab9e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -218,8 +218,7 @@ int iwl_rx_queue_restock(struct iwl_priv *priv) | |||
218 | 218 | ||
219 | /* If we've added more space for the firmware to place data, tell it. | 219 | /* If we've added more space for the firmware to place data, tell it. |
220 | * Increment device's write pointer in multiples of 8. */ | 220 | * Increment device's write pointer in multiples of 8. */ |
221 | if ((write != (rxq->write & ~0x7)) | 221 | if (write != (rxq->write & ~0x7)) { |
222 | || (abs(rxq->write - rxq->read) > 7)) { | ||
223 | spin_lock_irqsave(&rxq->lock, flags); | 222 | spin_lock_irqsave(&rxq->lock, flags); |
224 | rxq->need_update = 1; | 223 | rxq->need_update = 1; |
225 | spin_unlock_irqrestore(&rxq->lock, flags); | 224 | spin_unlock_irqrestore(&rxq->lock, flags); |
@@ -317,7 +316,10 @@ void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
317 | 316 | ||
318 | pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd, | 317 | pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd, |
319 | rxq->dma_addr); | 318 | rxq->dma_addr); |
319 | pci_free_consistent(priv->pci_dev, sizeof(struct iwl_rb_status), | ||
320 | rxq->rb_stts, rxq->rb_stts_dma); | ||
320 | rxq->bd = NULL; | 321 | rxq->bd = NULL; |
322 | rxq->rb_stts = NULL; | ||
321 | } | 323 | } |
322 | EXPORT_SYMBOL(iwl_rx_queue_free); | 324 | EXPORT_SYMBOL(iwl_rx_queue_free); |
323 | 325 | ||
@@ -334,7 +336,12 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv) | |||
334 | /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ | 336 | /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ |
335 | rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr); | 337 | rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr); |
336 | if (!rxq->bd) | 338 | if (!rxq->bd) |
337 | return -ENOMEM; | 339 | goto err_bd; |
340 | |||
341 | rxq->rb_stts = pci_alloc_consistent(dev, sizeof(struct iwl_rb_status), | ||
342 | &rxq->rb_stts_dma); | ||
343 | if (!rxq->rb_stts) | ||
344 | goto err_rb; | ||
338 | 345 | ||
339 | /* Fill the rx_used queue with _all_ of the Rx buffers */ | 346 | /* Fill the rx_used queue with _all_ of the Rx buffers */ |
340 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) | 347 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) |
@@ -346,6 +353,12 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv) | |||
346 | rxq->free_count = 0; | 353 | rxq->free_count = 0; |
347 | rxq->need_update = 0; | 354 | rxq->need_update = 0; |
348 | return 0; | 355 | return 0; |
356 | |||
357 | err_rb: | ||
358 | pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd, | ||
359 | rxq->dma_addr); | ||
360 | err_bd: | ||
361 | return -ENOMEM; | ||
349 | } | 362 | } |
350 | EXPORT_SYMBOL(iwl_rx_queue_alloc); | 363 | EXPORT_SYMBOL(iwl_rx_queue_alloc); |
351 | 364 | ||
@@ -412,7 +425,7 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
412 | 425 | ||
413 | /* Tell device where in DRAM to update its Rx status */ | 426 | /* Tell device where in DRAM to update its Rx status */ |
414 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, | 427 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, |
415 | (priv->shared_phys + priv->rb_closed_offset) >> 4); | 428 | rxq->rb_stts_dma >> 4); |
416 | 429 | ||
417 | /* Enable Rx DMA | 430 | /* Enable Rx DMA |
418 | * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in | 431 | * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in |
@@ -426,6 +439,7 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
426 | FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | | 439 | FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | |
427 | FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | | 440 | FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | |
428 | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | | 441 | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | |
442 | FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME | | ||
429 | rb_size| | 443 | rb_size| |
430 | (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)| | 444 | (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)| |
431 | (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); | 445 | (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); |