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.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 9f8ccae93317..e502db0532e5 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;
@@ -763,15 +764,12 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
763 if (((rtlpriv->link_info.num_rx_inperiod + 764 if (((rtlpriv->link_info.num_rx_inperiod +
764 rtlpriv->link_info.num_tx_inperiod) > 8) || 765 rtlpriv->link_info.num_tx_inperiod) > 8) ||
765 (rtlpriv->link_info.num_rx_inperiod > 2)) { 766 (rtlpriv->link_info.num_rx_inperiod > 2)) {
766 rtl_lps_leave(hw); 767 tasklet_schedule(&rtlpriv->works.ips_leave_tasklet);
767 } 768 }
768 769
769 skb = new_skb; 770 skb = new_skb;
770 771
771 rtlpci->rx_ring[rx_queue_idx].rx_buf[rtlpci-> 772 rtlpci->rx_ring[rx_queue_idx].rx_buf[index] = skb;
772 rx_ring
773 [rx_queue_idx].
774 idx] = skb;
775 *((dma_addr_t *) skb->cb) = 773 *((dma_addr_t *) skb->cb) =
776 pci_map_single(rtlpci->pdev, skb_tail_pointer(skb), 774 pci_map_single(rtlpci->pdev, skb_tail_pointer(skb),
777 rtlpci->rxbuffersize, 775 rtlpci->rxbuffersize,
@@ -784,23 +782,22 @@ done:
784 rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false, 782 rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false,
785 HW_DESC_RXBUFF_ADDR, 783 HW_DESC_RXBUFF_ADDR,
786 (u8 *)&bufferaddress); 784 (u8 *)&bufferaddress);
787 rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN,
788 (u8 *)&tmp_one);
789 rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, 785 rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false,
790 HW_DESC_RXPKT_LEN, 786 HW_DESC_RXPKT_LEN,
791 (u8 *)&rtlpci->rxbuffersize); 787 (u8 *)&rtlpci->rxbuffersize);
792 788
793 if (rtlpci->rx_ring[rx_queue_idx].idx == 789 if (index == rtlpci->rxringcount - 1)
794 rtlpci->rxringcount - 1)
795 rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, 790 rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false,
796 HW_DESC_RXERO, 791 HW_DESC_RXERO,
797 (u8 *)&tmp_one); 792 (u8 *)&tmp_one);
798 793
799 rtlpci->rx_ring[rx_queue_idx].idx = 794 rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN,
800 (rtlpci->rx_ring[rx_queue_idx].idx + 1) % 795 (u8 *)&tmp_one);
801 rtlpci->rxringcount; 796
797 index = (index + 1) % rtlpci->rxringcount;
802 } 798 }
803 799
800 rtlpci->rx_ring[rx_queue_idx].idx = index;
804} 801}
805 802
806static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) 803static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
@@ -938,6 +935,11 @@ static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw)
938 _rtl_pci_tx_chk_waitq(hw); 935 _rtl_pci_tx_chk_waitq(hw);
939} 936}
940 937
938static void _rtl_pci_ips_leave_tasklet(struct ieee80211_hw *hw)
939{
940 rtl_lps_leave(hw);
941}
942
941static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) 943static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
942{ 944{
943 struct rtl_priv *rtlpriv = rtl_priv(hw); 945 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -1036,6 +1038,9 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw,
1036 tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet, 1038 tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet,
1037 (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet, 1039 (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet,
1038 (unsigned long)hw); 1040 (unsigned long)hw);
1041 tasklet_init(&rtlpriv->works.ips_leave_tasklet,
1042 (void (*)(unsigned long))_rtl_pci_ips_leave_tasklet,
1043 (unsigned long)hw);
1039} 1044}
1040 1045
1041static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, 1046static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw,
@@ -1505,6 +1510,7 @@ static void rtl_pci_deinit(struct ieee80211_hw *hw)
1505 1510
1506 synchronize_irq(rtlpci->pdev->irq); 1511 synchronize_irq(rtlpci->pdev->irq);
1507 tasklet_kill(&rtlpriv->works.irq_tasklet); 1512 tasklet_kill(&rtlpriv->works.irq_tasklet);
1513 tasklet_kill(&rtlpriv->works.ips_leave_tasklet);
1508 1514
1509 flush_workqueue(rtlpriv->works.rtl_wq); 1515 flush_workqueue(rtlpriv->works.rtl_wq);
1510 destroy_workqueue(rtlpriv->works.rtl_wq); 1516 destroy_workqueue(rtlpriv->works.rtl_wq);
@@ -1579,6 +1585,7 @@ static void rtl_pci_stop(struct ieee80211_hw *hw)
1579 set_hal_stop(rtlhal); 1585 set_hal_stop(rtlhal);
1580 1586
1581 rtlpriv->cfg->ops->disable_interrupt(hw); 1587 rtlpriv->cfg->ops->disable_interrupt(hw);
1588 tasklet_kill(&rtlpriv->works.ips_leave_tasklet);
1582 1589
1583 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); 1590 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
1584 while (ppsc->rfchange_inprogress) { 1591 while (ppsc->rfchange_inprogress) {