aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtlwifi/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rtlwifi/pci.c')
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 89100e7c553b..fc44005b0d53 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -622,7 +622,7 @@ tx_status_ok:
622 if (((rtlpriv->link_info.num_rx_inperiod + 622 if (((rtlpriv->link_info.num_rx_inperiod +
623 rtlpriv->link_info.num_tx_inperiod) > 8) || 623 rtlpriv->link_info.num_tx_inperiod) > 8) ||
624 (rtlpriv->link_info.num_rx_inperiod > 2)) { 624 (rtlpriv->link_info.num_rx_inperiod > 2)) {
625 rtl_lps_leave(hw); 625 tasklet_schedule(&rtlpriv->works.ips_leave_tasklet);
626 } 626 }
627} 627}
628 628
@@ -644,22 +644,23 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
644 .noise = -98, 644 .noise = -98,
645 .rate = 0, 645 .rate = 0,
646 }; 646 };
647 int index = rtlpci->rx_ring[rx_queue_idx].idx;
647 648
648 /*RX NORMAL PKT */ 649 /*RX NORMAL PKT */
649 while (count--) { 650 while (count--) {
650 /*rx descriptor */ 651 /*rx descriptor */
651 struct rtl_rx_desc *pdesc = &rtlpci->rx_ring[rx_queue_idx].desc[ 652 struct rtl_rx_desc *pdesc = &rtlpci->rx_ring[rx_queue_idx].desc[
652 rtlpci->rx_ring[rx_queue_idx].idx]; 653 index];
653 /*rx pkt */ 654 /*rx pkt */
654 struct sk_buff *skb = rtlpci->rx_ring[rx_queue_idx].rx_buf[ 655 struct sk_buff *skb = rtlpci->rx_ring[rx_queue_idx].rx_buf[
655 rtlpci->rx_ring[rx_queue_idx].idx]; 656 index];
656 657
657 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, 658 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc,
658 false, HW_DESC_OWN); 659 false, HW_DESC_OWN);
659 660
660 if (own) { 661 if (own) {
661 /*wait data to be filled by hardware */ 662 /*wait data to be filled by hardware */
662 return; 663 break;
663 } else { 664 } else {
664 struct ieee80211_hdr *hdr; 665 struct ieee80211_hdr *hdr;
665 __le16 fc; 666 __le16 fc;
@@ -700,7 +701,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
700 rtlpci->rxbuffersize, 701 rtlpci->rxbuffersize,
701 PCI_DMA_FROMDEVICE); 702 PCI_DMA_FROMDEVICE);
702 703
703 if (!stats.crc || !stats.hwerror) { 704 if (!stats.crc && !stats.hwerror) {
704 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, 705 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status,
705 sizeof(rx_status)); 706 sizeof(rx_status));
706 707
@@ -765,15 +766,12 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
765 if (((rtlpriv->link_info.num_rx_inperiod + 766 if (((rtlpriv->link_info.num_rx_inperiod +
766 rtlpriv->link_info.num_tx_inperiod) > 8) || 767 rtlpriv->link_info.num_tx_inperiod) > 8) ||
767 (rtlpriv->link_info.num_rx_inperiod > 2)) { 768 (rtlpriv->link_info.num_rx_inperiod > 2)) {
768 rtl_lps_leave(hw); 769 tasklet_schedule(&rtlpriv->works.ips_leave_tasklet);
769 } 770 }
770 771
771 skb = new_skb; 772 skb = new_skb;
772 773
773 rtlpci->rx_ring[rx_queue_idx].rx_buf[rtlpci-> 774 rtlpci->rx_ring[rx_queue_idx].rx_buf[index] = skb;
774 rx_ring
775 [rx_queue_idx].
776 idx] = skb;
777 *((dma_addr_t *) skb->cb) = 775 *((dma_addr_t *) skb->cb) =
778 pci_map_single(rtlpci->pdev, skb_tail_pointer(skb), 776 pci_map_single(rtlpci->pdev, skb_tail_pointer(skb),
779 rtlpci->rxbuffersize, 777 rtlpci->rxbuffersize,
@@ -786,23 +784,22 @@ done:
786 rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false, 784 rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false,
787 HW_DESC_RXBUFF_ADDR, 785 HW_DESC_RXBUFF_ADDR,
788 (u8 *)&bufferaddress); 786 (u8 *)&bufferaddress);
789 rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN,
790 (u8 *)&tmp_one);
791 rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, 787 rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false,
792 HW_DESC_RXPKT_LEN, 788 HW_DESC_RXPKT_LEN,
793 (u8 *)&rtlpci->rxbuffersize); 789 (u8 *)&rtlpci->rxbuffersize);
794 790
795 if (rtlpci->rx_ring[rx_queue_idx].idx == 791 if (index == rtlpci->rxringcount - 1)
796 rtlpci->rxringcount - 1)
797 rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, 792 rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false,
798 HW_DESC_RXERO, 793 HW_DESC_RXERO,
799 (u8 *)&tmp_one); 794 (u8 *)&tmp_one);
800 795
801 rtlpci->rx_ring[rx_queue_idx].idx = 796 rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN,
802 (rtlpci->rx_ring[rx_queue_idx].idx + 1) % 797 (u8 *)&tmp_one);
803 rtlpci->rxringcount; 798
799 index = (index + 1) % rtlpci->rxringcount;
804 } 800 }
805 801
802 rtlpci->rx_ring[rx_queue_idx].idx = index;
806} 803}
807 804
808static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) 805static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
@@ -940,6 +937,11 @@ static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw)
940 _rtl_pci_tx_chk_waitq(hw); 937 _rtl_pci_tx_chk_waitq(hw);
941} 938}
942 939
940static void _rtl_pci_ips_leave_tasklet(struct ieee80211_hw *hw)
941{
942 rtl_lps_leave(hw);
943}
944
943static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) 945static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
944{ 946{
945 struct rtl_priv *rtlpriv = rtl_priv(hw); 947 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -1038,6 +1040,9 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw,
1038 tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet, 1040 tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet,
1039 (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet, 1041 (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet,
1040 (unsigned long)hw); 1042 (unsigned long)hw);
1043 tasklet_init(&rtlpriv->works.ips_leave_tasklet,
1044 (void (*)(unsigned long))_rtl_pci_ips_leave_tasklet,
1045 (unsigned long)hw);
1041} 1046}
1042 1047
1043static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, 1048static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw,
@@ -1507,6 +1512,7 @@ static void rtl_pci_deinit(struct ieee80211_hw *hw)
1507 1512
1508 synchronize_irq(rtlpci->pdev->irq); 1513 synchronize_irq(rtlpci->pdev->irq);
1509 tasklet_kill(&rtlpriv->works.irq_tasklet); 1514 tasklet_kill(&rtlpriv->works.irq_tasklet);
1515 tasklet_kill(&rtlpriv->works.ips_leave_tasklet);
1510 1516
1511 flush_workqueue(rtlpriv->works.rtl_wq); 1517 flush_workqueue(rtlpriv->works.rtl_wq);
1512 destroy_workqueue(rtlpriv->works.rtl_wq); 1518 destroy_workqueue(rtlpriv->works.rtl_wq);
@@ -1581,6 +1587,7 @@ static void rtl_pci_stop(struct ieee80211_hw *hw)
1581 set_hal_stop(rtlhal); 1587 set_hal_stop(rtlhal);
1582 1588
1583 rtlpriv->cfg->ops->disable_interrupt(hw); 1589 rtlpriv->cfg->ops->disable_interrupt(hw);
1590 tasklet_kill(&rtlpriv->works.ips_leave_tasklet);
1584 1591
1585 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); 1592 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
1586 while (ppsc->rfchange_inprogress) { 1593 while (ppsc->rfchange_inprogress) {