diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi/pci.c')
-rw-r--r-- | drivers/net/wireless/rtlwifi/pci.c | 39 |
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 | ||
806 | static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) | 803 | static 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 | ||
938 | static void _rtl_pci_ips_leave_tasklet(struct ieee80211_hw *hw) | ||
939 | { | ||
940 | rtl_lps_leave(hw); | ||
941 | } | ||
942 | |||
941 | static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) | 943 | static 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 | ||
1041 | static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, | 1046 | static 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) { |