diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2011-07-11 10:35:34 -0400 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2011-07-16 10:38:46 -0400 |
commit | ab697a9f1e73ba817955e15bd899a8a0627f9fd6 (patch) | |
tree | 238ec4488413f008da43ee9914484500f81df60f /drivers | |
parent | 4caab328eeea02b244765c355f9d875f8f5f6093 (diff) |
iwlagn: move rx transport functions to iwl-trans-rx-pcie.c
Also create a new file: iwl-trans-int-pcie.h which will include
the non static functions that are shared among the current pcie transport layer.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/iwlwifi/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 226 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 354 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-rx.c | 136 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h | 42 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c | 694 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans.c | 61 |
9 files changed, 799 insertions, 725 deletions
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 2433389f8dfe..d3c8e37ec153 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
@@ -14,7 +14,7 @@ iwlagn-objs += iwl-6000.o | |||
14 | iwlagn-objs += iwl-1000.o | 14 | iwlagn-objs += iwl-1000.o |
15 | iwlagn-objs += iwl-2000.o | 15 | iwlagn-objs += iwl-2000.o |
16 | iwlagn-objs += iwl-pci.o | 16 | iwlagn-objs += iwl-pci.o |
17 | iwlagn-objs += iwl-trans.o | 17 | iwlagn-objs += iwl-trans.o iwl-trans-rx-pcie.o |
18 | 18 | ||
19 | iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o | 19 | iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o |
20 | iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o | 20 | iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index d2ba20087986..4156316e108d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -628,56 +628,6 @@ struct iwl_mod_params iwlagn_mod_params = { | |||
628 | /* the rest are 0 by default */ | 628 | /* the rest are 0 by default */ |
629 | }; | 629 | }; |
630 | 630 | ||
631 | int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | ||
632 | { | ||
633 | u32 rb_size; | ||
634 | const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ | ||
635 | u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */ | ||
636 | |||
637 | rb_timeout = RX_RB_TIMEOUT; | ||
638 | |||
639 | if (iwlagn_mod_params.amsdu_size_8K) | ||
640 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; | ||
641 | else | ||
642 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; | ||
643 | |||
644 | /* Stop Rx DMA */ | ||
645 | iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); | ||
646 | |||
647 | /* Reset driver's Rx queue write index */ | ||
648 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); | ||
649 | |||
650 | /* Tell device where to find RBD circular buffer in DRAM */ | ||
651 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG, | ||
652 | (u32)(rxq->bd_dma >> 8)); | ||
653 | |||
654 | /* Tell device where in DRAM to update its Rx status */ | ||
655 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, | ||
656 | rxq->rb_stts_dma >> 4); | ||
657 | |||
658 | /* Enable Rx DMA | ||
659 | * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in | ||
660 | * the credit mechanism in 5000 HW RX FIFO | ||
661 | * Direct rx interrupts to hosts | ||
662 | * Rx buffer size 4 or 8k | ||
663 | * RB timeout 0x10 | ||
664 | * 256 RBDs | ||
665 | */ | ||
666 | iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, | ||
667 | FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | | ||
668 | FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | | ||
669 | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | | ||
670 | FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MSK | | ||
671 | rb_size| | ||
672 | (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)| | ||
673 | (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); | ||
674 | |||
675 | /* Set interrupt coalescing timer to default (2048 usecs) */ | ||
676 | iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); | ||
677 | |||
678 | return 0; | ||
679 | } | ||
680 | |||
681 | static void iwlagn_set_pwr_vmain(struct iwl_priv *priv) | 631 | static void iwlagn_set_pwr_vmain(struct iwl_priv *priv) |
682 | { | 632 | { |
683 | /* | 633 | /* |
@@ -695,10 +645,10 @@ static void iwlagn_set_pwr_vmain(struct iwl_priv *priv) | |||
695 | ~APMG_PS_CTRL_MSK_PWR_SRC); | 645 | ~APMG_PS_CTRL_MSK_PWR_SRC); |
696 | } | 646 | } |
697 | 647 | ||
648 | /*TODO: this function should move to transport layer */ | ||
698 | int iwlagn_hw_nic_init(struct iwl_priv *priv) | 649 | int iwlagn_hw_nic_init(struct iwl_priv *priv) |
699 | { | 650 | { |
700 | unsigned long flags; | 651 | unsigned long flags; |
701 | struct iwl_rx_queue *rxq = &priv->rxq; | ||
702 | 652 | ||
703 | /* nic_init */ | 653 | /* nic_init */ |
704 | spin_lock_irqsave(&priv->lock, flags); | 654 | spin_lock_irqsave(&priv->lock, flags); |
@@ -716,17 +666,6 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv) | |||
716 | /* Allocate the RX queue, or reset if it is already allocated */ | 666 | /* Allocate the RX queue, or reset if it is already allocated */ |
717 | trans_rx_init(priv); | 667 | trans_rx_init(priv); |
718 | 668 | ||
719 | iwlagn_rx_replenish(priv); | ||
720 | |||
721 | iwlagn_rx_init(priv, rxq); | ||
722 | |||
723 | spin_lock_irqsave(&priv->lock, flags); | ||
724 | |||
725 | rxq->need_update = 1; | ||
726 | iwl_rx_queue_update_write_ptr(priv, rxq); | ||
727 | |||
728 | spin_unlock_irqrestore(&priv->lock, flags); | ||
729 | |||
730 | /* Allocate or reset and init all Tx and Command queues */ | 669 | /* Allocate or reset and init all Tx and Command queues */ |
731 | if (trans_tx_init(priv)) | 670 | if (trans_tx_init(priv)) |
732 | return -ENOMEM; | 671 | return -ENOMEM; |
@@ -742,169 +681,6 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv) | |||
742 | return 0; | 681 | return 0; |
743 | } | 682 | } |
744 | 683 | ||
745 | /** | ||
746 | * iwlagn_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr | ||
747 | */ | ||
748 | static inline __le32 iwlagn_dma_addr2rbd_ptr(struct iwl_priv *priv, | ||
749 | dma_addr_t dma_addr) | ||
750 | { | ||
751 | return cpu_to_le32((u32)(dma_addr >> 8)); | ||
752 | } | ||
753 | |||
754 | /** | ||
755 | * iwlagn_rx_queue_restock - refill RX queue from pre-allocated pool | ||
756 | * | ||
757 | * If there are slots in the RX queue that need to be restocked, | ||
758 | * and we have free pre-allocated buffers, fill the ranks as much | ||
759 | * as we can, pulling from rx_free. | ||
760 | * | ||
761 | * This moves the 'write' index forward to catch up with 'processed', and | ||
762 | * also updates the memory address in the firmware to reference the new | ||
763 | * target buffer. | ||
764 | */ | ||
765 | void iwlagn_rx_queue_restock(struct iwl_priv *priv) | ||
766 | { | ||
767 | struct iwl_rx_queue *rxq = &priv->rxq; | ||
768 | struct list_head *element; | ||
769 | struct iwl_rx_mem_buffer *rxb; | ||
770 | unsigned long flags; | ||
771 | |||
772 | spin_lock_irqsave(&rxq->lock, flags); | ||
773 | while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) { | ||
774 | /* The overwritten rxb must be a used one */ | ||
775 | rxb = rxq->queue[rxq->write]; | ||
776 | BUG_ON(rxb && rxb->page); | ||
777 | |||
778 | /* Get next free Rx buffer, remove from free list */ | ||
779 | element = rxq->rx_free.next; | ||
780 | rxb = list_entry(element, struct iwl_rx_mem_buffer, list); | ||
781 | list_del(element); | ||
782 | |||
783 | /* Point to Rx buffer via next RBD in circular buffer */ | ||
784 | rxq->bd[rxq->write] = iwlagn_dma_addr2rbd_ptr(priv, | ||
785 | rxb->page_dma); | ||
786 | rxq->queue[rxq->write] = rxb; | ||
787 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; | ||
788 | rxq->free_count--; | ||
789 | } | ||
790 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
791 | /* If the pre-allocated buffer pool is dropping low, schedule to | ||
792 | * refill it */ | ||
793 | if (rxq->free_count <= RX_LOW_WATERMARK) | ||
794 | queue_work(priv->workqueue, &priv->rx_replenish); | ||
795 | |||
796 | |||
797 | /* If we've added more space for the firmware to place data, tell it. | ||
798 | * Increment device's write pointer in multiples of 8. */ | ||
799 | if (rxq->write_actual != (rxq->write & ~0x7)) { | ||
800 | spin_lock_irqsave(&rxq->lock, flags); | ||
801 | rxq->need_update = 1; | ||
802 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
803 | iwl_rx_queue_update_write_ptr(priv, rxq); | ||
804 | } | ||
805 | } | ||
806 | |||
807 | /** | ||
808 | * iwlagn_rx_replenish - Move all used packet from rx_used to rx_free | ||
809 | * | ||
810 | * When moving to rx_free an SKB is allocated for the slot. | ||
811 | * | ||
812 | * Also restock the Rx queue via iwl_rx_queue_restock. | ||
813 | * This is called as a scheduled work item (except for during initialization) | ||
814 | */ | ||
815 | void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority) | ||
816 | { | ||
817 | struct iwl_rx_queue *rxq = &priv->rxq; | ||
818 | struct list_head *element; | ||
819 | struct iwl_rx_mem_buffer *rxb; | ||
820 | struct page *page; | ||
821 | unsigned long flags; | ||
822 | gfp_t gfp_mask = priority; | ||
823 | |||
824 | while (1) { | ||
825 | spin_lock_irqsave(&rxq->lock, flags); | ||
826 | if (list_empty(&rxq->rx_used)) { | ||
827 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
828 | return; | ||
829 | } | ||
830 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
831 | |||
832 | if (rxq->free_count > RX_LOW_WATERMARK) | ||
833 | gfp_mask |= __GFP_NOWARN; | ||
834 | |||
835 | if (priv->hw_params.rx_page_order > 0) | ||
836 | gfp_mask |= __GFP_COMP; | ||
837 | |||
838 | /* Alloc a new receive buffer */ | ||
839 | page = alloc_pages(gfp_mask, priv->hw_params.rx_page_order); | ||
840 | if (!page) { | ||
841 | if (net_ratelimit()) | ||
842 | IWL_DEBUG_INFO(priv, "alloc_pages failed, " | ||
843 | "order: %d\n", | ||
844 | priv->hw_params.rx_page_order); | ||
845 | |||
846 | if ((rxq->free_count <= RX_LOW_WATERMARK) && | ||
847 | net_ratelimit()) | ||
848 | IWL_CRIT(priv, "Failed to alloc_pages with %s. Only %u free buffers remaining.\n", | ||
849 | priority == GFP_ATOMIC ? "GFP_ATOMIC" : "GFP_KERNEL", | ||
850 | rxq->free_count); | ||
851 | /* We don't reschedule replenish work here -- we will | ||
852 | * call the restock method and if it still needs | ||
853 | * more buffers it will schedule replenish */ | ||
854 | return; | ||
855 | } | ||
856 | |||
857 | spin_lock_irqsave(&rxq->lock, flags); | ||
858 | |||
859 | if (list_empty(&rxq->rx_used)) { | ||
860 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
861 | __free_pages(page, priv->hw_params.rx_page_order); | ||
862 | return; | ||
863 | } | ||
864 | element = rxq->rx_used.next; | ||
865 | rxb = list_entry(element, struct iwl_rx_mem_buffer, list); | ||
866 | list_del(element); | ||
867 | |||
868 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
869 | |||
870 | BUG_ON(rxb->page); | ||
871 | rxb->page = page; | ||
872 | /* Get physical address of the RB */ | ||
873 | rxb->page_dma = dma_map_page(priv->bus.dev, page, 0, | ||
874 | PAGE_SIZE << priv->hw_params.rx_page_order, | ||
875 | DMA_FROM_DEVICE); | ||
876 | /* dma address must be no more than 36 bits */ | ||
877 | BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); | ||
878 | /* and also 256 byte aligned! */ | ||
879 | BUG_ON(rxb->page_dma & DMA_BIT_MASK(8)); | ||
880 | |||
881 | spin_lock_irqsave(&rxq->lock, flags); | ||
882 | |||
883 | list_add_tail(&rxb->list, &rxq->rx_free); | ||
884 | rxq->free_count++; | ||
885 | |||
886 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
887 | } | ||
888 | } | ||
889 | |||
890 | void iwlagn_rx_replenish(struct iwl_priv *priv) | ||
891 | { | ||
892 | unsigned long flags; | ||
893 | |||
894 | iwlagn_rx_allocate(priv, GFP_KERNEL); | ||
895 | |||
896 | spin_lock_irqsave(&priv->lock, flags); | ||
897 | iwlagn_rx_queue_restock(priv); | ||
898 | spin_unlock_irqrestore(&priv->lock, flags); | ||
899 | } | ||
900 | |||
901 | void iwlagn_rx_replenish_now(struct iwl_priv *priv) | ||
902 | { | ||
903 | iwlagn_rx_allocate(priv, GFP_ATOMIC); | ||
904 | |||
905 | iwlagn_rx_queue_restock(priv); | ||
906 | } | ||
907 | |||
908 | int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band) | 684 | int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band) |
909 | { | 685 | { |
910 | int idx = 0; | 686 | int idx = 0; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c2a124131ef9..bd85af91c58a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -457,346 +457,6 @@ static void iwl_bg_tx_flush(struct work_struct *work) | |||
457 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); | 457 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); |
458 | } | 458 | } |
459 | 459 | ||
460 | /** | ||
461 | * iwl_rx_handle - Main entry function for receiving responses from uCode | ||
462 | * | ||
463 | * Uses the priv->rx_handlers callback function array to invoke | ||
464 | * the appropriate handlers, including command responses, | ||
465 | * frame-received notifications, and other notifications. | ||
466 | */ | ||
467 | static void iwl_rx_handle(struct iwl_priv *priv) | ||
468 | { | ||
469 | struct iwl_rx_mem_buffer *rxb; | ||
470 | struct iwl_rx_packet *pkt; | ||
471 | struct iwl_rx_queue *rxq = &priv->rxq; | ||
472 | u32 r, i; | ||
473 | int reclaim; | ||
474 | unsigned long flags; | ||
475 | u8 fill_rx = 0; | ||
476 | u32 count = 8; | ||
477 | int total_empty; | ||
478 | |||
479 | /* uCode's read index (stored in shared DRAM) indicates the last Rx | ||
480 | * buffer that the driver may process (last buffer filled by ucode). */ | ||
481 | r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF; | ||
482 | i = rxq->read; | ||
483 | |||
484 | /* Rx interrupt, but nothing sent from uCode */ | ||
485 | if (i == r) | ||
486 | IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i); | ||
487 | |||
488 | /* calculate total frames need to be restock after handling RX */ | ||
489 | total_empty = r - rxq->write_actual; | ||
490 | if (total_empty < 0) | ||
491 | total_empty += RX_QUEUE_SIZE; | ||
492 | |||
493 | if (total_empty > (RX_QUEUE_SIZE / 2)) | ||
494 | fill_rx = 1; | ||
495 | |||
496 | while (i != r) { | ||
497 | int len; | ||
498 | |||
499 | rxb = rxq->queue[i]; | ||
500 | |||
501 | /* If an RXB doesn't have a Rx queue slot associated with it, | ||
502 | * then a bug has been introduced in the queue refilling | ||
503 | * routines -- catch it here */ | ||
504 | if (WARN_ON(rxb == NULL)) { | ||
505 | i = (i + 1) & RX_QUEUE_MASK; | ||
506 | continue; | ||
507 | } | ||
508 | |||
509 | rxq->queue[i] = NULL; | ||
510 | |||
511 | dma_unmap_page(priv->bus.dev, rxb->page_dma, | ||
512 | PAGE_SIZE << priv->hw_params.rx_page_order, | ||
513 | DMA_FROM_DEVICE); | ||
514 | pkt = rxb_addr(rxb); | ||
515 | |||
516 | IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, | ||
517 | i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); | ||
518 | |||
519 | len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | ||
520 | len += sizeof(u32); /* account for status word */ | ||
521 | trace_iwlwifi_dev_rx(priv, pkt, len); | ||
522 | |||
523 | /* Reclaim a command buffer only if this packet is a response | ||
524 | * to a (driver-originated) command. | ||
525 | * If the packet (e.g. Rx frame) originated from uCode, | ||
526 | * there is no command buffer to reclaim. | ||
527 | * Ucode should set SEQ_RX_FRAME bit if ucode-originated, | ||
528 | * but apparently a few don't get set; catch them here. */ | ||
529 | reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) && | ||
530 | (pkt->hdr.cmd != REPLY_RX_PHY_CMD) && | ||
531 | (pkt->hdr.cmd != REPLY_RX) && | ||
532 | (pkt->hdr.cmd != REPLY_RX_MPDU_CMD) && | ||
533 | (pkt->hdr.cmd != REPLY_COMPRESSED_BA) && | ||
534 | (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && | ||
535 | (pkt->hdr.cmd != REPLY_TX); | ||
536 | |||
537 | iwl_rx_dispatch(priv, rxb); | ||
538 | |||
539 | /* | ||
540 | * XXX: After here, we should always check rxb->page | ||
541 | * against NULL before touching it or its virtual | ||
542 | * memory (pkt). Because some rx_handler might have | ||
543 | * already taken or freed the pages. | ||
544 | */ | ||
545 | |||
546 | if (reclaim) { | ||
547 | /* Invoke any callbacks, transfer the buffer to caller, | ||
548 | * and fire off the (possibly) blocking | ||
549 | * trans_send_cmd() | ||
550 | * as we reclaim the driver command queue */ | ||
551 | if (rxb->page) | ||
552 | iwl_tx_cmd_complete(priv, rxb); | ||
553 | else | ||
554 | IWL_WARN(priv, "Claim null rxb?\n"); | ||
555 | } | ||
556 | |||
557 | /* Reuse the page if possible. For notification packets and | ||
558 | * SKBs that fail to Rx correctly, add them back into the | ||
559 | * rx_free list for reuse later. */ | ||
560 | spin_lock_irqsave(&rxq->lock, flags); | ||
561 | if (rxb->page != NULL) { | ||
562 | rxb->page_dma = dma_map_page(priv->bus.dev, rxb->page, | ||
563 | 0, PAGE_SIZE << priv->hw_params.rx_page_order, | ||
564 | DMA_FROM_DEVICE); | ||
565 | list_add_tail(&rxb->list, &rxq->rx_free); | ||
566 | rxq->free_count++; | ||
567 | } else | ||
568 | list_add_tail(&rxb->list, &rxq->rx_used); | ||
569 | |||
570 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
571 | |||
572 | i = (i + 1) & RX_QUEUE_MASK; | ||
573 | /* If there are a lot of unused frames, | ||
574 | * restock the Rx queue so ucode wont assert. */ | ||
575 | if (fill_rx) { | ||
576 | count++; | ||
577 | if (count >= 8) { | ||
578 | rxq->read = i; | ||
579 | iwlagn_rx_replenish_now(priv); | ||
580 | count = 0; | ||
581 | } | ||
582 | } | ||
583 | } | ||
584 | |||
585 | /* Backtrack one entry */ | ||
586 | rxq->read = i; | ||
587 | if (fill_rx) | ||
588 | iwlagn_rx_replenish_now(priv); | ||
589 | else | ||
590 | iwlagn_rx_queue_restock(priv); | ||
591 | } | ||
592 | |||
593 | /* tasklet for iwlagn interrupt */ | ||
594 | void iwl_irq_tasklet(struct iwl_priv *priv) | ||
595 | { | ||
596 | u32 inta = 0; | ||
597 | u32 handled = 0; | ||
598 | unsigned long flags; | ||
599 | u32 i; | ||
600 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
601 | u32 inta_mask; | ||
602 | #endif | ||
603 | |||
604 | spin_lock_irqsave(&priv->lock, flags); | ||
605 | |||
606 | /* Ack/clear/reset pending uCode interrupts. | ||
607 | * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, | ||
608 | */ | ||
609 | /* There is a hardware bug in the interrupt mask function that some | ||
610 | * interrupts (i.e. CSR_INT_BIT_SCD) can still be generated even if | ||
611 | * they are disabled in the CSR_INT_MASK register. Furthermore the | ||
612 | * ICT interrupt handling mechanism has another bug that might cause | ||
613 | * these unmasked interrupts fail to be detected. We workaround the | ||
614 | * hardware bugs here by ACKing all the possible interrupts so that | ||
615 | * interrupt coalescing can still be achieved. | ||
616 | */ | ||
617 | iwl_write32(priv, CSR_INT, priv->_agn.inta | ~priv->inta_mask); | ||
618 | |||
619 | inta = priv->_agn.inta; | ||
620 | |||
621 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
622 | if (iwl_get_debug_level(priv) & IWL_DL_ISR) { | ||
623 | /* just for debug */ | ||
624 | inta_mask = iwl_read32(priv, CSR_INT_MASK); | ||
625 | IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x\n ", | ||
626 | inta, inta_mask); | ||
627 | } | ||
628 | #endif | ||
629 | |||
630 | spin_unlock_irqrestore(&priv->lock, flags); | ||
631 | |||
632 | /* saved interrupt in inta variable now we can reset priv->_agn.inta */ | ||
633 | priv->_agn.inta = 0; | ||
634 | |||
635 | /* Now service all interrupt bits discovered above. */ | ||
636 | if (inta & CSR_INT_BIT_HW_ERR) { | ||
637 | IWL_ERR(priv, "Hardware error detected. Restarting.\n"); | ||
638 | |||
639 | /* Tell the device to stop sending interrupts */ | ||
640 | iwl_disable_interrupts(priv); | ||
641 | |||
642 | priv->isr_stats.hw++; | ||
643 | iwl_irq_handle_error(priv); | ||
644 | |||
645 | handled |= CSR_INT_BIT_HW_ERR; | ||
646 | |||
647 | return; | ||
648 | } | ||
649 | |||
650 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
651 | if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) { | ||
652 | /* NIC fires this, but we don't use it, redundant with WAKEUP */ | ||
653 | if (inta & CSR_INT_BIT_SCD) { | ||
654 | IWL_DEBUG_ISR(priv, "Scheduler finished to transmit " | ||
655 | "the frame/frames.\n"); | ||
656 | priv->isr_stats.sch++; | ||
657 | } | ||
658 | |||
659 | /* Alive notification via Rx interrupt will do the real work */ | ||
660 | if (inta & CSR_INT_BIT_ALIVE) { | ||
661 | IWL_DEBUG_ISR(priv, "Alive interrupt\n"); | ||
662 | priv->isr_stats.alive++; | ||
663 | } | ||
664 | } | ||
665 | #endif | ||
666 | /* Safely ignore these bits for debug checks below */ | ||
667 | inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE); | ||
668 | |||
669 | /* HW RF KILL switch toggled */ | ||
670 | if (inta & CSR_INT_BIT_RF_KILL) { | ||
671 | int hw_rf_kill = 0; | ||
672 | if (!(iwl_read32(priv, CSR_GP_CNTRL) & | ||
673 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) | ||
674 | hw_rf_kill = 1; | ||
675 | |||
676 | IWL_WARN(priv, "RF_KILL bit toggled to %s.\n", | ||
677 | hw_rf_kill ? "disable radio" : "enable radio"); | ||
678 | |||
679 | priv->isr_stats.rfkill++; | ||
680 | |||
681 | /* driver only loads ucode once setting the interface up. | ||
682 | * the driver allows loading the ucode even if the radio | ||
683 | * is killed. Hence update the killswitch state here. The | ||
684 | * rfkill handler will care about restarting if needed. | ||
685 | */ | ||
686 | if (!test_bit(STATUS_ALIVE, &priv->status)) { | ||
687 | if (hw_rf_kill) | ||
688 | set_bit(STATUS_RF_KILL_HW, &priv->status); | ||
689 | else | ||
690 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | ||
691 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill); | ||
692 | } | ||
693 | |||
694 | handled |= CSR_INT_BIT_RF_KILL; | ||
695 | } | ||
696 | |||
697 | /* Chip got too hot and stopped itself */ | ||
698 | if (inta & CSR_INT_BIT_CT_KILL) { | ||
699 | IWL_ERR(priv, "Microcode CT kill error detected.\n"); | ||
700 | priv->isr_stats.ctkill++; | ||
701 | handled |= CSR_INT_BIT_CT_KILL; | ||
702 | } | ||
703 | |||
704 | /* Error detected by uCode */ | ||
705 | if (inta & CSR_INT_BIT_SW_ERR) { | ||
706 | IWL_ERR(priv, "Microcode SW error detected. " | ||
707 | " Restarting 0x%X.\n", inta); | ||
708 | priv->isr_stats.sw++; | ||
709 | iwl_irq_handle_error(priv); | ||
710 | handled |= CSR_INT_BIT_SW_ERR; | ||
711 | } | ||
712 | |||
713 | /* uCode wakes up after power-down sleep */ | ||
714 | if (inta & CSR_INT_BIT_WAKEUP) { | ||
715 | IWL_DEBUG_ISR(priv, "Wakeup interrupt\n"); | ||
716 | iwl_rx_queue_update_write_ptr(priv, &priv->rxq); | ||
717 | for (i = 0; i < priv->hw_params.max_txq_num; i++) | ||
718 | iwl_txq_update_write_ptr(priv, &priv->txq[i]); | ||
719 | |||
720 | priv->isr_stats.wakeup++; | ||
721 | |||
722 | handled |= CSR_INT_BIT_WAKEUP; | ||
723 | } | ||
724 | |||
725 | /* All uCode command responses, including Tx command responses, | ||
726 | * Rx "responses" (frame-received notification), and other | ||
727 | * notifications from uCode come through here*/ | ||
728 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX | | ||
729 | CSR_INT_BIT_RX_PERIODIC)) { | ||
730 | IWL_DEBUG_ISR(priv, "Rx interrupt\n"); | ||
731 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { | ||
732 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); | ||
733 | iwl_write32(priv, CSR_FH_INT_STATUS, | ||
734 | CSR_FH_INT_RX_MASK); | ||
735 | } | ||
736 | if (inta & CSR_INT_BIT_RX_PERIODIC) { | ||
737 | handled |= CSR_INT_BIT_RX_PERIODIC; | ||
738 | iwl_write32(priv, CSR_INT, CSR_INT_BIT_RX_PERIODIC); | ||
739 | } | ||
740 | /* Sending RX interrupt require many steps to be done in the | ||
741 | * the device: | ||
742 | * 1- write interrupt to current index in ICT table. | ||
743 | * 2- dma RX frame. | ||
744 | * 3- update RX shared data to indicate last write index. | ||
745 | * 4- send interrupt. | ||
746 | * This could lead to RX race, driver could receive RX interrupt | ||
747 | * but the shared data changes does not reflect this; | ||
748 | * periodic interrupt will detect any dangling Rx activity. | ||
749 | */ | ||
750 | |||
751 | /* Disable periodic interrupt; we use it as just a one-shot. */ | ||
752 | iwl_write8(priv, CSR_INT_PERIODIC_REG, | ||
753 | CSR_INT_PERIODIC_DIS); | ||
754 | iwl_rx_handle(priv); | ||
755 | |||
756 | /* | ||
757 | * Enable periodic interrupt in 8 msec only if we received | ||
758 | * real RX interrupt (instead of just periodic int), to catch | ||
759 | * any dangling Rx interrupt. If it was just the periodic | ||
760 | * interrupt, there was no dangling Rx activity, and no need | ||
761 | * to extend the periodic interrupt; one-shot is enough. | ||
762 | */ | ||
763 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) | ||
764 | iwl_write8(priv, CSR_INT_PERIODIC_REG, | ||
765 | CSR_INT_PERIODIC_ENA); | ||
766 | |||
767 | priv->isr_stats.rx++; | ||
768 | } | ||
769 | |||
770 | /* This "Tx" DMA channel is used only for loading uCode */ | ||
771 | if (inta & CSR_INT_BIT_FH_TX) { | ||
772 | iwl_write32(priv, CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK); | ||
773 | IWL_DEBUG_ISR(priv, "uCode load interrupt\n"); | ||
774 | priv->isr_stats.tx++; | ||
775 | handled |= CSR_INT_BIT_FH_TX; | ||
776 | /* Wake up uCode load routine, now that load is complete */ | ||
777 | priv->ucode_write_complete = 1; | ||
778 | wake_up_interruptible(&priv->wait_command_queue); | ||
779 | } | ||
780 | |||
781 | if (inta & ~handled) { | ||
782 | IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled); | ||
783 | priv->isr_stats.unhandled++; | ||
784 | } | ||
785 | |||
786 | if (inta & ~(priv->inta_mask)) { | ||
787 | IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n", | ||
788 | inta & ~priv->inta_mask); | ||
789 | } | ||
790 | |||
791 | /* Re-enable all interrupts */ | ||
792 | /* only Re-enable if disabled by irq */ | ||
793 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) | ||
794 | iwl_enable_interrupts(priv); | ||
795 | /* Re-enable RF_KILL if it occurred */ | ||
796 | else if (handled & CSR_INT_BIT_RF_KILL) | ||
797 | iwl_enable_rfkill_int(priv); | ||
798 | } | ||
799 | |||
800 | /***************************************************************************** | 460 | /***************************************************************************** |
801 | * | 461 | * |
802 | * sysfs attributes | 462 | * sysfs attributes |
@@ -2321,19 +1981,6 @@ static void iwl_bg_restart(struct work_struct *data) | |||
2321 | } | 1981 | } |
2322 | } | 1982 | } |
2323 | 1983 | ||
2324 | static void iwl_bg_rx_replenish(struct work_struct *data) | ||
2325 | { | ||
2326 | struct iwl_priv *priv = | ||
2327 | container_of(data, struct iwl_priv, rx_replenish); | ||
2328 | |||
2329 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
2330 | return; | ||
2331 | |||
2332 | mutex_lock(&priv->mutex); | ||
2333 | iwlagn_rx_replenish(priv); | ||
2334 | mutex_unlock(&priv->mutex); | ||
2335 | } | ||
2336 | |||
2337 | static int iwl_mac_offchannel_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | 1984 | static int iwl_mac_offchannel_tx(struct ieee80211_hw *hw, struct sk_buff *skb, |
2338 | struct ieee80211_channel *chan, | 1985 | struct ieee80211_channel *chan, |
2339 | enum nl80211_channel_type channel_type, | 1986 | enum nl80211_channel_type channel_type, |
@@ -3188,7 +2835,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
3188 | init_waitqueue_head(&priv->wait_command_queue); | 2835 | init_waitqueue_head(&priv->wait_command_queue); |
3189 | 2836 | ||
3190 | INIT_WORK(&priv->restart, iwl_bg_restart); | 2837 | INIT_WORK(&priv->restart, iwl_bg_restart); |
3191 | INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); | ||
3192 | INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); | 2838 | INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); |
3193 | INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); | 2839 | INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); |
3194 | INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush); | 2840 | INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 6ddfd9338ee9..1655e5943694 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -174,7 +174,6 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr); | |||
174 | int iwlagn_send_tx_power(struct iwl_priv *priv); | 174 | int iwlagn_send_tx_power(struct iwl_priv *priv); |
175 | void iwlagn_temperature(struct iwl_priv *priv); | 175 | void iwlagn_temperature(struct iwl_priv *priv); |
176 | u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv); | 176 | u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv); |
177 | int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq); | ||
178 | int iwlagn_hw_nic_init(struct iwl_priv *priv); | 177 | int iwlagn_hw_nic_init(struct iwl_priv *priv); |
179 | int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv); | 178 | int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv); |
180 | int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); | 179 | int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); |
@@ -182,11 +181,6 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); | |||
182 | int iwlagn_send_beacon_cmd(struct iwl_priv *priv); | 181 | int iwlagn_send_beacon_cmd(struct iwl_priv *priv); |
183 | 182 | ||
184 | /* rx */ | 183 | /* rx */ |
185 | void iwl_irq_tasklet(struct iwl_priv *priv); | ||
186 | void iwlagn_rx_queue_restock(struct iwl_priv *priv); | ||
187 | void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority); | ||
188 | void iwlagn_rx_replenish(struct iwl_priv *priv); | ||
189 | void iwlagn_rx_replenish_now(struct iwl_priv *priv); | ||
190 | int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); | 184 | int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); |
191 | void iwl_setup_rx_handlers(struct iwl_priv *priv); | 185 | void iwl_setup_rx_handlers(struct iwl_priv *priv); |
192 | void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); | 186 | void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 2318052e094b..711d2f61e2e6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -336,9 +336,6 @@ static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx, | |||
336 | /***************************************************** | 336 | /***************************************************** |
337 | * RX | 337 | * RX |
338 | ******************************************************/ | 338 | ******************************************************/ |
339 | void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, | ||
340 | struct iwl_rx_queue *q); | ||
341 | int iwl_rx_queue_space(const struct iwl_rx_queue *q); | ||
342 | void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); | 339 | void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); |
343 | 340 | ||
344 | void iwl_chswitch_done(struct iwl_priv *priv, bool is_success); | 341 | void iwl_chswitch_done(struct iwl_priv *priv, bool is_success); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index bd63b785f68c..05fd75fb59ac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -41,142 +41,6 @@ | |||
41 | #include "iwl-agn-calib.h" | 41 | #include "iwl-agn-calib.h" |
42 | #include "iwl-agn.h" | 42 | #include "iwl-agn.h" |
43 | 43 | ||
44 | /****************************************************************************** | ||
45 | * | ||
46 | * RX path functions | ||
47 | * | ||
48 | ******************************************************************************/ | ||
49 | |||
50 | /* | ||
51 | * Rx theory of operation | ||
52 | * | ||
53 | * Driver allocates a circular buffer of Receive Buffer Descriptors (RBDs), | ||
54 | * each of which point to Receive Buffers to be filled by the NIC. These get | ||
55 | * used not only for Rx frames, but for any command response or notification | ||
56 | * from the NIC. The driver and NIC manage the Rx buffers by means | ||
57 | * of indexes into the circular buffer. | ||
58 | * | ||
59 | * Rx Queue Indexes | ||
60 | * The host/firmware share two index registers for managing the Rx buffers. | ||
61 | * | ||
62 | * The READ index maps to the first position that the firmware may be writing | ||
63 | * to -- the driver can read up to (but not including) this position and get | ||
64 | * good data. | ||
65 | * The READ index is managed by the firmware once the card is enabled. | ||
66 | * | ||
67 | * The WRITE index maps to the last position the driver has read from -- the | ||
68 | * position preceding WRITE is the last slot the firmware can place a packet. | ||
69 | * | ||
70 | * The queue is empty (no good data) if WRITE = READ - 1, and is full if | ||
71 | * WRITE = READ. | ||
72 | * | ||
73 | * During initialization, the host sets up the READ queue position to the first | ||
74 | * INDEX position, and WRITE to the last (READ - 1 wrapped) | ||
75 | * | ||
76 | * When the firmware places a packet in a buffer, it will advance the READ index | ||
77 | * and fire the RX interrupt. The driver can then query the READ index and | ||
78 | * process as many packets as possible, moving the WRITE index forward as it | ||
79 | * resets the Rx queue buffers with new memory. | ||
80 | * | ||
81 | * The management in the driver is as follows: | ||
82 | * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When | ||
83 | * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled | ||
84 | * to replenish the iwl->rxq->rx_free. | ||
85 | * + In iwl_rx_replenish (scheduled) if 'processed' != 'read' then the | ||
86 | * iwl->rxq is replenished and the READ INDEX is updated (updating the | ||
87 | * 'processed' and 'read' driver indexes as well) | ||
88 | * + A received packet is processed and handed to the kernel network stack, | ||
89 | * detached from the iwl->rxq. The driver 'processed' index is updated. | ||
90 | * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free | ||
91 | * list. If there are no allocated buffers in iwl->rxq->rx_free, the READ | ||
92 | * INDEX is not incremented and iwl->status(RX_STALLED) is set. If there | ||
93 | * were enough free buffers and RX_STALLED is set it is cleared. | ||
94 | * | ||
95 | * | ||
96 | * Driver sequence: | ||
97 | * | ||
98 | * iwl_rx_queue_alloc() Allocates rx_free | ||
99 | * iwl_rx_replenish() Replenishes rx_free list from rx_used, and calls | ||
100 | * iwl_rx_queue_restock | ||
101 | * iwl_rx_queue_restock() Moves available buffers from rx_free into Rx | ||
102 | * queue, updates firmware pointers, and updates | ||
103 | * the WRITE index. If insufficient rx_free buffers | ||
104 | * are available, schedules iwl_rx_replenish | ||
105 | * | ||
106 | * -- enable interrupts -- | ||
107 | * ISR - iwl_rx() Detach iwl_rx_mem_buffers from pool up to the | ||
108 | * READ INDEX, detaching the SKB from the pool. | ||
109 | * Moves the packet buffer from queue to rx_used. | ||
110 | * Calls iwl_rx_queue_restock to refill any empty | ||
111 | * slots. | ||
112 | * ... | ||
113 | * | ||
114 | */ | ||
115 | |||
116 | /** | ||
117 | * iwl_rx_queue_space - Return number of free slots available in queue. | ||
118 | */ | ||
119 | int iwl_rx_queue_space(const struct iwl_rx_queue *q) | ||
120 | { | ||
121 | int s = q->read - q->write; | ||
122 | if (s <= 0) | ||
123 | s += RX_QUEUE_SIZE; | ||
124 | /* keep some buffer to not confuse full and empty queue */ | ||
125 | s -= 2; | ||
126 | if (s < 0) | ||
127 | s = 0; | ||
128 | return s; | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue | ||
133 | */ | ||
134 | void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q) | ||
135 | { | ||
136 | unsigned long flags; | ||
137 | u32 reg; | ||
138 | |||
139 | spin_lock_irqsave(&q->lock, flags); | ||
140 | |||
141 | if (q->need_update == 0) | ||
142 | goto exit_unlock; | ||
143 | |||
144 | if (priv->cfg->base_params->shadow_reg_enable) { | ||
145 | /* shadow register enabled */ | ||
146 | /* Device expects a multiple of 8 */ | ||
147 | q->write_actual = (q->write & ~0x7); | ||
148 | iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write_actual); | ||
149 | } else { | ||
150 | /* If power-saving is in use, make sure device is awake */ | ||
151 | if (test_bit(STATUS_POWER_PMI, &priv->status)) { | ||
152 | reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); | ||
153 | |||
154 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { | ||
155 | IWL_DEBUG_INFO(priv, | ||
156 | "Rx queue requesting wakeup," | ||
157 | " GP1 = 0x%x\n", reg); | ||
158 | iwl_set_bit(priv, CSR_GP_CNTRL, | ||
159 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
160 | goto exit_unlock; | ||
161 | } | ||
162 | |||
163 | q->write_actual = (q->write & ~0x7); | ||
164 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR, | ||
165 | q->write_actual); | ||
166 | |||
167 | /* Else device is assumed to be awake */ | ||
168 | } else { | ||
169 | /* Device expects a multiple of 8 */ | ||
170 | q->write_actual = (q->write & ~0x7); | ||
171 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR, | ||
172 | q->write_actual); | ||
173 | } | ||
174 | } | ||
175 | q->need_update = 0; | ||
176 | |||
177 | exit_unlock: | ||
178 | spin_unlock_irqrestore(&q->lock, flags); | ||
179 | } | ||
180 | 44 | ||
181 | /****************************************************************************** | 45 | /****************************************************************************** |
182 | * | 46 | * |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h b/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h new file mode 100644 index 000000000000..6c56a3f75411 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. | ||
4 | * | ||
5 | * Portions of this file are derived from the ipw3945 project, as well | ||
6 | * as portions of the ieee80211 subsystem header files. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of version 2 of the GNU General Public License as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along with | ||
18 | * this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
20 | * | ||
21 | * The full GNU General Public License is included in this distribution in the | ||
22 | * file called LICENSE. | ||
23 | * | ||
24 | * Contact Information: | ||
25 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | #ifndef __iwl_trans_int_pcie_h__ | ||
30 | #define __iwl_trans_int_pcie_h__ | ||
31 | |||
32 | /*This file includes the declaration that are internal to the | ||
33 | * trans_pcie layer */ | ||
34 | |||
35 | void iwl_bg_rx_replenish(struct work_struct *data); | ||
36 | void iwl_irq_tasklet(struct iwl_priv *priv); | ||
37 | void iwlagn_rx_replenish(struct iwl_priv *priv); | ||
38 | void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, | ||
39 | struct iwl_rx_queue *q); | ||
40 | |||
41 | #endif /* __iwl_trans_int_pcie_h__ */ | ||
42 | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c new file mode 100644 index 000000000000..046a33f5ca6d --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c | |||
@@ -0,0 +1,694 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. | ||
4 | * | ||
5 | * Portions of this file are derived from the ipw3945 project, as well | ||
6 | * as portions of the ieee80211 subsystem header files. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of version 2 of the GNU General Public License as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along with | ||
18 | * this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
20 | * | ||
21 | * The full GNU General Public License is included in this distribution in the | ||
22 | * file called LICENSE. | ||
23 | * | ||
24 | * Contact Information: | ||
25 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | #include <linux/sched.h> | ||
30 | #include <linux/wait.h> | ||
31 | |||
32 | #include "iwl-dev.h" | ||
33 | #include "iwl-agn.h" | ||
34 | #include "iwl-core.h" | ||
35 | #include "iwl-io.h" | ||
36 | #include "iwl-helpers.h" | ||
37 | #include "iwl-trans-int-pcie.h" | ||
38 | |||
39 | /****************************************************************************** | ||
40 | * | ||
41 | * RX path functions | ||
42 | * | ||
43 | ******************************************************************************/ | ||
44 | |||
45 | /* | ||
46 | * Rx theory of operation | ||
47 | * | ||
48 | * Driver allocates a circular buffer of Receive Buffer Descriptors (RBDs), | ||
49 | * each of which point to Receive Buffers to be filled by the NIC. These get | ||
50 | * used not only for Rx frames, but for any command response or notification | ||
51 | * from the NIC. The driver and NIC manage the Rx buffers by means | ||
52 | * of indexes into the circular buffer. | ||
53 | * | ||
54 | * Rx Queue Indexes | ||
55 | * The host/firmware share two index registers for managing the Rx buffers. | ||
56 | * | ||
57 | * The READ index maps to the first position that the firmware may be writing | ||
58 | * to -- the driver can read up to (but not including) this position and get | ||
59 | * good data. | ||
60 | * The READ index is managed by the firmware once the card is enabled. | ||
61 | * | ||
62 | * The WRITE index maps to the last position the driver has read from -- the | ||
63 | * position preceding WRITE is the last slot the firmware can place a packet. | ||
64 | * | ||
65 | * The queue is empty (no good data) if WRITE = READ - 1, and is full if | ||
66 | * WRITE = READ. | ||
67 | * | ||
68 | * During initialization, the host sets up the READ queue position to the first | ||
69 | * INDEX position, and WRITE to the last (READ - 1 wrapped) | ||
70 | * | ||
71 | * When the firmware places a packet in a buffer, it will advance the READ index | ||
72 | * and fire the RX interrupt. The driver can then query the READ index and | ||
73 | * process as many packets as possible, moving the WRITE index forward as it | ||
74 | * resets the Rx queue buffers with new memory. | ||
75 | * | ||
76 | * The management in the driver is as follows: | ||
77 | * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When | ||
78 | * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled | ||
79 | * to replenish the iwl->rxq->rx_free. | ||
80 | * + In iwl_rx_replenish (scheduled) if 'processed' != 'read' then the | ||
81 | * iwl->rxq is replenished and the READ INDEX is updated (updating the | ||
82 | * 'processed' and 'read' driver indexes as well) | ||
83 | * + A received packet is processed and handed to the kernel network stack, | ||
84 | * detached from the iwl->rxq. The driver 'processed' index is updated. | ||
85 | * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free | ||
86 | * list. If there are no allocated buffers in iwl->rxq->rx_free, the READ | ||
87 | * INDEX is not incremented and iwl->status(RX_STALLED) is set. If there | ||
88 | * were enough free buffers and RX_STALLED is set it is cleared. | ||
89 | * | ||
90 | * | ||
91 | * Driver sequence: | ||
92 | * | ||
93 | * iwl_rx_queue_alloc() Allocates rx_free | ||
94 | * iwl_rx_replenish() Replenishes rx_free list from rx_used, and calls | ||
95 | * iwl_rx_queue_restock | ||
96 | * iwl_rx_queue_restock() Moves available buffers from rx_free into Rx | ||
97 | * queue, updates firmware pointers, and updates | ||
98 | * the WRITE index. If insufficient rx_free buffers | ||
99 | * are available, schedules iwl_rx_replenish | ||
100 | * | ||
101 | * -- enable interrupts -- | ||
102 | * ISR - iwl_rx() Detach iwl_rx_mem_buffers from pool up to the | ||
103 | * READ INDEX, detaching the SKB from the pool. | ||
104 | * Moves the packet buffer from queue to rx_used. | ||
105 | * Calls iwl_rx_queue_restock to refill any empty | ||
106 | * slots. | ||
107 | * ... | ||
108 | * | ||
109 | */ | ||
110 | |||
111 | /** | ||
112 | * iwl_rx_queue_space - Return number of free slots available in queue. | ||
113 | */ | ||
114 | static int iwl_rx_queue_space(const struct iwl_rx_queue *q) | ||
115 | { | ||
116 | int s = q->read - q->write; | ||
117 | if (s <= 0) | ||
118 | s += RX_QUEUE_SIZE; | ||
119 | /* keep some buffer to not confuse full and empty queue */ | ||
120 | s -= 2; | ||
121 | if (s < 0) | ||
122 | s = 0; | ||
123 | return s; | ||
124 | } | ||
125 | |||
126 | /** | ||
127 | * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue | ||
128 | */ | ||
129 | void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, | ||
130 | struct iwl_rx_queue *q) | ||
131 | { | ||
132 | unsigned long flags; | ||
133 | u32 reg; | ||
134 | |||
135 | spin_lock_irqsave(&q->lock, flags); | ||
136 | |||
137 | if (q->need_update == 0) | ||
138 | goto exit_unlock; | ||
139 | |||
140 | if (priv->cfg->base_params->shadow_reg_enable) { | ||
141 | /* shadow register enabled */ | ||
142 | /* Device expects a multiple of 8 */ | ||
143 | q->write_actual = (q->write & ~0x7); | ||
144 | iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write_actual); | ||
145 | } else { | ||
146 | /* If power-saving is in use, make sure device is awake */ | ||
147 | if (test_bit(STATUS_POWER_PMI, &priv->status)) { | ||
148 | reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); | ||
149 | |||
150 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { | ||
151 | IWL_DEBUG_INFO(priv, | ||
152 | "Rx queue requesting wakeup," | ||
153 | " GP1 = 0x%x\n", reg); | ||
154 | iwl_set_bit(priv, CSR_GP_CNTRL, | ||
155 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
156 | goto exit_unlock; | ||
157 | } | ||
158 | |||
159 | q->write_actual = (q->write & ~0x7); | ||
160 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR, | ||
161 | q->write_actual); | ||
162 | |||
163 | /* Else device is assumed to be awake */ | ||
164 | } else { | ||
165 | /* Device expects a multiple of 8 */ | ||
166 | q->write_actual = (q->write & ~0x7); | ||
167 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR, | ||
168 | q->write_actual); | ||
169 | } | ||
170 | } | ||
171 | q->need_update = 0; | ||
172 | |||
173 | exit_unlock: | ||
174 | spin_unlock_irqrestore(&q->lock, flags); | ||
175 | } | ||
176 | |||
177 | /** | ||
178 | * iwlagn_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr | ||
179 | */ | ||
180 | static inline __le32 iwlagn_dma_addr2rbd_ptr(struct iwl_priv *priv, | ||
181 | dma_addr_t dma_addr) | ||
182 | { | ||
183 | return cpu_to_le32((u32)(dma_addr >> 8)); | ||
184 | } | ||
185 | |||
186 | /** | ||
187 | * iwlagn_rx_queue_restock - refill RX queue from pre-allocated pool | ||
188 | * | ||
189 | * If there are slots in the RX queue that need to be restocked, | ||
190 | * and we have free pre-allocated buffers, fill the ranks as much | ||
191 | * as we can, pulling from rx_free. | ||
192 | * | ||
193 | * This moves the 'write' index forward to catch up with 'processed', and | ||
194 | * also updates the memory address in the firmware to reference the new | ||
195 | * target buffer. | ||
196 | */ | ||
197 | static void iwlagn_rx_queue_restock(struct iwl_priv *priv) | ||
198 | { | ||
199 | struct iwl_rx_queue *rxq = &priv->rxq; | ||
200 | struct list_head *element; | ||
201 | struct iwl_rx_mem_buffer *rxb; | ||
202 | unsigned long flags; | ||
203 | |||
204 | spin_lock_irqsave(&rxq->lock, flags); | ||
205 | while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) { | ||
206 | /* The overwritten rxb must be a used one */ | ||
207 | rxb = rxq->queue[rxq->write]; | ||
208 | BUG_ON(rxb && rxb->page); | ||
209 | |||
210 | /* Get next free Rx buffer, remove from free list */ | ||
211 | element = rxq->rx_free.next; | ||
212 | rxb = list_entry(element, struct iwl_rx_mem_buffer, list); | ||
213 | list_del(element); | ||
214 | |||
215 | /* Point to Rx buffer via next RBD in circular buffer */ | ||
216 | rxq->bd[rxq->write] = iwlagn_dma_addr2rbd_ptr(priv, | ||
217 | rxb->page_dma); | ||
218 | rxq->queue[rxq->write] = rxb; | ||
219 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; | ||
220 | rxq->free_count--; | ||
221 | } | ||
222 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
223 | /* If the pre-allocated buffer pool is dropping low, schedule to | ||
224 | * refill it */ | ||
225 | if (rxq->free_count <= RX_LOW_WATERMARK) | ||
226 | queue_work(priv->workqueue, &priv->rx_replenish); | ||
227 | |||
228 | |||
229 | /* If we've added more space for the firmware to place data, tell it. | ||
230 | * Increment device's write pointer in multiples of 8. */ | ||
231 | if (rxq->write_actual != (rxq->write & ~0x7)) { | ||
232 | spin_lock_irqsave(&rxq->lock, flags); | ||
233 | rxq->need_update = 1; | ||
234 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
235 | iwl_rx_queue_update_write_ptr(priv, rxq); | ||
236 | } | ||
237 | } | ||
238 | |||
239 | /** | ||
240 | * iwlagn_rx_replenish - Move all used packet from rx_used to rx_free | ||
241 | * | ||
242 | * When moving to rx_free an SKB is allocated for the slot. | ||
243 | * | ||
244 | * Also restock the Rx queue via iwl_rx_queue_restock. | ||
245 | * This is called as a scheduled work item (except for during initialization) | ||
246 | */ | ||
247 | static void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority) | ||
248 | { | ||
249 | struct iwl_rx_queue *rxq = &priv->rxq; | ||
250 | struct list_head *element; | ||
251 | struct iwl_rx_mem_buffer *rxb; | ||
252 | struct page *page; | ||
253 | unsigned long flags; | ||
254 | gfp_t gfp_mask = priority; | ||
255 | |||
256 | while (1) { | ||
257 | spin_lock_irqsave(&rxq->lock, flags); | ||
258 | if (list_empty(&rxq->rx_used)) { | ||
259 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
260 | return; | ||
261 | } | ||
262 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
263 | |||
264 | if (rxq->free_count > RX_LOW_WATERMARK) | ||
265 | gfp_mask |= __GFP_NOWARN; | ||
266 | |||
267 | if (priv->hw_params.rx_page_order > 0) | ||
268 | gfp_mask |= __GFP_COMP; | ||
269 | |||
270 | /* Alloc a new receive buffer */ | ||
271 | page = alloc_pages(gfp_mask, priv->hw_params.rx_page_order); | ||
272 | if (!page) { | ||
273 | if (net_ratelimit()) | ||
274 | IWL_DEBUG_INFO(priv, "alloc_pages failed, " | ||
275 | "order: %d\n", | ||
276 | priv->hw_params.rx_page_order); | ||
277 | |||
278 | if ((rxq->free_count <= RX_LOW_WATERMARK) && | ||
279 | net_ratelimit()) | ||
280 | IWL_CRIT(priv, "Failed to alloc_pages with %s." | ||
281 | "Only %u free buffers remaining.\n", | ||
282 | priority == GFP_ATOMIC ? | ||
283 | "GFP_ATOMIC" : "GFP_KERNEL", | ||
284 | rxq->free_count); | ||
285 | /* We don't reschedule replenish work here -- we will | ||
286 | * call the restock method and if it still needs | ||
287 | * more buffers it will schedule replenish */ | ||
288 | return; | ||
289 | } | ||
290 | |||
291 | spin_lock_irqsave(&rxq->lock, flags); | ||
292 | |||
293 | if (list_empty(&rxq->rx_used)) { | ||
294 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
295 | __free_pages(page, priv->hw_params.rx_page_order); | ||
296 | return; | ||
297 | } | ||
298 | element = rxq->rx_used.next; | ||
299 | rxb = list_entry(element, struct iwl_rx_mem_buffer, list); | ||
300 | list_del(element); | ||
301 | |||
302 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
303 | |||
304 | BUG_ON(rxb->page); | ||
305 | rxb->page = page; | ||
306 | /* Get physical address of the RB */ | ||
307 | rxb->page_dma = dma_map_page(priv->bus.dev, page, 0, | ||
308 | PAGE_SIZE << priv->hw_params.rx_page_order, | ||
309 | DMA_FROM_DEVICE); | ||
310 | /* dma address must be no more than 36 bits */ | ||
311 | BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); | ||
312 | /* and also 256 byte aligned! */ | ||
313 | BUG_ON(rxb->page_dma & DMA_BIT_MASK(8)); | ||
314 | |||
315 | spin_lock_irqsave(&rxq->lock, flags); | ||
316 | |||
317 | list_add_tail(&rxb->list, &rxq->rx_free); | ||
318 | rxq->free_count++; | ||
319 | |||
320 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
321 | } | ||
322 | } | ||
323 | |||
324 | void iwlagn_rx_replenish(struct iwl_priv *priv) | ||
325 | { | ||
326 | unsigned long flags; | ||
327 | |||
328 | iwlagn_rx_allocate(priv, GFP_KERNEL); | ||
329 | |||
330 | spin_lock_irqsave(&priv->lock, flags); | ||
331 | iwlagn_rx_queue_restock(priv); | ||
332 | spin_unlock_irqrestore(&priv->lock, flags); | ||
333 | } | ||
334 | |||
335 | static void iwlagn_rx_replenish_now(struct iwl_priv *priv) | ||
336 | { | ||
337 | iwlagn_rx_allocate(priv, GFP_ATOMIC); | ||
338 | |||
339 | iwlagn_rx_queue_restock(priv); | ||
340 | } | ||
341 | |||
342 | void iwl_bg_rx_replenish(struct work_struct *data) | ||
343 | { | ||
344 | struct iwl_priv *priv = | ||
345 | container_of(data, struct iwl_priv, rx_replenish); | ||
346 | |||
347 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
348 | return; | ||
349 | |||
350 | mutex_lock(&priv->mutex); | ||
351 | iwlagn_rx_replenish(priv); | ||
352 | mutex_unlock(&priv->mutex); | ||
353 | } | ||
354 | |||
355 | /** | ||
356 | * iwl_rx_handle - Main entry function for receiving responses from uCode | ||
357 | * | ||
358 | * Uses the priv->rx_handlers callback function array to invoke | ||
359 | * the appropriate handlers, including command responses, | ||
360 | * frame-received notifications, and other notifications. | ||
361 | */ | ||
362 | static void iwl_rx_handle(struct iwl_priv *priv) | ||
363 | { | ||
364 | struct iwl_rx_mem_buffer *rxb; | ||
365 | struct iwl_rx_packet *pkt; | ||
366 | struct iwl_rx_queue *rxq = &priv->rxq; | ||
367 | u32 r, i; | ||
368 | int reclaim; | ||
369 | unsigned long flags; | ||
370 | u8 fill_rx = 0; | ||
371 | u32 count = 8; | ||
372 | int total_empty; | ||
373 | |||
374 | /* uCode's read index (stored in shared DRAM) indicates the last Rx | ||
375 | * buffer that the driver may process (last buffer filled by ucode). */ | ||
376 | r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF; | ||
377 | i = rxq->read; | ||
378 | |||
379 | /* Rx interrupt, but nothing sent from uCode */ | ||
380 | if (i == r) | ||
381 | IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i); | ||
382 | |||
383 | /* calculate total frames need to be restock after handling RX */ | ||
384 | total_empty = r - rxq->write_actual; | ||
385 | if (total_empty < 0) | ||
386 | total_empty += RX_QUEUE_SIZE; | ||
387 | |||
388 | if (total_empty > (RX_QUEUE_SIZE / 2)) | ||
389 | fill_rx = 1; | ||
390 | |||
391 | while (i != r) { | ||
392 | int len; | ||
393 | |||
394 | rxb = rxq->queue[i]; | ||
395 | |||
396 | /* If an RXB doesn't have a Rx queue slot associated with it, | ||
397 | * then a bug has been introduced in the queue refilling | ||
398 | * routines -- catch it here */ | ||
399 | if (WARN_ON(rxb == NULL)) { | ||
400 | i = (i + 1) & RX_QUEUE_MASK; | ||
401 | continue; | ||
402 | } | ||
403 | |||
404 | rxq->queue[i] = NULL; | ||
405 | |||
406 | dma_unmap_page(priv->bus.dev, rxb->page_dma, | ||
407 | PAGE_SIZE << priv->hw_params.rx_page_order, | ||
408 | DMA_FROM_DEVICE); | ||
409 | pkt = rxb_addr(rxb); | ||
410 | |||
411 | IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, | ||
412 | i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); | ||
413 | |||
414 | len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | ||
415 | len += sizeof(u32); /* account for status word */ | ||
416 | trace_iwlwifi_dev_rx(priv, pkt, len); | ||
417 | |||
418 | /* Reclaim a command buffer only if this packet is a response | ||
419 | * to a (driver-originated) command. | ||
420 | * If the packet (e.g. Rx frame) originated from uCode, | ||
421 | * there is no command buffer to reclaim. | ||
422 | * Ucode should set SEQ_RX_FRAME bit if ucode-originated, | ||
423 | * but apparently a few don't get set; catch them here. */ | ||
424 | reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) && | ||
425 | (pkt->hdr.cmd != REPLY_RX_PHY_CMD) && | ||
426 | (pkt->hdr.cmd != REPLY_RX) && | ||
427 | (pkt->hdr.cmd != REPLY_RX_MPDU_CMD) && | ||
428 | (pkt->hdr.cmd != REPLY_COMPRESSED_BA) && | ||
429 | (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && | ||
430 | (pkt->hdr.cmd != REPLY_TX); | ||
431 | |||
432 | iwl_rx_dispatch(priv, rxb); | ||
433 | |||
434 | /* | ||
435 | * XXX: After here, we should always check rxb->page | ||
436 | * against NULL before touching it or its virtual | ||
437 | * memory (pkt). Because some rx_handler might have | ||
438 | * already taken or freed the pages. | ||
439 | */ | ||
440 | |||
441 | if (reclaim) { | ||
442 | /* Invoke any callbacks, transfer the buffer to caller, | ||
443 | * and fire off the (possibly) blocking | ||
444 | * trans_send_cmd() | ||
445 | * as we reclaim the driver command queue */ | ||
446 | if (rxb->page) | ||
447 | iwl_tx_cmd_complete(priv, rxb); | ||
448 | else | ||
449 | IWL_WARN(priv, "Claim null rxb?\n"); | ||
450 | } | ||
451 | |||
452 | /* Reuse the page if possible. For notification packets and | ||
453 | * SKBs that fail to Rx correctly, add them back into the | ||
454 | * rx_free list for reuse later. */ | ||
455 | spin_lock_irqsave(&rxq->lock, flags); | ||
456 | if (rxb->page != NULL) { | ||
457 | rxb->page_dma = dma_map_page(priv->bus.dev, rxb->page, | ||
458 | 0, PAGE_SIZE << priv->hw_params.rx_page_order, | ||
459 | DMA_FROM_DEVICE); | ||
460 | list_add_tail(&rxb->list, &rxq->rx_free); | ||
461 | rxq->free_count++; | ||
462 | } else | ||
463 | list_add_tail(&rxb->list, &rxq->rx_used); | ||
464 | |||
465 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
466 | |||
467 | i = (i + 1) & RX_QUEUE_MASK; | ||
468 | /* If there are a lot of unused frames, | ||
469 | * restock the Rx queue so ucode wont assert. */ | ||
470 | if (fill_rx) { | ||
471 | count++; | ||
472 | if (count >= 8) { | ||
473 | rxq->read = i; | ||
474 | iwlagn_rx_replenish_now(priv); | ||
475 | count = 0; | ||
476 | } | ||
477 | } | ||
478 | } | ||
479 | |||
480 | /* Backtrack one entry */ | ||
481 | rxq->read = i; | ||
482 | if (fill_rx) | ||
483 | iwlagn_rx_replenish_now(priv); | ||
484 | else | ||
485 | iwlagn_rx_queue_restock(priv); | ||
486 | } | ||
487 | |||
488 | /* tasklet for iwlagn interrupt */ | ||
489 | void iwl_irq_tasklet(struct iwl_priv *priv) | ||
490 | { | ||
491 | u32 inta = 0; | ||
492 | u32 handled = 0; | ||
493 | unsigned long flags; | ||
494 | u32 i; | ||
495 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
496 | u32 inta_mask; | ||
497 | #endif | ||
498 | |||
499 | spin_lock_irqsave(&priv->lock, flags); | ||
500 | |||
501 | /* Ack/clear/reset pending uCode interrupts. | ||
502 | * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, | ||
503 | */ | ||
504 | /* There is a hardware bug in the interrupt mask function that some | ||
505 | * interrupts (i.e. CSR_INT_BIT_SCD) can still be generated even if | ||
506 | * they are disabled in the CSR_INT_MASK register. Furthermore the | ||
507 | * ICT interrupt handling mechanism has another bug that might cause | ||
508 | * these unmasked interrupts fail to be detected. We workaround the | ||
509 | * hardware bugs here by ACKing all the possible interrupts so that | ||
510 | * interrupt coalescing can still be achieved. | ||
511 | */ | ||
512 | iwl_write32(priv, CSR_INT, priv->_agn.inta | ~priv->inta_mask); | ||
513 | |||
514 | inta = priv->_agn.inta; | ||
515 | |||
516 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
517 | if (iwl_get_debug_level(priv) & IWL_DL_ISR) { | ||
518 | /* just for debug */ | ||
519 | inta_mask = iwl_read32(priv, CSR_INT_MASK); | ||
520 | IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x\n ", | ||
521 | inta, inta_mask); | ||
522 | } | ||
523 | #endif | ||
524 | |||
525 | spin_unlock_irqrestore(&priv->lock, flags); | ||
526 | |||
527 | /* saved interrupt in inta variable now we can reset priv->_agn.inta */ | ||
528 | priv->_agn.inta = 0; | ||
529 | |||
530 | /* Now service all interrupt bits discovered above. */ | ||
531 | if (inta & CSR_INT_BIT_HW_ERR) { | ||
532 | IWL_ERR(priv, "Hardware error detected. Restarting.\n"); | ||
533 | |||
534 | /* Tell the device to stop sending interrupts */ | ||
535 | iwl_disable_interrupts(priv); | ||
536 | |||
537 | priv->isr_stats.hw++; | ||
538 | iwl_irq_handle_error(priv); | ||
539 | |||
540 | handled |= CSR_INT_BIT_HW_ERR; | ||
541 | |||
542 | return; | ||
543 | } | ||
544 | |||
545 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
546 | if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) { | ||
547 | /* NIC fires this, but we don't use it, redundant with WAKEUP */ | ||
548 | if (inta & CSR_INT_BIT_SCD) { | ||
549 | IWL_DEBUG_ISR(priv, "Scheduler finished to transmit " | ||
550 | "the frame/frames.\n"); | ||
551 | priv->isr_stats.sch++; | ||
552 | } | ||
553 | |||
554 | /* Alive notification via Rx interrupt will do the real work */ | ||
555 | if (inta & CSR_INT_BIT_ALIVE) { | ||
556 | IWL_DEBUG_ISR(priv, "Alive interrupt\n"); | ||
557 | priv->isr_stats.alive++; | ||
558 | } | ||
559 | } | ||
560 | #endif | ||
561 | /* Safely ignore these bits for debug checks below */ | ||
562 | inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE); | ||
563 | |||
564 | /* HW RF KILL switch toggled */ | ||
565 | if (inta & CSR_INT_BIT_RF_KILL) { | ||
566 | int hw_rf_kill = 0; | ||
567 | if (!(iwl_read32(priv, CSR_GP_CNTRL) & | ||
568 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) | ||
569 | hw_rf_kill = 1; | ||
570 | |||
571 | IWL_WARN(priv, "RF_KILL bit toggled to %s.\n", | ||
572 | hw_rf_kill ? "disable radio" : "enable radio"); | ||
573 | |||
574 | priv->isr_stats.rfkill++; | ||
575 | |||
576 | /* driver only loads ucode once setting the interface up. | ||
577 | * the driver allows loading the ucode even if the radio | ||
578 | * is killed. Hence update the killswitch state here. The | ||
579 | * rfkill handler will care about restarting if needed. | ||
580 | */ | ||
581 | if (!test_bit(STATUS_ALIVE, &priv->status)) { | ||
582 | if (hw_rf_kill) | ||
583 | set_bit(STATUS_RF_KILL_HW, &priv->status); | ||
584 | else | ||
585 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | ||
586 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill); | ||
587 | } | ||
588 | |||
589 | handled |= CSR_INT_BIT_RF_KILL; | ||
590 | } | ||
591 | |||
592 | /* Chip got too hot and stopped itself */ | ||
593 | if (inta & CSR_INT_BIT_CT_KILL) { | ||
594 | IWL_ERR(priv, "Microcode CT kill error detected.\n"); | ||
595 | priv->isr_stats.ctkill++; | ||
596 | handled |= CSR_INT_BIT_CT_KILL; | ||
597 | } | ||
598 | |||
599 | /* Error detected by uCode */ | ||
600 | if (inta & CSR_INT_BIT_SW_ERR) { | ||
601 | IWL_ERR(priv, "Microcode SW error detected. " | ||
602 | " Restarting 0x%X.\n", inta); | ||
603 | priv->isr_stats.sw++; | ||
604 | iwl_irq_handle_error(priv); | ||
605 | handled |= CSR_INT_BIT_SW_ERR; | ||
606 | } | ||
607 | |||
608 | /* uCode wakes up after power-down sleep */ | ||
609 | if (inta & CSR_INT_BIT_WAKEUP) { | ||
610 | IWL_DEBUG_ISR(priv, "Wakeup interrupt\n"); | ||
611 | iwl_rx_queue_update_write_ptr(priv, &priv->rxq); | ||
612 | for (i = 0; i < priv->hw_params.max_txq_num; i++) | ||
613 | iwl_txq_update_write_ptr(priv, &priv->txq[i]); | ||
614 | |||
615 | priv->isr_stats.wakeup++; | ||
616 | |||
617 | handled |= CSR_INT_BIT_WAKEUP; | ||
618 | } | ||
619 | |||
620 | /* All uCode command responses, including Tx command responses, | ||
621 | * Rx "responses" (frame-received notification), and other | ||
622 | * notifications from uCode come through here*/ | ||
623 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX | | ||
624 | CSR_INT_BIT_RX_PERIODIC)) { | ||
625 | IWL_DEBUG_ISR(priv, "Rx interrupt\n"); | ||
626 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { | ||
627 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); | ||
628 | iwl_write32(priv, CSR_FH_INT_STATUS, | ||
629 | CSR_FH_INT_RX_MASK); | ||
630 | } | ||
631 | if (inta & CSR_INT_BIT_RX_PERIODIC) { | ||
632 | handled |= CSR_INT_BIT_RX_PERIODIC; | ||
633 | iwl_write32(priv, CSR_INT, CSR_INT_BIT_RX_PERIODIC); | ||
634 | } | ||
635 | /* Sending RX interrupt require many steps to be done in the | ||
636 | * the device: | ||
637 | * 1- write interrupt to current index in ICT table. | ||
638 | * 2- dma RX frame. | ||
639 | * 3- update RX shared data to indicate last write index. | ||
640 | * 4- send interrupt. | ||
641 | * This could lead to RX race, driver could receive RX interrupt | ||
642 | * but the shared data changes does not reflect this; | ||
643 | * periodic interrupt will detect any dangling Rx activity. | ||
644 | */ | ||
645 | |||
646 | /* Disable periodic interrupt; we use it as just a one-shot. */ | ||
647 | iwl_write8(priv, CSR_INT_PERIODIC_REG, | ||
648 | CSR_INT_PERIODIC_DIS); | ||
649 | iwl_rx_handle(priv); | ||
650 | |||
651 | /* | ||
652 | * Enable periodic interrupt in 8 msec only if we received | ||
653 | * real RX interrupt (instead of just periodic int), to catch | ||
654 | * any dangling Rx interrupt. If it was just the periodic | ||
655 | * interrupt, there was no dangling Rx activity, and no need | ||
656 | * to extend the periodic interrupt; one-shot is enough. | ||
657 | */ | ||
658 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) | ||
659 | iwl_write8(priv, CSR_INT_PERIODIC_REG, | ||
660 | CSR_INT_PERIODIC_ENA); | ||
661 | |||
662 | priv->isr_stats.rx++; | ||
663 | } | ||
664 | |||
665 | /* This "Tx" DMA channel is used only for loading uCode */ | ||
666 | if (inta & CSR_INT_BIT_FH_TX) { | ||
667 | iwl_write32(priv, CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK); | ||
668 | IWL_DEBUG_ISR(priv, "uCode load interrupt\n"); | ||
669 | priv->isr_stats.tx++; | ||
670 | handled |= CSR_INT_BIT_FH_TX; | ||
671 | /* Wake up uCode load routine, now that load is complete */ | ||
672 | priv->ucode_write_complete = 1; | ||
673 | wake_up_interruptible(&priv->wait_command_queue); | ||
674 | } | ||
675 | |||
676 | if (inta & ~handled) { | ||
677 | IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled); | ||
678 | priv->isr_stats.unhandled++; | ||
679 | } | ||
680 | |||
681 | if (inta & ~(priv->inta_mask)) { | ||
682 | IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n", | ||
683 | inta & ~priv->inta_mask); | ||
684 | } | ||
685 | |||
686 | /* Re-enable all interrupts */ | ||
687 | /* only Re-enable if disabled by irq */ | ||
688 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) | ||
689 | iwl_enable_interrupts(priv); | ||
690 | /* Re-enable RF_KILL if it occurred */ | ||
691 | else if (handled & CSR_INT_BIT_RF_KILL) | ||
692 | iwl_enable_rfkill_int(priv); | ||
693 | } | ||
694 | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index ca9690287100..6b7cb73442bf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c | |||
@@ -64,6 +64,7 @@ | |||
64 | #include "iwl-trans.h" | 64 | #include "iwl-trans.h" |
65 | #include "iwl-core.h" | 65 | #include "iwl-core.h" |
66 | #include "iwl-helpers.h" | 66 | #include "iwl-helpers.h" |
67 | #include "iwl-trans-int-pcie.h" | ||
67 | /*TODO remove uneeded includes when the transport layer tx_free will be here */ | 68 | /*TODO remove uneeded includes when the transport layer tx_free will be here */ |
68 | #include "iwl-agn.h" | 69 | #include "iwl-agn.h" |
69 | #include "iwl-core.h" | 70 | #include "iwl-core.h" |
@@ -127,6 +128,55 @@ static void iwl_trans_rxq_free_rx_bufs(struct iwl_priv *priv) | |||
127 | } | 128 | } |
128 | } | 129 | } |
129 | 130 | ||
131 | static void iwl_trans_rx_hw_init(struct iwl_priv *priv, | ||
132 | struct iwl_rx_queue *rxq) | ||
133 | { | ||
134 | u32 rb_size; | ||
135 | const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ | ||
136 | u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */ | ||
137 | |||
138 | rb_timeout = RX_RB_TIMEOUT; | ||
139 | |||
140 | if (iwlagn_mod_params.amsdu_size_8K) | ||
141 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; | ||
142 | else | ||
143 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; | ||
144 | |||
145 | /* Stop Rx DMA */ | ||
146 | iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); | ||
147 | |||
148 | /* Reset driver's Rx queue write index */ | ||
149 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); | ||
150 | |||
151 | /* Tell device where to find RBD circular buffer in DRAM */ | ||
152 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG, | ||
153 | (u32)(rxq->bd_dma >> 8)); | ||
154 | |||
155 | /* Tell device where in DRAM to update its Rx status */ | ||
156 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, | ||
157 | rxq->rb_stts_dma >> 4); | ||
158 | |||
159 | /* Enable Rx DMA | ||
160 | * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in | ||
161 | * the credit mechanism in 5000 HW RX FIFO | ||
162 | * Direct rx interrupts to hosts | ||
163 | * Rx buffer size 4 or 8k | ||
164 | * RB timeout 0x10 | ||
165 | * 256 RBDs | ||
166 | */ | ||
167 | iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, | ||
168 | FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | | ||
169 | FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | | ||
170 | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | | ||
171 | FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MSK | | ||
172 | rb_size| | ||
173 | (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)| | ||
174 | (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); | ||
175 | |||
176 | /* Set interrupt coalescing timer to default (2048 usecs) */ | ||
177 | iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); | ||
178 | } | ||
179 | |||
130 | static int iwl_trans_rx_init(struct iwl_priv *priv) | 180 | static int iwl_trans_rx_init(struct iwl_priv *priv) |
131 | { | 181 | { |
132 | struct iwl_rx_queue *rxq = &priv->rxq; | 182 | struct iwl_rx_queue *rxq = &priv->rxq; |
@@ -155,6 +205,15 @@ static int iwl_trans_rx_init(struct iwl_priv *priv) | |||
155 | rxq->free_count = 0; | 205 | rxq->free_count = 0; |
156 | spin_unlock_irqrestore(&rxq->lock, flags); | 206 | spin_unlock_irqrestore(&rxq->lock, flags); |
157 | 207 | ||
208 | iwlagn_rx_replenish(priv); | ||
209 | |||
210 | iwl_trans_rx_hw_init(priv, rxq); | ||
211 | |||
212 | spin_lock_irqsave(&priv->lock, flags); | ||
213 | rxq->need_update = 1; | ||
214 | iwl_rx_queue_update_write_ptr(priv, rxq); | ||
215 | spin_unlock_irqrestore(&priv->lock, flags); | ||
216 | |||
158 | return 0; | 217 | return 0; |
159 | } | 218 | } |
160 | 219 | ||
@@ -756,5 +815,7 @@ int iwl_trans_register(struct iwl_priv *priv) | |||
756 | tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) | 815 | tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) |
757 | iwl_irq_tasklet, (unsigned long)priv); | 816 | iwl_irq_tasklet, (unsigned long)priv); |
758 | 817 | ||
818 | INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); | ||
819 | |||
759 | return 0; | 820 | return 0; |
760 | } | 821 | } |