aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtlwifi
diff options
context:
space:
mode:
authorTroy Tan <troy_tan@realsil.com.cn>2015-02-03 12:15:17 -0500
committerKalle Valo <kvalo@codeaurora.org>2015-02-06 01:36:00 -0500
commitd0311314d00298f83aa5450a1d4a92889e7cc2ea (patch)
treed35d17b893589fc42b2ff8f54af8465155bb32e2 /drivers/net/wireless/rtlwifi
parent7201472ed376882927ecc0d917acec6cc1610c80 (diff)
rtlwifi: rtl8192ee: Fix handling of new style descriptors
The hardware and firmware for the RTL8192EE utilize a FIFO list of descriptors. There were some problems with the initial implementation. The worst of these failed to detect that the FIFO was becoming full, which led to the device needing to be power cycled. As this condition is not relevant to most of the devices supported by rtlwifi, a callback routine was added to detect this situation. This patch implements the necessary changes in the pci handler, and the linkage into the appropriate rtl8192ee routine. Signed-off-by: Troy Tan <troy_tan@realsil.com.cn> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Cc: Stable <stable@vger.kernel.org> [V3.18] Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/rtlwifi')
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c31
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ee/sw.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ee/trx.c20
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ee/trx.h1
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h1
5 files changed, 46 insertions, 10 deletions
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 846a2e6e34d8..88331d729b0e 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -578,6 +578,13 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
578 else 578 else
579 entry = (u8 *)(&ring->desc[ring->idx]); 579 entry = (u8 *)(&ring->desc[ring->idx]);
580 580
581 if (rtlpriv->cfg->ops->get_available_desc &&
582 rtlpriv->cfg->ops->get_available_desc(hw, prio) <= 1) {
583 RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_DMESG,
584 "no available desc!\n");
585 return;
586 }
587
581 if (!rtlpriv->cfg->ops->is_tx_desc_closed(hw, prio, ring->idx)) 588 if (!rtlpriv->cfg->ops->is_tx_desc_closed(hw, prio, ring->idx))
582 return; 589 return;
583 ring->idx = (ring->idx + 1) % ring->entries; 590 ring->idx = (ring->idx + 1) % ring->entries;
@@ -641,10 +648,9 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
641 648
642 ieee80211_tx_status_irqsafe(hw, skb); 649 ieee80211_tx_status_irqsafe(hw, skb);
643 650
644 if ((ring->entries - skb_queue_len(&ring->queue)) 651 if ((ring->entries - skb_queue_len(&ring->queue)) <= 4) {
645 == 2) {
646 652
647 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, 653 RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
648 "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%x\n", 654 "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%x\n",
649 prio, ring->idx, 655 prio, ring->idx,
650 skb_queue_len(&ring->queue)); 656 skb_queue_len(&ring->queue));
@@ -786,7 +792,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
786 rx_remained_cnt = 792 rx_remained_cnt =
787 rtlpriv->cfg->ops->rx_desc_buff_remained_cnt(hw, 793 rtlpriv->cfg->ops->rx_desc_buff_remained_cnt(hw,
788 hw_queue); 794 hw_queue);
789 if (rx_remained_cnt < 1) 795 if (rx_remained_cnt == 0)
790 return; 796 return;
791 797
792 } else { /* rx descriptor */ 798 } else { /* rx descriptor */
@@ -834,18 +840,18 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
834 else 840 else
835 skb_reserve(skb, stats.rx_drvinfo_size + 841 skb_reserve(skb, stats.rx_drvinfo_size +
836 stats.rx_bufshift); 842 stats.rx_bufshift);
837
838 } else { 843 } else {
839 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 844 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
840 "skb->end - skb->tail = %d, len is %d\n", 845 "skb->end - skb->tail = %d, len is %d\n",
841 skb->end - skb->tail, len); 846 skb->end - skb->tail, len);
842 break; 847 dev_kfree_skb_any(skb);
848 goto new_trx_end;
843 } 849 }
844 /* handle command packet here */ 850 /* handle command packet here */
845 if (rtlpriv->cfg->ops->rx_command_packet && 851 if (rtlpriv->cfg->ops->rx_command_packet &&
846 rtlpriv->cfg->ops->rx_command_packet(hw, stats, skb)) { 852 rtlpriv->cfg->ops->rx_command_packet(hw, stats, skb)) {
847 dev_kfree_skb_any(skb); 853 dev_kfree_skb_any(skb);
848 goto end; 854 goto new_trx_end;
849 } 855 }
850 856
851 /* 857 /*
@@ -895,6 +901,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
895 } else { 901 } else {
896 dev_kfree_skb_any(skb); 902 dev_kfree_skb_any(skb);
897 } 903 }
904new_trx_end:
898 if (rtlpriv->use_new_trx_flow) { 905 if (rtlpriv->use_new_trx_flow) {
899 rtlpci->rx_ring[hw_queue].next_rx_rp += 1; 906 rtlpci->rx_ring[hw_queue].next_rx_rp += 1;
900 rtlpci->rx_ring[hw_queue].next_rx_rp %= 907 rtlpci->rx_ring[hw_queue].next_rx_rp %=
@@ -910,7 +917,6 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
910 rtlpriv->enter_ps = false; 917 rtlpriv->enter_ps = false;
911 schedule_work(&rtlpriv->works.lps_change_work); 918 schedule_work(&rtlpriv->works.lps_change_work);
912 } 919 }
913end:
914 if (rtlpriv->use_new_trx_flow) { 920 if (rtlpriv->use_new_trx_flow) {
915 _rtl_pci_init_one_rxdesc(hw, (u8 *)buffer_desc, 921 _rtl_pci_init_one_rxdesc(hw, (u8 *)buffer_desc,
916 rxring_idx, 922 rxring_idx,
@@ -1672,6 +1678,15 @@ static int rtl_pci_tx(struct ieee80211_hw *hw,
1672 } 1678 }
1673 } 1679 }
1674 1680
1681 if (rtlpriv->cfg->ops->get_available_desc &&
1682 rtlpriv->cfg->ops->get_available_desc(hw, hw_queue) == 0) {
1683 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1684 "get_available_desc fail\n");
1685 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock,
1686 flags);
1687 return skb->len;
1688 }
1689
1675 if (ieee80211_is_data_qos(fc)) { 1690 if (ieee80211_is_data_qos(fc)) {
1676 tid = rtl_get_tid(skb); 1691 tid = rtl_get_tid(skb);
1677 if (sta) { 1692 if (sta) {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ee/sw.c
index 9b5a7d5be121..c31c6bfb536d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ee/sw.c
@@ -113,8 +113,6 @@ int rtl92ee_init_sw_vars(struct ieee80211_hw *hw)
113 RCR_HTC_LOC_CTRL | 113 RCR_HTC_LOC_CTRL |
114 RCR_AMF | 114 RCR_AMF |
115 RCR_ACF | 115 RCR_ACF |
116 RCR_ADF |
117 RCR_AICV |
118 RCR_ACRC32 | 116 RCR_ACRC32 |
119 RCR_AB | 117 RCR_AB |
120 RCR_AM | 118 RCR_AM |
@@ -241,6 +239,7 @@ static struct rtl_hal_ops rtl8192ee_hal_ops = {
241 .set_desc = rtl92ee_set_desc, 239 .set_desc = rtl92ee_set_desc,
242 .get_desc = rtl92ee_get_desc, 240 .get_desc = rtl92ee_get_desc,
243 .is_tx_desc_closed = rtl92ee_is_tx_desc_closed, 241 .is_tx_desc_closed = rtl92ee_is_tx_desc_closed,
242 .get_available_desc = rtl92ee_get_available_desc,
244 .tx_polling = rtl92ee_tx_polling, 243 .tx_polling = rtl92ee_tx_polling,
245 .enable_hw_sec = rtl92ee_enable_hw_security_config, 244 .enable_hw_sec = rtl92ee_enable_hw_security_config,
246 .set_key = rtl92ee_set_key, 245 .set_key = rtl92ee_set_key,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ee/trx.c
index 2b60bdc7452f..1245e2f53c8d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ee/trx.c
@@ -555,6 +555,26 @@ static u16 get_desc_addr_fr_q_idx(u16 queue_index)
555 return desc_address; 555 return desc_address;
556} 556}
557 557
558u16 rtl92ee_get_available_desc(struct ieee80211_hw *hw, u8 q_idx)
559{
560 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
561 struct rtl_priv *rtlpriv = rtl_priv(hw);
562 u16 point_diff = 0;
563 u16 current_tx_read_point = 0, current_tx_write_point = 0;
564 u32 tmp_4byte;
565
566 tmp_4byte = rtl_read_dword(rtlpriv,
567 get_desc_addr_fr_q_idx(q_idx));
568 current_tx_read_point = (u16)((tmp_4byte >> 16) & 0x0fff);
569 current_tx_write_point = (u16)((tmp_4byte) & 0x0fff);
570
571 point_diff = calc_fifo_space(current_tx_read_point,
572 current_tx_write_point);
573
574 rtlpci->tx_ring[q_idx].avl_desc = point_diff;
575 return point_diff;
576}
577
558void rtl92ee_pre_fill_tx_bd_desc(struct ieee80211_hw *hw, 578void rtl92ee_pre_fill_tx_bd_desc(struct ieee80211_hw *hw,
559 u8 *tx_bd_desc, u8 *desc, u8 queue_index, 579 u8 *tx_bd_desc, u8 *desc, u8 queue_index,
560 struct sk_buff *skb, dma_addr_t addr) 580 struct sk_buff *skb, dma_addr_t addr)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/trx.h b/drivers/net/wireless/rtlwifi/rtl8192ee/trx.h
index 5abb749b33e9..8f78ac9e6040 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/trx.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ee/trx.h
@@ -831,6 +831,7 @@ void rtl92ee_rx_check_dma_ok(struct ieee80211_hw *hw, u8 *header_desc,
831 u8 queue_index); 831 u8 queue_index);
832u16 rtl92ee_rx_desc_buff_remained_cnt(struct ieee80211_hw *hw, 832u16 rtl92ee_rx_desc_buff_remained_cnt(struct ieee80211_hw *hw,
833 u8 queue_index); 833 u8 queue_index);
834u16 rtl92ee_get_available_desc(struct ieee80211_hw *hw, u8 queue_index);
834void rtl92ee_pre_fill_tx_bd_desc(struct ieee80211_hw *hw, 835void rtl92ee_pre_fill_tx_bd_desc(struct ieee80211_hw *hw,
835 u8 *tx_bd_desc, u8 *desc, u8 queue_index, 836 u8 *tx_bd_desc, u8 *desc, u8 queue_index,
836 struct sk_buff *skb, dma_addr_t addr); 837 struct sk_buff *skb, dma_addr_t addr);
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index b53d9dd7a595..51572912c53d 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -2182,6 +2182,7 @@ struct rtl_hal_ops {
2182 void (*add_wowlan_pattern)(struct ieee80211_hw *hw, 2182 void (*add_wowlan_pattern)(struct ieee80211_hw *hw,
2183 struct rtl_wow_pattern *rtl_pattern, 2183 struct rtl_wow_pattern *rtl_pattern,
2184 u8 index); 2184 u8 index);
2185 u16 (*get_available_desc)(struct ieee80211_hw *hw, u8 q_idx);
2185}; 2186};
2186 2187
2187struct rtl_intf_ops { 2188struct rtl_intf_ops {