aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2014-09-26 17:40:27 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-09-30 13:17:38 -0400
commit557f933113a42a48ec617b81b5ea53fd7202b1ed (patch)
treefb234552f04d6070e74644a0f8078432c3fd9ba2 /drivers/net/wireless
parent9f087a924427c01190b205f0051be00808c99828 (diff)
rtlwifi: rtl8188ee: rtl8192com: rtl8192cu: rtl8192ee: rtl8723ae: rtl87323be: rtl8821ae: Use common cmd_send_packet
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>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/rtlwifi/core.c31
-rw-r--r--drivers/net/wireless/rtlwifi/core.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/fw.c36
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c36
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.c1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ee/fw.c34
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/fw.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/fw.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8821ae/fw.c38
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h1
10 files changed, 45 insertions, 139 deletions
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
index 10a3bc6dca80..f6179bc06086 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -1768,6 +1768,37 @@ bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
1768 return true; 1768 return true;
1769} 1769}
1770EXPORT_SYMBOL(rtl_hal_pwrseqcmdparsing); 1770EXPORT_SYMBOL(rtl_hal_pwrseqcmdparsing);
1771
1772bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb)
1773{
1774 struct rtl_priv *rtlpriv = rtl_priv(hw);
1775 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1776 struct rtl8192_tx_ring *ring;
1777 struct rtl_tx_desc *pdesc;
1778 unsigned long flags;
1779 struct sk_buff *pskb = NULL;
1780
1781 ring = &rtlpci->tx_ring[BEACON_QUEUE];
1782
1783 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
1784 pskb = __skb_dequeue(&ring->queue);
1785 if (pskb)
1786 kfree_skb(pskb);
1787
1788 /*this is wrong, fill_tx_cmddesc needs update*/
1789 pdesc = &ring->desc[0];
1790
1791 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb);
1792
1793 __skb_queue_tail(&ring->queue, skb);
1794
1795 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
1796
1797 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
1798
1799 return true;
1800}
1801EXPORT_SYMBOL(rtl_cmd_send_packet);
1771const struct ieee80211_ops rtl_ops = { 1802const struct ieee80211_ops rtl_ops = {
1772 .start = rtl_op_start, 1803 .start = rtl_op_start,
1773 .stop = rtl_op_stop, 1804 .stop = rtl_op_stop,
diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h
index cdd47276f694..59cd3b9dca25 100644
--- a/drivers/net/wireless/rtlwifi/core.h
+++ b/drivers/net/wireless/rtlwifi/core.h
@@ -41,5 +41,6 @@ void rtl_addr_delay(u32 addr);
41void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr, 41void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr,
42 u32 mask, u32 data); 42 u32 mask, u32 data);
43void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data); 43void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data);
44bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb);
44 45
45#endif 46#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/fw.c b/drivers/net/wireless/rtlwifi/rtl8188ee/fw.c
index 8d4cf2edeed4..c8058aa73ecf 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/fw.c
@@ -26,6 +26,7 @@
26#include "../wifi.h" 26#include "../wifi.h"
27#include "../pci.h" 27#include "../pci.h"
28#include "../base.h" 28#include "../base.h"
29#include "../core.h"
29#include "reg.h" 30#include "reg.h"
30#include "def.h" 31#include "def.h"
31#include "fw.h" 32#include "fw.h"
@@ -512,39 +513,6 @@ void rtl88e_set_fw_ap_off_load_cmd(struct ieee80211_hw *hw,
512 513
513} 514}
514 515
515static bool _rtl88e_cmd_send_packet(struct ieee80211_hw *hw,
516 struct sk_buff *skb)
517{
518 struct rtl_priv *rtlpriv = rtl_priv(hw);
519 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
520 struct rtl8192_tx_ring *ring;
521 struct rtl_tx_desc *pdesc;
522 struct sk_buff *pskb = NULL;
523 u8 own;
524 unsigned long flags;
525
526 ring = &rtlpci->tx_ring[BEACON_QUEUE];
527
528 pskb = __skb_dequeue(&ring->queue);
529 if (pskb)
530 kfree_skb(pskb);
531
532 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
533
534 pdesc = &ring->desc[0];
535 own = (u8)rtlpriv->cfg->ops->get_desc((u8 *)pdesc, true, HW_DESC_OWN);
536
537 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb);
538
539 __skb_queue_tail(&ring->queue, skb);
540
541 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
542
543 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
544
545 return true;
546}
547
548#define BEACON_PG 0 /* ->1 */ 516#define BEACON_PG 0 /* ->1 */
549#define PSPOLL_PG 2 517#define PSPOLL_PG 2
550#define NULL_PG 3 518#define NULL_PG 3
@@ -730,7 +698,7 @@ void rtl88e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
730 memcpy(skb_put(skb, totalpacketlen), 698 memcpy(skb_put(skb, totalpacketlen),
731 &reserved_page_packet, totalpacketlen); 699 &reserved_page_packet, totalpacketlen);
732 700
733 rtstatus = _rtl88e_cmd_send_packet(hw, skb); 701 rtstatus = rtl_cmd_send_packet(hw, skb);
734 702
735 if (rtstatus) 703 if (rtstatus)
736 b_dlok = true; 704 b_dlok = true;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
index 6a57e6dafde7..a00861b26ece 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
@@ -26,6 +26,7 @@
26#include "../wifi.h" 26#include "../wifi.h"
27#include "../pci.h" 27#include "../pci.h"
28#include "../base.h" 28#include "../base.h"
29#include "../core.h"
29#include "../rtl8192ce/reg.h" 30#include "../rtl8192ce/reg.h"
30#include "../rtl8192ce/def.h" 31#include "../rtl8192ce/def.h"
31#include "fw_common.h" 32#include "fw_common.h"
@@ -538,39 +539,6 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
538} 539}
539EXPORT_SYMBOL(rtl92c_set_fw_pwrmode_cmd); 540EXPORT_SYMBOL(rtl92c_set_fw_pwrmode_cmd);
540 541
541static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
542 struct sk_buff *skb)
543{
544 struct rtl_priv *rtlpriv = rtl_priv(hw);
545 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
546 struct rtl8192_tx_ring *ring;
547 struct rtl_tx_desc *pdesc;
548 u8 own;
549 unsigned long flags;
550 struct sk_buff *pskb = NULL;
551
552 ring = &rtlpci->tx_ring[BEACON_QUEUE];
553
554 pskb = __skb_dequeue(&ring->queue);
555 if (pskb)
556 kfree_skb(pskb);
557
558 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
559
560 pdesc = &ring->desc[0];
561 own = (u8)rtlpriv->cfg->ops->get_desc((u8 *)pdesc, true, HW_DESC_OWN);
562
563 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb);
564
565 __skb_queue_tail(&ring->queue, skb);
566
567 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
568
569 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
570
571 return true;
572}
573
574#define BEACON_PG 0 /*->1*/ 542#define BEACON_PG 0 /*->1*/
575#define PSPOLL_PG 2 543#define PSPOLL_PG 2
576#define NULL_PG 3 544#define NULL_PG 3
@@ -754,7 +722,7 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
754 memcpy((u8 *)skb_put(skb, totalpacketlen), 722 memcpy((u8 *)skb_put(skb, totalpacketlen),
755 &reserved_page_packet, totalpacketlen); 723 &reserved_page_packet, totalpacketlen);
756 724
757 rtstatus = _rtl92c_cmd_send_packet(hw, skb); 725 rtstatus = rtl_cmd_send_packet(hw, skb);
758 726
759 if (rtstatus) 727 if (rtstatus)
760 b_dlok = true; 728 b_dlok = true;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index f72f0db82444..7c5fbaf5fee0 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -122,7 +122,6 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = {
122 .fill_tx_desc = rtl92cu_tx_fill_desc, 122 .fill_tx_desc = rtl92cu_tx_fill_desc,
123 .fill_fake_txdesc = rtl92cu_fill_fake_txdesc, 123 .fill_fake_txdesc = rtl92cu_fill_fake_txdesc,
124 .fill_tx_cmddesc = rtl92cu_tx_fill_cmddesc, 124 .fill_tx_cmddesc = rtl92cu_tx_fill_cmddesc,
125 .cmd_send_packet = rtl92cu_cmd_send_packet,
126 .query_rx_desc = rtl92cu_rx_query_desc, 125 .query_rx_desc = rtl92cu_rx_query_desc,
127 .set_channel_access = rtl92cu_update_channel_access_setting, 126 .set_channel_access = rtl92cu_update_channel_access_setting,
128 .radio_onoff_checking = rtl92cu_gpio_radio_on_off_checking, 127 .radio_onoff_checking = rtl92cu_gpio_radio_on_off_checking,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/fw.c b/drivers/net/wireless/rtlwifi/rtl8192ee/fw.c
index 3c4a9a9abfd3..45c128b91f7f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ee/fw.c
@@ -26,6 +26,7 @@
26#include "../wifi.h" 26#include "../wifi.h"
27#include "../pci.h" 27#include "../pci.h"
28#include "../base.h" 28#include "../base.h"
29#include "../core.h"
29#include "reg.h" 30#include "reg.h"
30#include "def.h" 31#include "def.h"
31#include "fw.h" 32#include "fw.h"
@@ -541,37 +542,6 @@ void rtl92ee_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
541 rtl92ee_fill_h2c_cmd(hw, H2C_92E_MSRRPT, 3, parm); 542 rtl92ee_fill_h2c_cmd(hw, H2C_92E_MSRRPT, 3, parm);
542} 543}
543 544
544static bool _rtl92ee_cmd_send_packet(struct ieee80211_hw *hw,
545 struct sk_buff *skb)
546{
547 struct rtl_priv *rtlpriv = rtl_priv(hw);
548 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
549 struct rtl8192_tx_ring *ring;
550 struct rtl_tx_desc *pdesc;
551 unsigned long flags;
552 struct sk_buff *pskb = NULL;
553
554 ring = &rtlpci->tx_ring[BEACON_QUEUE];
555
556 pskb = __skb_dequeue(&ring->queue);
557 if (pskb)
558 kfree_skb(pskb);
559
560 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
561 /*this is wrong, fill_tx_cmddesc needs update*/
562 pdesc = &ring->desc[0];
563
564 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb);
565
566 __skb_queue_tail(&ring->queue, skb);
567
568 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
569
570 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
571
572 return true;
573}
574
575#define BEACON_PG 0 /* ->1 */ 545#define BEACON_PG 0 /* ->1 */
576#define PSPOLL_PG 2 546#define PSPOLL_PG 2
577#define NULL_PG 3 547#define NULL_PG 3
@@ -758,7 +728,7 @@ void rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
758 memcpy((u8 *)skb_put(skb, totalpacketlen), 728 memcpy((u8 *)skb_put(skb, totalpacketlen),
759 &reserved_page_packet, totalpacketlen); 729 &reserved_page_packet, totalpacketlen);
760 730
761 rtstatus = _rtl92ee_cmd_send_packet(hw, skb); 731 rtstatus = rtl_cmd_send_packet(hw, skb);
762 732
763 if (rtstatus) 733 if (rtstatus)
764 b_dlok = true; 734 b_dlok = true;
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c
index 97d92e2d3cc9..b7c0d38ee5b5 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c
@@ -26,6 +26,7 @@
26#include "../wifi.h" 26#include "../wifi.h"
27#include "../pci.h" 27#include "../pci.h"
28#include "../base.h" 28#include "../base.h"
29#include "../core.h"
29#include "reg.h" 30#include "reg.h"
30#include "def.h" 31#include "def.h"
31#include "fw.h" 32#include "fw.h"
@@ -473,7 +474,7 @@ void rtl8723e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
473 memcpy((u8 *)skb_put(skb, totalpacketlen), 474 memcpy((u8 *)skb_put(skb, totalpacketlen),
474 &reserved_page_packet, totalpacketlen); 475 &reserved_page_packet, totalpacketlen);
475 476
476 rtstatus = rtl8723_cmd_send_packet(hw, skb); 477 rtstatus = rtl_cmd_send_packet(hw, skb);
477 478
478 if (rtstatus) 479 if (rtstatus)
479 b_dlok = true; 480 b_dlok = true;
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/fw.c b/drivers/net/wireless/rtlwifi/rtl8723be/fw.c
index 0c07992985b9..69d4f0fc1af1 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/fw.c
@@ -26,6 +26,7 @@
26#include "../wifi.h" 26#include "../wifi.h"
27#include "../pci.h" 27#include "../pci.h"
28#include "../base.h" 28#include "../base.h"
29#include "../core.h"
29#include "reg.h" 30#include "reg.h"
30#include "def.h" 31#include "def.h"
31#include "fw.h" 32#include "fw.h"
@@ -467,7 +468,7 @@ void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
467 memcpy((u8 *)skb_put(skb, totalpacketlen), 468 memcpy((u8 *)skb_put(skb, totalpacketlen),
468 &reserved_page_packet, totalpacketlen); 469 &reserved_page_packet, totalpacketlen);
469 470
470 rtstatus = rtl8723_cmd_send_packet(hw, skb); 471 rtstatus = rtl_cmd_send_packet(hw, skb);
471 472
472 if (rtstatus) 473 if (rtstatus)
473 b_dlok = true; 474 b_dlok = true;
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/fw.c b/drivers/net/wireless/rtlwifi/rtl8821ae/fw.c
index 2efdb64d5528..95e95626b632 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/fw.c
@@ -26,6 +26,7 @@
26#include "../wifi.h" 26#include "../wifi.h"
27#include "../pci.h" 27#include "../pci.h"
28#include "../base.h" 28#include "../base.h"
29#include "../core.h"
29#include "reg.h" 30#include "reg.h"
30#include "def.h" 31#include "def.h"
31#include "fw.h" 32#include "fw.h"
@@ -742,39 +743,6 @@ void rtl8821ae_set_fw_global_info_cmd(struct ieee80211_hw *hw)
742 remote_wakeup_sec_info, H2C_8821AE_AOAC_GLOBAL_INFO_LEN); 743 remote_wakeup_sec_info, H2C_8821AE_AOAC_GLOBAL_INFO_LEN);
743} 744}
744 745
745static bool _rtl8821ae_cmd_send_packet(struct ieee80211_hw *hw,
746 struct sk_buff *skb)
747{
748 struct rtl_priv *rtlpriv = rtl_priv(hw);
749 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
750 struct rtl8192_tx_ring *ring;
751 struct rtl_tx_desc *pdesc;
752 struct sk_buff *pskb = NULL;
753 u8 own;
754 unsigned long flags;
755
756 ring = &rtlpci->tx_ring[BEACON_QUEUE];
757
758 pskb = __skb_dequeue(&ring->queue);
759 if (pskb)
760 kfree_skb(pskb);
761
762 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
763
764 pdesc = &ring->desc[0];
765 own = (u8)rtlpriv->cfg->ops->get_desc((u8 *)pdesc, true, HW_DESC_OWN);
766
767 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb);
768
769 __skb_queue_tail(&ring->queue, skb);
770
771 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
772
773 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
774
775 return true;
776}
777
778#define BEACON_PG 0 746#define BEACON_PG 0
779#define PSPOLL_PG 1 747#define PSPOLL_PG 1
780#define NULL_PG 2 748#define NULL_PG 2
@@ -1581,7 +1549,7 @@ out:
1581 memcpy((u8 *)skb_put(skb, totalpacketlen), 1549 memcpy((u8 *)skb_put(skb, totalpacketlen),
1582 &reserved_page_packet_8812, totalpacketlen); 1550 &reserved_page_packet_8812, totalpacketlen);
1583 1551
1584 rtstatus = _rtl8821ae_cmd_send_packet(hw, skb); 1552 rtstatus = rtl_cmd_send_packet(hw, skb);
1585 1553
1586 if (rtstatus) 1554 if (rtstatus)
1587 b_dlok = true; 1555 b_dlok = true;
@@ -1706,7 +1674,7 @@ out:
1706 memcpy((u8 *)skb_put(skb, totalpacketlen), 1674 memcpy((u8 *)skb_put(skb, totalpacketlen),
1707 &reserved_page_packet_8821, totalpacketlen); 1675 &reserved_page_packet_8821, totalpacketlen);
1708 1676
1709 rtstatus = _rtl8821ae_cmd_send_packet(hw, skb); 1677 rtstatus = rtl_cmd_send_packet(hw, skb);
1710 1678
1711 if (rtstatus) 1679 if (rtstatus)
1712 b_dlok = true; 1680 b_dlok = true;
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index 92874b1a8aa6..976667ae8549 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -2101,7 +2101,6 @@ struct rtl_hal_ops {
2101 void (*fill_tx_cmddesc) (struct ieee80211_hw *hw, u8 *pdesc, 2101 void (*fill_tx_cmddesc) (struct ieee80211_hw *hw, u8 *pdesc,
2102 bool firstseg, bool lastseg, 2102 bool firstseg, bool lastseg,
2103 struct sk_buff *skb); 2103 struct sk_buff *skb);
2104 bool (*cmd_send_packet)(struct ieee80211_hw *hw, struct sk_buff *skb);
2105 bool (*query_rx_desc) (struct ieee80211_hw *hw, 2104 bool (*query_rx_desc) (struct ieee80211_hw *hw,
2106 struct rtl_stats *stats, 2105 struct rtl_stats *stats,
2107 struct ieee80211_rx_status *rx_status, 2106 struct ieee80211_rx_status *rx_status,