From: Greg Kroah-Hartman Date: Sun, 26 Apr 2015 10:05:56 +0000 (+0200) Subject: 3.19-stable patches X-Git-Tag: v4.0.1~15 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1eea65f9b61f3fa790113e46be21566893a529c7;p=thirdparty%2Fkernel%2Fstable-queue.git 3.19-stable patches added patches: rtlwifi-rtl8192ee-fix-handling-of-new-style-descriptors.patch --- diff --git a/queue-3.19/rtlwifi-rtl8192ee-fix-handling-of-new-style-descriptors.patch b/queue-3.19/rtlwifi-rtl8192ee-fix-handling-of-new-style-descriptors.patch new file mode 100644 index 00000000000..ebbd14c3d05 --- /dev/null +++ b/queue-3.19/rtlwifi-rtl8192ee-fix-handling-of-new-style-descriptors.patch @@ -0,0 +1,190 @@ +From d0311314d00298f83aa5450a1d4a92889e7cc2ea Mon Sep 17 00:00:00 2001 +From: Troy Tan +Date: Tue, 3 Feb 2015 11:15:17 -0600 +Subject: rtlwifi: rtl8192ee: Fix handling of new style descriptors + +From: Troy Tan + +commit d0311314d00298f83aa5450a1d4a92889e7cc2ea upstream. + +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 +Signed-off-by: Larry Finger +Cc: Stable [V3.18] +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/rtlwifi/pci.c | 31 ++++++++++++++++++++------- + drivers/net/wireless/rtlwifi/rtl8192ee/sw.c | 3 -- + drivers/net/wireless/rtlwifi/rtl8192ee/trx.c | 7 +++--- + drivers/net/wireless/rtlwifi/rtl8192ee/trx.h | 2 - + drivers/net/wireless/rtlwifi/wifi.h | 1 + 5 files changed, 30 insertions(+), 14 deletions(-) + +--- 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 ieee8 + else + entry = (u8 *)(&ring->desc[ring->idx]); + ++ if (rtlpriv->cfg->ops->get_available_desc && ++ rtlpriv->cfg->ops->get_available_desc(hw, prio) <= 1) { ++ RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_DMESG, ++ "no available desc!\n"); ++ return; ++ } ++ + if (!rtlpriv->cfg->ops->is_tx_desc_closed(hw, prio, ring->idx)) + return; + ring->idx = (ring->idx + 1) % ring->entries; +@@ -641,10 +648,9 @@ static void _rtl_pci_tx_isr(struct ieee8 + + ieee80211_tx_status_irqsafe(hw, skb); + +- if ((ring->entries - skb_queue_len(&ring->queue)) +- == 2) { ++ if ((ring->entries - skb_queue_len(&ring->queue)) <= 4) { + +- RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, ++ RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, + "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%x\n", + prio, ring->idx, + skb_queue_len(&ring->queue)); +@@ -793,7 +799,7 @@ static void _rtl_pci_rx_interrupt(struct + rx_remained_cnt = + rtlpriv->cfg->ops->rx_desc_buff_remained_cnt(hw, + hw_queue); +- if (rx_remained_cnt < 1) ++ if (rx_remained_cnt == 0) + return; + + } else { /* rx descriptor */ +@@ -845,18 +851,18 @@ static void _rtl_pci_rx_interrupt(struct + else + skb_reserve(skb, stats.rx_drvinfo_size + + stats.rx_bufshift); +- + } else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "skb->end - skb->tail = %d, len is %d\n", + skb->end - skb->tail, len); +- break; ++ dev_kfree_skb_any(skb); ++ goto new_trx_end; + } + /* handle command packet here */ + if (rtlpriv->cfg->ops->rx_command_packet && + rtlpriv->cfg->ops->rx_command_packet(hw, stats, skb)) { + dev_kfree_skb_any(skb); +- goto end; ++ goto new_trx_end; + } + + /* +@@ -906,6 +912,7 @@ static void _rtl_pci_rx_interrupt(struct + } else { + dev_kfree_skb_any(skb); + } ++new_trx_end: + if (rtlpriv->use_new_trx_flow) { + rtlpci->rx_ring[hw_queue].next_rx_rp += 1; + rtlpci->rx_ring[hw_queue].next_rx_rp %= +@@ -921,7 +928,6 @@ static void _rtl_pci_rx_interrupt(struct + rtlpriv->enter_ps = false; + schedule_work(&rtlpriv->works.lps_change_work); + } +-end: + skb = new_skb; + no_new: + if (rtlpriv->use_new_trx_flow) { +@@ -1695,6 +1701,15 @@ static int rtl_pci_tx(struct ieee80211_h + } + } + ++ if (rtlpriv->cfg->ops->get_available_desc && ++ rtlpriv->cfg->ops->get_available_desc(hw, hw_queue) == 0) { ++ RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ++ "get_available_desc fail\n"); ++ spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, ++ flags); ++ return skb->len; ++ } ++ + if (ieee80211_is_data_qos(fc)) { + tid = rtl_get_tid(skb); + if (sta) { +--- 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 ieee8021 + RCR_HTC_LOC_CTRL | + RCR_AMF | + RCR_ACF | +- RCR_ADF | +- RCR_AICV | + RCR_ACRC32 | + RCR_AB | + RCR_AM | +@@ -241,6 +239,7 @@ static struct rtl_hal_ops rtl8192ee_hal_ + .set_desc = rtl92ee_set_desc, + .get_desc = rtl92ee_get_desc, + .is_tx_desc_closed = rtl92ee_is_tx_desc_closed, ++ .get_available_desc = rtl92ee_get_available_desc, + .tx_polling = rtl92ee_tx_polling, + .enable_hw_sec = rtl92ee_enable_hw_security_config, + .set_key = rtl92ee_set_key, +--- a/drivers/net/wireless/rtlwifi/rtl8192ee/trx.c ++++ b/drivers/net/wireless/rtlwifi/rtl8192ee/trx.c +@@ -707,7 +707,7 @@ static u16 get_desc_addr_fr_q_idx(u16 qu + return desc_address; + } + +-void rtl92ee_get_available_desc(struct ieee80211_hw *hw, u8 q_idx) ++u16 rtl92ee_get_available_desc(struct ieee80211_hw *hw, u8 q_idx) + { + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); +@@ -721,11 +721,12 @@ void rtl92ee_get_available_desc(struct i + current_tx_write_point = (u16)((tmp_4byte) & 0x0fff); + + point_diff = ((current_tx_read_point > current_tx_write_point) ? +- (current_tx_read_point - current_tx_write_point) : +- (TX_DESC_NUM_92E - current_tx_write_point + ++ (current_tx_read_point - current_tx_write_point - 1) : ++ (TX_DESC_NUM_92E - 1 - current_tx_write_point + + current_tx_read_point)); + + rtlpci->tx_ring[q_idx].avl_desc = point_diff; ++ return point_diff; + } + + void rtl92ee_pre_fill_tx_bd_desc(struct ieee80211_hw *hw, +--- a/drivers/net/wireless/rtlwifi/rtl8192ee/trx.h ++++ b/drivers/net/wireless/rtlwifi/rtl8192ee/trx.h +@@ -831,7 +831,7 @@ void rtl92ee_rx_check_dma_ok(struct ieee + u8 queue_index); + u16 rtl92ee_rx_desc_buff_remained_cnt(struct ieee80211_hw *hw, + u8 queue_index); +-void rtl92ee_get_available_desc(struct ieee80211_hw *hw, u8 queue_index); ++u16 rtl92ee_get_available_desc(struct ieee80211_hw *hw, u8 queue_index); + void rtl92ee_pre_fill_tx_bd_desc(struct ieee80211_hw *hw, + u8 *tx_bd_desc, u8 *desc, u8 queue_index, + struct sk_buff *skb, dma_addr_t addr); +--- a/drivers/net/wireless/rtlwifi/wifi.h ++++ b/drivers/net/wireless/rtlwifi/wifi.h +@@ -2161,6 +2161,7 @@ struct rtl_hal_ops { + void (*add_wowlan_pattern)(struct ieee80211_hw *hw, + struct rtl_wow_pattern *rtl_pattern, + u8 index); ++ u16 (*get_available_desc)(struct ieee80211_hw *hw, u8 q_idx); + }; + + struct rtl_intf_ops { diff --git a/queue-3.19/series b/queue-3.19/series index 8204dc048ee..93c3de1cdc8 100644 --- a/queue-3.19/series +++ b/queue-3.19/series @@ -23,3 +23,4 @@ kvm-nvmx-mask-unrestricted_guest-if-disabled-on-l0.patch staging-comedi-adv_pci1710-fix-ai-insn_read-for-non-zero-channel.patch mm-hugetlb-reduce-arch-dependent-code-around-follow_huge_.patch mm-hugetlb-take-page-table-lock-in-follow_huge_pmd.patch +rtlwifi-rtl8192ee-fix-handling-of-new-style-descriptors.patch