rtlwifi: rtl8188ee: rtl8192com: rtl8192cu: rtl8192ee: rtl8723ae: rtl87323be: rtl8821a...
authorLarry Finger <Larry.Finger@lwfinger.net>
Fri, 26 Sep 2014 21:40:27 +0000 (16:40 -0500)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 30 Sep 2014 17:17:38 +0000 (13:17 -0400)
A locking problem was found in routine _rtl92ee_cmd_send_packet() that led
to system freezes. Upon inspection, several drivers had the same problem;
however, the routines all used the same code. The common code has been
moved into rtlwifi.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/rtlwifi/core.c
drivers/net/wireless/rtlwifi/core.h
drivers/net/wireless/rtlwifi/rtl8188ee/fw.c
drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
drivers/net/wireless/rtlwifi/rtl8192ee/fw.c
drivers/net/wireless/rtlwifi/rtl8723ae/fw.c
drivers/net/wireless/rtlwifi/rtl8723be/fw.c
drivers/net/wireless/rtlwifi/rtl8821ae/fw.c
drivers/net/wireless/rtlwifi/wifi.h

index 10a3bc6dca80c262caebbf4cbe73ccf9389c77d4..f6179bc060869cfdb6dd6d9d9c90d8cc43197904 100644 (file)
@@ -1768,6 +1768,37 @@ bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
        return true;
 }
 EXPORT_SYMBOL(rtl_hal_pwrseqcmdparsing);
+
+bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl8192_tx_ring *ring;
+       struct rtl_tx_desc *pdesc;
+       unsigned long flags;
+       struct sk_buff *pskb = NULL;
+
+       ring = &rtlpci->tx_ring[BEACON_QUEUE];
+
+       spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
+       pskb = __skb_dequeue(&ring->queue);
+       if (pskb)
+               kfree_skb(pskb);
+
+       /*this is wrong, fill_tx_cmddesc needs update*/
+       pdesc = &ring->desc[0];
+
+       rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb);
+
+       __skb_queue_tail(&ring->queue, skb);
+
+       spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+
+       rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
+
+       return true;
+}
+EXPORT_SYMBOL(rtl_cmd_send_packet);
 const struct ieee80211_ops rtl_ops = {
        .start = rtl_op_start,
        .stop = rtl_op_stop,
index cdd47276f69481258537e1c16b84f473caae6977..59cd3b9dca25f895bcd6ee24f43f366867c8e41a 100644 (file)
@@ -41,5 +41,6 @@ void rtl_addr_delay(u32 addr);
 void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr,
                     u32 mask, u32 data);
 void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data);
+bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb);
 
 #endif
index 8d4cf2edeed4815e87de2663d0abdf3eaae1f3df..c8058aa73ecfc1aa8f282cc80aa27b789f657906 100644 (file)
@@ -26,6 +26,7 @@
 #include "../wifi.h"
 #include "../pci.h"
 #include "../base.h"
+#include "../core.h"
 #include "reg.h"
 #include "def.h"
 #include "fw.h"
@@ -512,39 +513,6 @@ void rtl88e_set_fw_ap_off_load_cmd(struct ieee80211_hw *hw,
 
 }
 
-static bool _rtl88e_cmd_send_packet(struct ieee80211_hw *hw,
-                                   struct sk_buff *skb)
-{
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-       struct rtl8192_tx_ring *ring;
-       struct rtl_tx_desc *pdesc;
-       struct sk_buff *pskb = NULL;
-       u8 own;
-       unsigned long flags;
-
-       ring = &rtlpci->tx_ring[BEACON_QUEUE];
-
-       pskb = __skb_dequeue(&ring->queue);
-       if (pskb)
-               kfree_skb(pskb);
-
-       spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
-
-       pdesc = &ring->desc[0];
-       own = (u8)rtlpriv->cfg->ops->get_desc((u8 *)pdesc, true, HW_DESC_OWN);
-
-       rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb);
-
-       __skb_queue_tail(&ring->queue, skb);
-
-       spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
-
-       rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
-
-       return true;
-}
-
 #define BEACON_PG              0 /* ->1 */
 #define PSPOLL_PG              2
 #define NULL_PG                        3
@@ -730,7 +698,7 @@ void rtl88e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
        memcpy(skb_put(skb, totalpacketlen),
               &reserved_page_packet, totalpacketlen);
 
-       rtstatus = _rtl88e_cmd_send_packet(hw, skb);
+       rtstatus = rtl_cmd_send_packet(hw, skb);
 
        if (rtstatus)
                b_dlok = true;
