diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2012-11-14 07:44:18 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2012-11-19 09:02:47 -0500 |
commit | 9805c4460ae37aa9328a470c7aebea32f0667e24 (patch) | |
tree | a4d18982e3b296fc2d3019342fa226745d4922d5 /drivers | |
parent | c61259858d685caf865e9819e3d3062a0865d93c (diff) |
iwlwifi: continue clean up - pcie/rx.c
Rename static functions. Function moved from trans.c to
rx.c. A few could be made static, others had to be exported.
Also, don't use rxb or rxbuf, but rb which stands for receive
buffer.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/internal.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/rx.c | 227 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/trans.c | 196 |
3 files changed, 216 insertions, 212 deletions
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index d058ddaebd93..a71a78237b62 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h | |||
@@ -323,10 +323,11 @@ void iwl_trans_pcie_free(struct iwl_trans *trans); | |||
323 | /***************************************************** | 323 | /***************************************************** |
324 | * RX | 324 | * RX |
325 | ******************************************************/ | 325 | ******************************************************/ |
326 | void iwl_pcie_rx_replenish_work(struct work_struct *data); | 326 | int iwl_pcie_rx_init(struct iwl_trans *trans); |
327 | void iwl_pcie_rx_replenish(struct iwl_trans *trans); | ||
328 | void iwl_pcie_tasklet(struct iwl_trans *trans); | 327 | void iwl_pcie_tasklet(struct iwl_trans *trans); |
329 | void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_rxq *q); | 328 | void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_rxq *q); |
329 | int iwl_pcie_rx_stop(struct iwl_trans *trans); | ||
330 | void iwl_pcie_rx_free(struct iwl_trans *trans); | ||
330 | 331 | ||
331 | /***************************************************** | 332 | /***************************************************** |
332 | * ICT - interrupt handling | 333 | * ICT - interrupt handling |
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 087d022bc93a..e3ae28d7a0da 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c | |||
@@ -123,7 +123,25 @@ static int iwl_rxq_space(const struct iwl_rxq *q) | |||
123 | } | 123 | } |
124 | 124 | ||
125 | /* | 125 | /* |
126 | * iwl_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr | ||
127 | */ | ||
128 | static inline __le32 iwl_pcie_dma_addr2rbd_ptr(dma_addr_t dma_addr) | ||
129 | { | ||
130 | return cpu_to_le32((u32)(dma_addr >> 8)); | ||
131 | } | ||
132 | |||
133 | int iwl_pcie_rx_stop(struct iwl_trans *trans) | ||
134 | { | ||
135 | |||
136 | /* stop Rx DMA */ | ||
137 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); | ||
138 | return iwl_poll_direct_bit(trans, FH_MEM_RSSR_RX_STATUS_REG, | ||
139 | FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); | ||
140 | } | ||
141 | |||
142 | /* | ||
126 | * iwl_pcie_rxq_inc_wr_ptr - Update the write pointer for the RX queue | 143 | * iwl_pcie_rxq_inc_wr_ptr - Update the write pointer for the RX queue |
144 | * TODO - could be made static | ||
127 | */ | 145 | */ |
128 | void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_rxq *q) | 146 | void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_rxq *q) |
129 | { | 147 | { |
@@ -176,14 +194,6 @@ void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_rxq *q) | |||
176 | } | 194 | } |
177 | 195 | ||
178 | /* | 196 | /* |
179 | * iwl_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr | ||
180 | */ | ||
181 | static inline __le32 iwl_dma_addr2rbd_ptr(dma_addr_t dma_addr) | ||
182 | { | ||
183 | return cpu_to_le32((u32)(dma_addr >> 8)); | ||
184 | } | ||
185 | |||
186 | /* | ||
187 | * iwl_pcie_rxq_restock - refill RX queue from pre-allocated pool | 197 | * iwl_pcie_rxq_restock - refill RX queue from pre-allocated pool |
188 | * | 198 | * |
189 | * If there are slots in the RX queue that need to be restocked, | 199 | * If there are slots in the RX queue that need to be restocked, |
@@ -224,7 +234,7 @@ static void iwl_pcie_rxq_restock(struct iwl_trans *trans) | |||
224 | list_del(&rxb->list); | 234 | list_del(&rxb->list); |
225 | 235 | ||
226 | /* Point to Rx buffer via next RBD in circular buffer */ | 236 | /* Point to Rx buffer via next RBD in circular buffer */ |
227 | rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(rxb->page_dma); | 237 | rxq->bd[rxq->write] = iwl_pcie_dma_addr2rbd_ptr(rxb->page_dma); |
228 | rxq->queue[rxq->write] = rxb; | 238 | rxq->queue[rxq->write] = rxb; |
229 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; | 239 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; |
230 | rxq->free_count--; | 240 | rxq->free_count--; |
@@ -246,7 +256,7 @@ static void iwl_pcie_rxq_restock(struct iwl_trans *trans) | |||
246 | } | 256 | } |
247 | 257 | ||
248 | /* | 258 | /* |
249 | * iwl_pcie_rx_allocate - allocate a page for each used RBD | 259 | * iwl_pcie_rxq_alloc_rbs - allocate a page for each used RBD |
250 | * | 260 | * |
251 | * A used RBD is an Rx buffer that has been given to the stack. To use it again | 261 | * A used RBD is an Rx buffer that has been given to the stack. To use it again |
252 | * a page must be allocated and the RBD must point to the page. This function | 262 | * a page must be allocated and the RBD must point to the page. This function |
@@ -254,7 +264,7 @@ static void iwl_pcie_rxq_restock(struct iwl_trans *trans) | |||
254 | * iwl_pcie_rxq_restock. The latter function will update the HW to use the newly | 264 | * iwl_pcie_rxq_restock. The latter function will update the HW to use the newly |
255 | * allocated buffers. | 265 | * allocated buffers. |
256 | */ | 266 | */ |
257 | static void iwl_pcie_rx_allocate(struct iwl_trans *trans, gfp_t priority) | 267 | static void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority) |
258 | { | 268 | { |
259 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 269 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
260 | struct iwl_rxq *rxq = &trans_pcie->rxq; | 270 | struct iwl_rxq *rxq = &trans_pcie->rxq; |
@@ -331,6 +341,28 @@ static void iwl_pcie_rx_allocate(struct iwl_trans *trans, gfp_t priority) | |||
331 | } | 341 | } |
332 | } | 342 | } |
333 | 343 | ||
344 | static void iwl_pcie_rxq_free_rbs(struct iwl_trans *trans) | ||
345 | { | ||
346 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
347 | struct iwl_rxq *rxq = &trans_pcie->rxq; | ||
348 | int i; | ||
349 | |||
350 | /* Fill the rx_used queue with _all_ of the Rx buffers */ | ||
351 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { | ||
352 | /* In the reset function, these buffers may have been allocated | ||
353 | * to an SKB, so we need to unmap and free potential storage */ | ||
354 | if (rxq->pool[i].page != NULL) { | ||
355 | dma_unmap_page(trans->dev, rxq->pool[i].page_dma, | ||
356 | PAGE_SIZE << trans_pcie->rx_page_order, | ||
357 | DMA_FROM_DEVICE); | ||
358 | __free_pages(rxq->pool[i].page, | ||
359 | trans_pcie->rx_page_order); | ||
360 | rxq->pool[i].page = NULL; | ||
361 | } | ||
362 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | ||
363 | } | ||
364 | } | ||
365 | |||
334 | /* | 366 | /* |
335 | * iwl_pcie_rx_replenish - Move all used buffers from rx_used to rx_free | 367 | * iwl_pcie_rx_replenish - Move all used buffers from rx_used to rx_free |
336 | * | 368 | * |
@@ -339,12 +371,12 @@ static void iwl_pcie_rx_allocate(struct iwl_trans *trans, gfp_t priority) | |||
339 | * Also restock the Rx queue via iwl_pcie_rxq_restock. | 371 | * Also restock the Rx queue via iwl_pcie_rxq_restock. |
340 | * This is called as a scheduled work item (except for during initialization) | 372 | * This is called as a scheduled work item (except for during initialization) |
341 | */ | 373 | */ |
342 | void iwl_pcie_rx_replenish(struct iwl_trans *trans) | 374 | static void iwl_pcie_rx_replenish(struct iwl_trans *trans) |
343 | { | 375 | { |
344 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 376 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
345 | unsigned long flags; | 377 | unsigned long flags; |
346 | 378 | ||
347 | iwl_pcie_rx_allocate(trans, GFP_KERNEL); | 379 | iwl_pcie_rxq_alloc_rbs(trans, GFP_KERNEL); |
348 | 380 | ||
349 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 381 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); |
350 | iwl_pcie_rxq_restock(trans); | 382 | iwl_pcie_rxq_restock(trans); |
@@ -353,12 +385,12 @@ void iwl_pcie_rx_replenish(struct iwl_trans *trans) | |||
353 | 385 | ||
354 | static void iwl_pcie_rx_replenish_now(struct iwl_trans *trans) | 386 | static void iwl_pcie_rx_replenish_now(struct iwl_trans *trans) |
355 | { | 387 | { |
356 | iwl_pcie_rx_allocate(trans, GFP_ATOMIC); | 388 | iwl_pcie_rxq_alloc_rbs(trans, GFP_ATOMIC); |
357 | 389 | ||
358 | iwl_pcie_rxq_restock(trans); | 390 | iwl_pcie_rxq_restock(trans); |
359 | } | 391 | } |
360 | 392 | ||
361 | void iwl_pcie_rx_replenish_work(struct work_struct *data) | 393 | static void iwl_pcie_rx_replenish_work(struct work_struct *data) |
362 | { | 394 | { |
363 | struct iwl_trans_pcie *trans_pcie = | 395 | struct iwl_trans_pcie *trans_pcie = |
364 | container_of(data, struct iwl_trans_pcie, rx_replenish); | 396 | container_of(data, struct iwl_trans_pcie, rx_replenish); |
@@ -366,7 +398,168 @@ void iwl_pcie_rx_replenish_work(struct work_struct *data) | |||
366 | iwl_pcie_rx_replenish(trans_pcie->trans); | 398 | iwl_pcie_rx_replenish(trans_pcie->trans); |
367 | } | 399 | } |
368 | 400 | ||
369 | static void iwl_pcie_rx_handle_rxbuf(struct iwl_trans *trans, | 401 | static int iwl_pcie_rx_alloc(struct iwl_trans *trans) |
402 | { | ||
403 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
404 | struct iwl_rxq *rxq = &trans_pcie->rxq; | ||
405 | struct device *dev = trans->dev; | ||
406 | |||
407 | memset(&trans_pcie->rxq, 0, sizeof(trans_pcie->rxq)); | ||
408 | |||
409 | spin_lock_init(&rxq->lock); | ||
410 | |||
411 | if (WARN_ON(rxq->bd || rxq->rb_stts)) | ||
412 | return -EINVAL; | ||
413 | |||
414 | /* Allocate the circular buffer of Read Buffer Descriptors (RBDs) */ | ||
415 | rxq->bd = dma_zalloc_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, | ||
416 | &rxq->bd_dma, GFP_KERNEL); | ||
417 | if (!rxq->bd) | ||
418 | goto err_bd; | ||
419 | |||
420 | /*Allocate the driver's pointer to receive buffer status */ | ||
421 | rxq->rb_stts = dma_zalloc_coherent(dev, sizeof(*rxq->rb_stts), | ||
422 | &rxq->rb_stts_dma, GFP_KERNEL); | ||
423 | if (!rxq->rb_stts) | ||
424 | goto err_rb_stts; | ||
425 | |||
426 | return 0; | ||
427 | |||
428 | err_rb_stts: | ||
429 | dma_free_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, | ||
430 | rxq->bd, rxq->bd_dma); | ||
431 | memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); | ||
432 | rxq->bd = NULL; | ||
433 | err_bd: | ||
434 | return -ENOMEM; | ||
435 | } | ||
436 | |||
437 | static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq) | ||
438 | { | ||
439 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
440 | u32 rb_size; | ||
441 | const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ | ||
442 | |||
443 | /* FIXME: RX_RB_TIMEOUT for all devices? */ | ||
444 | u32 rb_timeout = RX_RB_TIMEOUT; | ||
445 | |||
446 | if (trans_pcie->rx_buf_size_8k) | ||
447 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; | ||
448 | else | ||
449 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; | ||
450 | |||
451 | /* Stop Rx DMA */ | ||
452 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); | ||
453 | |||
454 | /* Reset driver's Rx queue write index */ | ||
455 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); | ||
456 | |||
457 | /* Tell device where to find RBD circular buffer in DRAM */ | ||
458 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_BASE_REG, | ||
459 | (u32)(rxq->bd_dma >> 8)); | ||
460 | |||
461 | /* Tell device where in DRAM to update its Rx status */ | ||
462 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_STTS_WPTR_REG, | ||
463 | rxq->rb_stts_dma >> 4); | ||
464 | |||
465 | /* Enable Rx DMA | ||
466 | * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in | ||
467 | * the credit mechanism in 5000 HW RX FIFO | ||
468 | * Direct rx interrupts to hosts | ||
469 | * Rx buffer size 4 or 8k | ||
470 | * RB timeout 0x10 | ||
471 | * 256 RBDs | ||
472 | */ | ||
473 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, | ||
474 | FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | | ||
475 | FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | | ||
476 | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | | ||
477 | rb_size| | ||
478 | (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)| | ||
479 | (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); | ||
480 | |||
481 | /* Set interrupt coalescing timer to default (2048 usecs) */ | ||
482 | iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); | ||
483 | } | ||
484 | |||
485 | int iwl_pcie_rx_init(struct iwl_trans *trans) | ||
486 | { | ||
487 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
488 | struct iwl_rxq *rxq = &trans_pcie->rxq; | ||
489 | |||
490 | int i, err; | ||
491 | unsigned long flags; | ||
492 | |||
493 | if (!rxq->bd) { | ||
494 | err = iwl_pcie_rx_alloc(trans); | ||
495 | if (err) | ||
496 | return err; | ||
497 | } | ||
498 | |||
499 | spin_lock_irqsave(&rxq->lock, flags); | ||
500 | INIT_LIST_HEAD(&rxq->rx_free); | ||
501 | INIT_LIST_HEAD(&rxq->rx_used); | ||
502 | |||
503 | INIT_WORK(&trans_pcie->rx_replenish, | ||
504 | iwl_pcie_rx_replenish_work); | ||
505 | |||
506 | iwl_pcie_rxq_free_rbs(trans); | ||
507 | |||
508 | for (i = 0; i < RX_QUEUE_SIZE; i++) | ||
509 | rxq->queue[i] = NULL; | ||
510 | |||
511 | /* Set us so that we have processed and used all buffers, but have | ||
512 | * not restocked the Rx queue with fresh buffers */ | ||
513 | rxq->read = rxq->write = 0; | ||
514 | rxq->write_actual = 0; | ||
515 | rxq->free_count = 0; | ||
516 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
517 | |||
518 | iwl_pcie_rx_replenish(trans); | ||
519 | |||
520 | iwl_pcie_rx_hw_init(trans, rxq); | ||
521 | |||
522 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | ||
523 | rxq->need_update = 1; | ||
524 | iwl_pcie_rxq_inc_wr_ptr(trans, rxq); | ||
525 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | ||
526 | |||
527 | return 0; | ||
528 | } | ||
529 | |||
530 | void iwl_pcie_rx_free(struct iwl_trans *trans) | ||
531 | { | ||
532 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
533 | struct iwl_rxq *rxq = &trans_pcie->rxq; | ||
534 | unsigned long flags; | ||
535 | |||
536 | /*if rxq->bd is NULL, it means that nothing has been allocated, | ||
537 | * exit now */ | ||
538 | if (!rxq->bd) { | ||
539 | IWL_DEBUG_INFO(trans, "Free NULL rx context\n"); | ||
540 | return; | ||
541 | } | ||
542 | |||
543 | spin_lock_irqsave(&rxq->lock, flags); | ||
544 | iwl_pcie_rxq_free_rbs(trans); | ||
545 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
546 | |||
547 | dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE, | ||
548 | rxq->bd, rxq->bd_dma); | ||
549 | memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); | ||
550 | rxq->bd = NULL; | ||
551 | |||
552 | if (rxq->rb_stts) | ||
553 | dma_free_coherent(trans->dev, | ||
554 | sizeof(struct iwl_rb_status), | ||
555 | rxq->rb_stts, rxq->rb_stts_dma); | ||
556 | else | ||
557 | IWL_DEBUG_INFO(trans, "Free rxq->rb_stts which is NULL\n"); | ||
558 | memset(&rxq->rb_stts_dma, 0, sizeof(rxq->rb_stts_dma)); | ||
559 | rxq->rb_stts = NULL; | ||
560 | } | ||
561 | |||
562 | static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, | ||
370 | struct iwl_rx_mem_buffer *rxb) | 563 | struct iwl_rx_mem_buffer *rxb) |
371 | { | 564 | { |
372 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 565 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
@@ -531,7 +724,7 @@ static void iwl_pcie_rx_handle(struct iwl_trans *trans) | |||
531 | 724 | ||
532 | IWL_DEBUG_RX(trans, "rxbuf: HW = %d, SW = %d (%p)\n", | 725 | IWL_DEBUG_RX(trans, "rxbuf: HW = %d, SW = %d (%p)\n", |
533 | r, i, rxb); | 726 | r, i, rxb); |
534 | iwl_pcie_rx_handle_rxbuf(trans, rxb); | 727 | iwl_pcie_rx_handle_rb(trans, rxb); |
535 | 728 | ||
536 | i = (i + 1) & RX_QUEUE_MASK; | 729 | i = (i + 1) & RX_QUEUE_MASK; |
537 | /* If there are a lot of unused frames, | 730 | /* If there are a lot of unused frames, |
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index a2cdb934df61..8a9cde5fa1e8 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -81,196 +81,6 @@ | |||
81 | (((1<<trans->cfg->base_params->num_of_queues) - 1) &\ | 81 | (((1<<trans->cfg->base_params->num_of_queues) - 1) &\ |
82 | (~(1<<(trans_pcie)->cmd_queue))) | 82 | (~(1<<(trans_pcie)->cmd_queue))) |
83 | 83 | ||
84 | static int iwl_trans_rx_alloc(struct iwl_trans *trans) | ||
85 | { | ||
86 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
87 | struct iwl_rxq *rxq = &trans_pcie->rxq; | ||
88 | struct device *dev = trans->dev; | ||
89 | |||
90 | memset(&trans_pcie->rxq, 0, sizeof(trans_pcie->rxq)); | ||
91 | |||
92 | spin_lock_init(&rxq->lock); | ||
93 | |||
94 | if (WARN_ON(rxq->bd || rxq->rb_stts)) | ||
95 | return -EINVAL; | ||
96 | |||
97 | /* Allocate the circular buffer of Read Buffer Descriptors (RBDs) */ | ||
98 | rxq->bd = dma_zalloc_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, | ||
99 | &rxq->bd_dma, GFP_KERNEL); | ||
100 | if (!rxq->bd) | ||
101 | goto err_bd; | ||
102 | |||
103 | /*Allocate the driver's pointer to receive buffer status */ | ||
104 | rxq->rb_stts = dma_zalloc_coherent(dev, sizeof(*rxq->rb_stts), | ||
105 | &rxq->rb_stts_dma, GFP_KERNEL); | ||
106 | if (!rxq->rb_stts) | ||
107 | goto err_rb_stts; | ||
108 | |||
109 | return 0; | ||
110 | |||
111 | err_rb_stts: | ||
112 | dma_free_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, | ||
113 | rxq->bd, rxq->bd_dma); | ||
114 | memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); | ||
115 | rxq->bd = NULL; | ||
116 | err_bd: | ||
117 | return -ENOMEM; | ||
118 | } | ||
119 | |||
120 | static void iwl_trans_rxq_free_rx_bufs(struct iwl_trans *trans) | ||
121 | { | ||
122 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
123 | struct iwl_rxq *rxq = &trans_pcie->rxq; | ||
124 | int i; | ||
125 | |||
126 | /* Fill the rx_used queue with _all_ of the Rx buffers */ | ||
127 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { | ||
128 | /* In the reset function, these buffers may have been allocated | ||
129 | * to an SKB, so we need to unmap and free potential storage */ | ||
130 | if (rxq->pool[i].page != NULL) { | ||
131 | dma_unmap_page(trans->dev, rxq->pool[i].page_dma, | ||
132 | PAGE_SIZE << trans_pcie->rx_page_order, | ||
133 | DMA_FROM_DEVICE); | ||
134 | __free_pages(rxq->pool[i].page, | ||
135 | trans_pcie->rx_page_order); | ||
136 | rxq->pool[i].page = NULL; | ||
137 | } | ||
138 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | ||
139 | } | ||
140 | } | ||
141 | |||
142 | static void iwl_trans_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq) | ||
143 | { | ||
144 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
145 | u32 rb_size; | ||
146 | const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ | ||
147 | u32 rb_timeout = RX_RB_TIMEOUT; /* FIXME: RX_RB_TIMEOUT for all devices? */ | ||
148 | |||
149 | if (trans_pcie->rx_buf_size_8k) | ||
150 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; | ||
151 | else | ||
152 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; | ||
153 | |||
154 | /* Stop Rx DMA */ | ||
155 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); | ||
156 | |||
157 | /* Reset driver's Rx queue write index */ | ||
158 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); | ||
159 | |||
160 | /* Tell device where to find RBD circular buffer in DRAM */ | ||
161 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_BASE_REG, | ||
162 | (u32)(rxq->bd_dma >> 8)); | ||
163 | |||
164 | /* Tell device where in DRAM to update its Rx status */ | ||
165 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_STTS_WPTR_REG, | ||
166 | rxq->rb_stts_dma >> 4); | ||
167 | |||
168 | /* Enable Rx DMA | ||
169 | * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in | ||
170 | * the credit mechanism in 5000 HW RX FIFO | ||
171 | * Direct rx interrupts to hosts | ||
172 | * Rx buffer size 4 or 8k | ||
173 | * RB timeout 0x10 | ||
174 | * 256 RBDs | ||
175 | */ | ||
176 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, | ||
177 | FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | | ||
178 | FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | | ||
179 | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | | ||
180 | rb_size| | ||
181 | (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)| | ||
182 | (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); | ||
183 | |||
184 | /* Set interrupt coalescing timer to default (2048 usecs) */ | ||
185 | iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); | ||
186 | } | ||
187 | |||
188 | static int iwl_rx_init(struct iwl_trans *trans) | ||
189 | { | ||
190 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
191 | struct iwl_rxq *rxq = &trans_pcie->rxq; | ||
192 | |||
193 | int i, err; | ||
194 | unsigned long flags; | ||
195 | |||
196 | if (!rxq->bd) { | ||
197 | err = iwl_trans_rx_alloc(trans); | ||
198 | if (err) | ||
199 | return err; | ||
200 | } | ||
201 | |||
202 | spin_lock_irqsave(&rxq->lock, flags); | ||
203 | INIT_LIST_HEAD(&rxq->rx_free); | ||
204 | INIT_LIST_HEAD(&rxq->rx_used); | ||
205 | |||
206 | INIT_WORK(&trans_pcie->rx_replenish, | ||
207 | iwl_pcie_rx_replenish_work); | ||
208 | |||
209 | iwl_trans_rxq_free_rx_bufs(trans); | ||
210 | |||
211 | for (i = 0; i < RX_QUEUE_SIZE; i++) | ||
212 | rxq->queue[i] = NULL; | ||
213 | |||
214 | /* Set us so that we have processed and used all buffers, but have | ||
215 | * not restocked the Rx queue with fresh buffers */ | ||
216 | rxq->read = rxq->write = 0; | ||
217 | rxq->write_actual = 0; | ||
218 | rxq->free_count = 0; | ||
219 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
220 | |||
221 | iwl_pcie_rx_replenish(trans); | ||
222 | |||
223 | iwl_trans_rx_hw_init(trans, rxq); | ||
224 | |||
225 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | ||
226 | rxq->need_update = 1; | ||
227 | iwl_pcie_rxq_inc_wr_ptr(trans, rxq); | ||
228 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | static void iwl_trans_pcie_rx_free(struct iwl_trans *trans) | ||
234 | { | ||
235 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
236 | struct iwl_rxq *rxq = &trans_pcie->rxq; | ||
237 | unsigned long flags; | ||
238 | |||
239 | /*if rxq->bd is NULL, it means that nothing has been allocated, | ||
240 | * exit now */ | ||
241 | if (!rxq->bd) { | ||
242 | IWL_DEBUG_INFO(trans, "Free NULL rx context\n"); | ||
243 | return; | ||
244 | } | ||
245 | |||
246 | spin_lock_irqsave(&rxq->lock, flags); | ||
247 | iwl_trans_rxq_free_rx_bufs(trans); | ||
248 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
249 | |||
250 | dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE, | ||
251 | rxq->bd, rxq->bd_dma); | ||
252 | memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); | ||
253 | rxq->bd = NULL; | ||
254 | |||
255 | if (rxq->rb_stts) | ||
256 | dma_free_coherent(trans->dev, | ||
257 | sizeof(struct iwl_rb_status), | ||
258 | rxq->rb_stts, rxq->rb_stts_dma); | ||
259 | else | ||
260 | IWL_DEBUG_INFO(trans, "Free rxq->rb_stts which is NULL\n"); | ||
261 | memset(&rxq->rb_stts_dma, 0, sizeof(rxq->rb_stts_dma)); | ||
262 | rxq->rb_stts = NULL; | ||
263 | } | ||
264 | |||
265 | static int iwl_trans_rx_stop(struct iwl_trans *trans) | ||
266 | { | ||
267 | |||
268 | /* stop Rx DMA */ | ||
269 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); | ||
270 | return iwl_poll_direct_bit(trans, FH_MEM_RSSR_RX_STATUS_REG, | ||
271 | FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); | ||
272 | } | ||
273 | |||
274 | static int iwlagn_alloc_dma_ptr(struct iwl_trans *trans, | 84 | static int iwlagn_alloc_dma_ptr(struct iwl_trans *trans, |
275 | struct iwl_dma_ptr *ptr, size_t size) | 85 | struct iwl_dma_ptr *ptr, size_t size) |
276 | { | 86 | { |
@@ -853,7 +663,7 @@ static int iwl_nic_init(struct iwl_trans *trans) | |||
853 | iwl_op_mode_nic_config(trans->op_mode); | 663 | iwl_op_mode_nic_config(trans->op_mode); |
854 | 664 | ||
855 | /* Allocate the RX queue, or reset if it is already allocated */ | 665 | /* Allocate the RX queue, or reset if it is already allocated */ |
856 | iwl_rx_init(trans); | 666 | iwl_pcie_rx_init(trans); |
857 | 667 | ||
858 | /* Allocate or reset and init all Tx and Command queues */ | 668 | /* Allocate or reset and init all Tx and Command queues */ |
859 | if (iwl_tx_init(trans)) | 669 | if (iwl_tx_init(trans)) |
@@ -1214,7 +1024,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
1214 | */ | 1024 | */ |
1215 | if (test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status)) { | 1025 | if (test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status)) { |
1216 | iwl_trans_tx_stop(trans); | 1026 | iwl_trans_tx_stop(trans); |
1217 | iwl_trans_rx_stop(trans); | 1027 | iwl_pcie_rx_stop(trans); |
1218 | 1028 | ||
1219 | /* Power-down device's busmaster DMA clocks */ | 1029 | /* Power-down device's busmaster DMA clocks */ |
1220 | iwl_write_prph(trans, APMG_CLK_DIS_REG, | 1030 | iwl_write_prph(trans, APMG_CLK_DIS_REG, |
@@ -1583,7 +1393,7 @@ void iwl_trans_pcie_free(struct iwl_trans *trans) | |||
1583 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1393 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1584 | 1394 | ||
1585 | iwl_trans_pcie_tx_free(trans); | 1395 | iwl_trans_pcie_tx_free(trans); |
1586 | iwl_trans_pcie_rx_free(trans); | 1396 | iwl_pcie_rx_free(trans); |
1587 | 1397 | ||
1588 | if (trans_pcie->irq_requested == true) { | 1398 | if (trans_pcie->irq_requested == true) { |
1589 | free_irq(trans_pcie->irq, trans); | 1399 | free_irq(trans_pcie->irq, trans); |