aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/pcie/rx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/pcie/rx.c')
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c91
1 files changed, 57 insertions, 34 deletions
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index d1a61ba6247a..17c8e5d82681 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -35,10 +35,6 @@
35#include "internal.h" 35#include "internal.h"
36#include "iwl-op-mode.h" 36#include "iwl-op-mode.h"
37 37
38#ifdef CONFIG_IWLWIFI_IDI
39#include "iwl-amfh.h"
40#endif
41
42/****************************************************************************** 38/******************************************************************************
43 * 39 *
44 * RX path functions 40 * RX path functions
@@ -181,15 +177,15 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans,
181} 177}
182 178
183/** 179/**
184 * iwlagn_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr 180 * iwl_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr
185 */ 181 */
186static inline __le32 iwlagn_dma_addr2rbd_ptr(dma_addr_t dma_addr) 182static inline __le32 iwl_dma_addr2rbd_ptr(dma_addr_t dma_addr)
187{ 183{
188 return cpu_to_le32((u32)(dma_addr >> 8)); 184 return cpu_to_le32((u32)(dma_addr >> 8));
189} 185}
190 186
191/** 187/**
192 * iwlagn_rx_queue_restock - refill RX queue from pre-allocated pool 188 * iwl_rx_queue_restock - refill RX queue from pre-allocated pool
193 * 189 *
194 * If there are slots in the RX queue that need to be restocked, 190 * If there are slots in the RX queue that need to be restocked,
195 * and we have free pre-allocated buffers, fill the ranks as much 191 * and we have free pre-allocated buffers, fill the ranks as much
@@ -199,7 +195,7 @@ static inline __le32 iwlagn_dma_addr2rbd_ptr(dma_addr_t dma_addr)
199 * also updates the memory address in the firmware to reference the new 195 * also updates the memory address in the firmware to reference the new
200 * target buffer. 196 * target buffer.
201 */ 197 */
202static void iwlagn_rx_queue_restock(struct iwl_trans *trans) 198static void iwl_rx_queue_restock(struct iwl_trans *trans)
203{ 199{
204 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 200 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
205 struct iwl_rx_queue *rxq = &trans_pcie->rxq; 201 struct iwl_rx_queue *rxq = &trans_pcie->rxq;
@@ -207,6 +203,17 @@ static void iwlagn_rx_queue_restock(struct iwl_trans *trans)
207 struct iwl_rx_mem_buffer *rxb; 203 struct iwl_rx_mem_buffer *rxb;
208 unsigned long flags; 204 unsigned long flags;
209 205
206 /*
207 * If the device isn't enabled - not need to try to add buffers...
208 * This can happen when we stop the device and still have an interrupt
209 * pending. We stop the APM before we sync the interrupts / tasklets
210 * because we have to (see comment there). On the other hand, since
211 * the APM is stopped, we cannot access the HW (in particular not prph).
212 * So don't try to restock if the APM has been already stopped.
213 */
214 if (!test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status))
215 return;
216
210 spin_lock_irqsave(&rxq->lock, flags); 217 spin_lock_irqsave(&rxq->lock, flags);
211 while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) { 218 while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
212 /* The overwritten rxb must be a used one */ 219 /* The overwritten rxb must be a used one */
@@ -219,7 +226,7 @@ static void iwlagn_rx_queue_restock(struct iwl_trans *trans)
219 list_del(element); 226 list_del(element);
220 227
221 /* Point to Rx buffer via next RBD in circular buffer */ 228 /* Point to Rx buffer via next RBD in circular buffer */
222 rxq->bd[rxq->write] = iwlagn_dma_addr2rbd_ptr(rxb->page_dma); 229 rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(rxb->page_dma);
223 rxq->queue[rxq->write] = rxb; 230 rxq->queue[rxq->write] = rxb;
224 rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; 231 rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
225 rxq->free_count--; 232 rxq->free_count--;
@@ -230,7 +237,6 @@ static void iwlagn_rx_queue_restock(struct iwl_trans *trans)
230 if (rxq->free_count <= RX_LOW_WATERMARK) 237 if (rxq->free_count <= RX_LOW_WATERMARK)
231 schedule_work(&trans_pcie->rx_replenish); 238 schedule_work(&trans_pcie->rx_replenish);
232 239
233
234 /* If we've added more space for the firmware to place data, tell it. 240 /* If we've added more space for the firmware to place data, tell it.
235 * Increment device's write pointer in multiples of 8. */ 241 * Increment device's write pointer in multiples of 8. */
236 if (rxq->write_actual != (rxq->write & ~0x7)) { 242 if (rxq->write_actual != (rxq->write & ~0x7)) {
@@ -241,15 +247,16 @@ static void iwlagn_rx_queue_restock(struct iwl_trans *trans)
241 } 247 }
242} 248}
243 249
244/** 250/*
245 * iwlagn_rx_replenish - Move all used packet from rx_used to rx_free 251 * iwl_rx_allocate - allocate a page for each used RBD
246 *
247 * When moving to rx_free an SKB is allocated for the slot.
248 * 252 *
249 * Also restock the Rx queue via iwl_rx_queue_restock. 253 * A used RBD is an Rx buffer that has been given to the stack. To use it again
250 * This is called as a scheduled work item (except for during initialization) 254 * a page must be allocated and the RBD must point to the page. This function
255 * doesn't change the HW pointer but handles the list of pages that is used by
256 * iwl_rx_queue_restock. The latter function will update the HW to use the newly
257 * allocated buffers.
251 */ 258 */
252static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority) 259static void iwl_rx_allocate(struct iwl_trans *trans, gfp_t priority)
253{ 260{
254 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 261 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
255 struct iwl_rx_queue *rxq = &trans_pcie->rxq; 262 struct iwl_rx_queue *rxq = &trans_pcie->rxq;
@@ -328,23 +335,31 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority)
328 } 335 }
329} 336}
330 337
331void iwlagn_rx_replenish(struct iwl_trans *trans) 338/*
339 * iwl_rx_replenish - Move all used buffers from rx_used to rx_free
340 *
341 * When moving to rx_free an page is allocated for the slot.
342 *
343 * Also restock the Rx queue via iwl_rx_queue_restock.
344 * This is called as a scheduled work item (except for during initialization)
345 */
346void iwl_rx_replenish(struct iwl_trans *trans)
332{ 347{
333 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 348 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
334 unsigned long flags; 349 unsigned long flags;
335 350
336 iwlagn_rx_allocate(trans, GFP_KERNEL); 351 iwl_rx_allocate(trans, GFP_KERNEL);
337 352
338 spin_lock_irqsave(&trans_pcie->irq_lock, flags); 353 spin_lock_irqsave(&trans_pcie->irq_lock, flags);
339 iwlagn_rx_queue_restock(trans); 354 iwl_rx_queue_restock(trans);
340 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 355 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
341} 356}
342 357
343static void iwlagn_rx_replenish_now(struct iwl_trans *trans) 358static void iwl_rx_replenish_now(struct iwl_trans *trans)
344{ 359{
345 iwlagn_rx_allocate(trans, GFP_ATOMIC); 360 iwl_rx_allocate(trans, GFP_ATOMIC);
346 361
347 iwlagn_rx_queue_restock(trans); 362 iwl_rx_queue_restock(trans);
348} 363}
349 364
350void iwl_bg_rx_replenish(struct work_struct *data) 365void iwl_bg_rx_replenish(struct work_struct *data)
@@ -352,7 +367,7 @@ void iwl_bg_rx_replenish(struct work_struct *data)
352 struct iwl_trans_pcie *trans_pcie = 367 struct iwl_trans_pcie *trans_pcie =
353 container_of(data, struct iwl_trans_pcie, rx_replenish); 368 container_of(data, struct iwl_trans_pcie, rx_replenish);
354 369
355 iwlagn_rx_replenish(trans_pcie->trans); 370 iwl_rx_replenish(trans_pcie->trans);
356} 371}
357 372
358static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, 373static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
@@ -421,13 +436,23 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
421 index = SEQ_TO_INDEX(sequence); 436 index = SEQ_TO_INDEX(sequence);
422 cmd_index = get_cmd_index(&txq->q, index); 437 cmd_index = get_cmd_index(&txq->q, index);
423 438
424 if (reclaim) 439 if (reclaim) {
425 cmd = txq->entries[cmd_index].cmd; 440 struct iwl_pcie_tx_queue_entry *ent;
426 else 441 ent = &txq->entries[cmd_index];
442 cmd = ent->copy_cmd;
443 WARN_ON_ONCE(!cmd && ent->meta.flags & CMD_WANT_HCMD);
444 } else {
427 cmd = NULL; 445 cmd = NULL;
446 }
428 447
429 err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); 448 err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd);
430 449
450 if (reclaim) {
451 /* The original command isn't needed any more */
452 kfree(txq->entries[cmd_index].copy_cmd);
453 txq->entries[cmd_index].copy_cmd = NULL;
454 }
455
431 /* 456 /*
432 * After here, we should always check rxcb._page_stolen, 457 * After here, we should always check rxcb._page_stolen,
433 * if it is true then one of the handlers took the page. 458 * if it is true then one of the handlers took the page.
@@ -520,7 +545,7 @@ static void iwl_rx_handle(struct iwl_trans *trans)
520 count++; 545 count++;
521 if (count >= 8) { 546 if (count >= 8) {
522 rxq->read = i; 547 rxq->read = i;
523 iwlagn_rx_replenish_now(trans); 548 iwl_rx_replenish_now(trans);
524 count = 0; 549 count = 0;
525 } 550 }
526 } 551 }
@@ -529,9 +554,9 @@ static void iwl_rx_handle(struct iwl_trans *trans)
529 /* Backtrack one entry */ 554 /* Backtrack one entry */
530 rxq->read = i; 555 rxq->read = i;
531 if (fill_rx) 556 if (fill_rx)
532 iwlagn_rx_replenish_now(trans); 557 iwl_rx_replenish_now(trans);
533 else 558 else
534 iwlagn_rx_queue_restock(trans); 559 iwl_rx_queue_restock(trans);
535} 560}
536 561
537/** 562/**
@@ -713,11 +738,9 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
713 /* Disable periodic interrupt; we use it as just a one-shot. */ 738 /* Disable periodic interrupt; we use it as just a one-shot. */
714 iwl_write8(trans, CSR_INT_PERIODIC_REG, 739 iwl_write8(trans, CSR_INT_PERIODIC_REG,
715 CSR_INT_PERIODIC_DIS); 740 CSR_INT_PERIODIC_DIS);
716#ifdef CONFIG_IWLWIFI_IDI 741
717 iwl_amfh_rx_handler();
718#else
719 iwl_rx_handle(trans); 742 iwl_rx_handle(trans);
720#endif 743
721 /* 744 /*
722 * Enable periodic interrupt in 8 msec only if we received 745 * Enable periodic interrupt in 8 msec only if we received
723 * real RX interrupt (instead of just periodic int), to catch 746 * real RX interrupt (instead of just periodic int), to catch