index 6a57e6dafde7fd43ab9ad72cb7e0c9bf8e50a97c..a00861b26ece7ae6b2c6168ca22bdaed42c71033 100644 (file)
@@ -26,6 +26,7 @@
 #include "../wifi.h"
 #include "../pci.h"
 #include "../base.h"
+#include "../core.h"
 #include "../rtl8192ce/reg.h"
 #include "../rtl8192ce/def.h"
 #include "fw_common.h"
@@ -538,39 +539,6 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
 }
 EXPORT_SYMBOL(rtl92c_set_fw_pwrmode_cmd);
 
-static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
-                               struct sk_buff *skb)
-{
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-       struct rtl8192_tx_ring *ring;
-       struct rtl_tx_desc *pdesc;
-       u8 own;
-       unsigned long flags;
-       struct sk_buff *pskb = NULL;
-
-       ring = &rtlpci->tx_ring[BEACON_QUEUE];
-
-       pskb = __skb_dequeue(&ring->queue);
-       if (pskb)
-               kfree_skb(pskb);
-
-       spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
-
-       pdesc = &ring->desc[0];
-       own = (u8)rtlpriv->cfg->ops->get_desc((u8 *)pdesc, true, HW_DESC_OWN);
-
-       rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb);
-
-       __skb_queue_tail(&ring->queue, skb);
-
-       spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
-
-       rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
-
-       return true;
-}
-
 #define BEACON_PG              0 /*->1*/
 #define PSPOLL_PG              2
 #define NULL_PG                        3
@@ -754,7 +722,7 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
        memcpy((u8 *)skb_put(skb, totalpacketlen),
               &reserved_page_packet, totalpacketlen);
 
-       rtstatus = _rtl92c_cmd_send_packet(hw, skb);
+       rtstatus = rtl_cmd_send_packet(hw, skb);
 
        if (rtstatus)
                b_dlok = true;
index f72f0db824443ca01ca2e8239c0382a743238d27..7c5fbaf5fee0d790d1cfbeaa563a1c360a1a976b 100644 (file)
@@ -122,7 +122,6 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = {
        .fill_tx_desc = rtl92cu_tx_fill_desc,
        .fill_fake_txdesc = rtl92cu_fill_fake_txdesc,
        .fill_tx_cmddesc = rtl92cu_tx_fill_cmddesc,
-       .cmd_send_packet = rtl92cu_cmd_send_packet,
        .query_rx_desc = rtl92cu_rx_query_desc,
        .set_channel_access = rtl92cu_update_channel_access_setting,
        .radio_onoff_checking = rtl92cu_gpio_radio_on_off_checking,
index 3c4a9a9abfd3f24345b3bcfaeedabba6581f0746..45c128b91f7fecb0d6ff07bfa7edc72f3a69847e 100644 (file)
@@ -26,6 +26,7 @@
 #include "../wifi.h"
 #include "../pci.h"
 #include "../base.h"
+#include "../core.h"
 #include "reg.h"
 #include "def.h"
 #include "fw.h"
@@ -541,37 +542,6 @@ void rtl92ee_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
        rtl92ee_fill_h2c_cmd(hw, H2C_92E_MSRRPT, 3, parm);
 }
 
-static bool _rtl92ee_cmd_send_packet(struct ieee80211_hw *hw,
-                                    struct sk_buff *skb)
-{
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-       struct rtl8192_tx_ring *ring;
-       struct rtl_tx_desc *pdesc;
-       unsigned long flags;
-       struct sk_buff *pskb = NULL;
-
-       ring = &rtlpci->tx_ring[BEACON_QUEUE];
-
-       pskb = __skb_dequeue(&ring->queue);
-       if (pskb)
-               kfree_skb(pskb);
-
-       spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
-       /*this is wrong, fill_tx_cmddesc needs update*/
-       pdesc = &ring->desc[0];
-
-       rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb);
-
-       __skb_queue_tail(&ring->queue, skb);
-
-       spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
-
-       rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
-
-       return true;
-}
-
 #define BEACON_PG              0 /* ->1 */
 #define PSPOLL_PG              2
 #define NULL_PG                        3
@@ -758,7 +728,7 @@ void rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
        memcpy((u8 *)skb_put(skb, totalpacketlen),
               &reserved_page_packet, totalpacketlen);
 
-       rtstatus = _rtl92ee_cmd_send_packet(hw, skb);
+       rtstatus = rtl_cmd_send_packet(hw, skb);
 
        if (rtstatus)
                b_dlok = true;
index 97d92e2d3cc939786bcdd269075d6857bc05f393..b7c0d38ee5b5850623ce2f49554ed9e82e66c0e0 100644 (file)
@@ -26,6 +26,7 @@
 #include "../wifi.h"
 #include "../pci.h"
 #include "../base.h"
+#include "../core.h"
 #include "reg.h"
 #include "def.h"
 #include "fw.h"
@@ -473,7 +474,7 @@ void rtl8723e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
        memcpy((u8 *)skb_put(skb, totalpacketlen),
               &reserved_page_packet, totalpacketlen);
 
-       rtstatus = rtl8723_cmd_send_packet(hw, skb);
+       rtstatus = rtl_cmd_send_packet(hw, skb);
 
        if (rtstatus)
                b_dlok = true;
index 0c07992985b9d44e0a1cccb4816c6ba9747425b5..69d4f0fc1af1c1ed9ec459cb97e461e0f7adf880 100644 (file)
@@ -26,6 +26,7 @@
 #include "../wifi.h"
 #include "../pci.h"
 #include "../base.h"
+#include "../core.h"
 #include "reg.h"
 #include "def.h"
 #include "fw.h"
@@ -467,7 +468,7 @@ void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
        memcpy((u8 *)skb_put(skb, totalpacketlen),
               &reserved_page_packet, totalpacketlen);
 
-       rtstatus = rtl8723_cmd_send_packet(hw, skb);
+       rtstatus = rtl_cmd_send_packet(hw, skb);
 
        if (rtstatus)
                b_dlok = true;
index 2efdb64d55289dd35f6e2bdcd81ec2167edf399d..95e95626b6325c29c43ceb440b4b3ea0b352874e 100644 (file)
@@ -26,6 +26,7 @@
 #include "../wifi.h"
 #include "../pci.h"
 #include "../base.h"
+#include "../core.h"
 #include "reg.h"
 #include "def.h"
 #include "fw.h"
@@ -742,39 +743,6 @@ void rtl8821ae_set_fw_global_info_cmd(struct ieee80211_hw *hw)
                      remote_wakeup_sec_info, H2C_8821AE_AOAC_GLOBAL_INFO_LEN);
 }
 
-static bool _rtl8821ae_cmd_send_packet(struct ieee80211_hw *hw,
-                               struct sk_buff *skb)
-{
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-       struct rtl8192_tx_ring *ring;
-       struct rtl_tx_desc *pdesc;
-       struct sk_buff *pskb = NULL;
-       u8 own;
-       unsigned long flags;
-
-       ring = &rtlpci->tx_ring[BEACON_QUEUE];
-
-       pskb = __skb_dequeue(&ring->queue);
-       if (pskb)
-               kfree_skb(pskb);
-
-       spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
-
-       pdesc = &ring->desc[0];
-       own = (u8)rtlpriv->cfg->ops->get_desc((u8 *)pdesc, true, HW_DESC_OWN);
-
-       rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb);
-
-       __skb_queue_tail(&ring->queue, skb);
-
-       spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
-
-       rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
-
-       return true;
-}
-
 #define BEACON_PG              0
 #define PSPOLL_PG              1
 #define NULL_PG                        2
@@ -1581,7 +1549,7 @@ out:
        memcpy((u8 *)skb_put(skb, totalpacketlen),
               &reserved_page_packet_8812, totalpacketlen);
 
-       rtstatus = _rtl8821ae_cmd_send_packet(hw, skb);
+       rtstatus = rtl_cmd_send_packet(hw, skb);
 
        if (rtstatus)
                b_dlok = true;
@@ -1706,7 +1674,7 @@ out:
        memcpy((u8 *)skb_put(skb, totalpacketlen),
               &reserved_page_packet_8821, totalpacketlen);
 
-       rtstatus = _rtl8821ae_cmd_send_packet(hw, skb);
+       rtstatus = rtl_cmd_send_packet(hw, skb);
 
        if (rtstatus)
                b_dlok = true;
index 92874b1a8aa69705a1d5c90d0842be34ee8d2a41..976667ae85498feeb7abb06b505a254706dcefee 100644 (file)
@@ -2101,7 +2101,6 @@ struct rtl_hal_ops {
        void (*fill_tx_cmddesc) (struct ieee80211_hw *hw, u8 *pdesc,
                                 bool firstseg, bool lastseg,
                                 struct sk_buff *skb);
-       bool (*cmd_send_packet)(struct ieee80211_hw *hw, struct sk_buff *skb);
        bool (*query_rx_desc) (struct ieee80211_hw *hw,
                               struct rtl_stats *stats,
                               struct ieee80211_rx_status *rx_status,