Commit 557f9331 authored by Larry Finger's avatar Larry Finger Committed by John W. Linville

rtlwifi: rtl8188ee: rtl8192com: rtl8192cu: rtl8192ee: rtl8723ae: rtl87323be:...

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: default avatarLarry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 9f087a92
...@@ -1768,6 +1768,37 @@ bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, ...@@ -1768,6 +1768,37 @@ bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
return true; return true;
} }
EXPORT_SYMBOL(rtl_hal_pwrseqcmdparsing); 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 = { const struct ieee80211_ops rtl_ops = {
.start = rtl_op_start, .start = rtl_op_start,
.stop = rtl_op_stop, .stop = rtl_op_stop,
......
...@@ -41,5 +41,6 @@ void rtl_addr_delay(u32 addr); ...@@ -41,5 +41,6 @@ void rtl_addr_delay(u32 addr);
void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr, void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr,
u32 mask, u32 data); u32 mask, u32 data);
void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, 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 #endif
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "../wifi.h" #include "../wifi.h"
#include "../pci.h" #include "../pci.h"
#include "../base.h" #include "../base.h"
#include "../core.h"
#include "reg.h" #include "reg.h"
#include "def.h" #include "def.h"
#include "fw.h" #include "fw.h"
...@@ -512,39 +513,6 @@ void rtl88e_set_fw_ap_off_load_cmd(struct ieee80211_hw *hw, ...@@ -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 BEACON_PG 0 /* ->1 */
#define PSPOLL_PG 2 #define PSPOLL_PG 2
#define NULL_PG 3 #define NULL_PG 3
...@@ -730,7 +698,7 @@ void rtl88e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) ...@@ -730,7 +698,7 @@ void rtl88e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
memcpy(skb_put(skb, totalpacketlen), memcpy(skb_put(skb, totalpacketlen),
&reserved_page_packet, totalpacketlen); &reserved_page_packet, totalpacketlen);
rtstatus = _rtl88e_cmd_send_packet(hw, skb); rtstatus = rtl_cmd_send_packet(hw, skb);
if (rtstatus) if (rtstatus)
b_dlok = true; b_dlok = true;
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "../wifi.h" #include "../wifi.h"
#include "../pci.h" #include "../pci.h"
#include "../base.h" #include "../base.h"
#include "../core.h"
#include "../rtl8192ce/reg.h" #include "../rtl8192ce/reg.h"
#include "../rtl8192ce/def.h" #include "../rtl8192ce/def.h"
#include "fw_common.h" #include "fw_common.h"
...@@ -538,39 +539,6 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) ...@@ -538,39 +539,6 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
} }
EXPORT_SYMBOL(rtl92c_set_fw_pwrmode_cmd); 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 BEACON_PG 0 /*->1*/
#define PSPOLL_PG 2 #define PSPOLL_PG 2
#define NULL_PG 3 #define NULL_PG 3
...@@ -754,7 +722,7 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) ...@@ -754,7 +722,7 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
memcpy((u8 *)skb_put(skb, totalpacketlen), memcpy((u8 *)skb_put(skb, totalpacketlen),
&reserved_page_packet, totalpacketlen); &reserved_page_packet, totalpacketlen);
rtstatus = _rtl92c_cmd_send_packet(hw, skb); rtstatus = rtl_cmd_send_packet(hw, skb);
if (rtstatus) if (rtstatus)
b_dlok = true; b_dlok = true;
......
...@@ -122,7 +122,6 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = { ...@@ -122,7 +122,6 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = {
.fill_tx_desc = rtl92cu_tx_fill_desc, .fill_tx_desc = rtl92cu_tx_fill_desc,
.fill_fake_txdesc = rtl92cu_fill_fake_txdesc, .fill_fake_txdesc = rtl92cu_fill_fake_txdesc,
.fill_tx_cmddesc = rtl92cu_tx_fill_cmddesc, .fill_tx_cmddesc = rtl92cu_tx_fill_cmddesc,
.cmd_send_packet = rtl92cu_cmd_send_packet,
.query_rx_desc = rtl92cu_rx_query_desc, .query_rx_desc = rtl92cu_rx_query_desc,
.set_channel_access = rtl92cu_update_channel_access_setting, .set_channel_access = rtl92cu_update_channel_access_setting,
.radio_onoff_checking = rtl92cu_gpio_radio_on_off_checking, .radio_onoff_checking = rtl92cu_gpio_radio_on_off_checking,
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "../wifi.h" #include "../wifi.h"
#include "../pci.h" #include "../pci.h"
#include "../base.h" #include "../base.h"
#include "../core.h"
#include "reg.h" #include "reg.h"
#include "def.h" #include "def.h"
#include "fw.h" #include "fw.h"
...@@ -541,37 +542,6 @@ void rtl92ee_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus) ...@@ -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); 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 BEACON_PG 0 /* ->1 */
#define PSPOLL_PG 2 #define PSPOLL_PG 2
#define NULL_PG 3 #define NULL_PG 3
...@@ -758,7 +728,7 @@ void rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) ...@@ -758,7 +728,7 @@ void rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
memcpy((u8 *)skb_put(skb, totalpacketlen), memcpy((u8 *)skb_put(skb, totalpacketlen),
&reserved_page_packet, totalpacketlen); &reserved_page_packet, totalpacketlen);
rtstatus = _rtl92ee_cmd_send_packet(hw, skb); rtstatus = rtl_cmd_send_packet(hw, skb);
if (rtstatus) if (rtstatus)
b_dlok = true; b_dlok = true;
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "../wifi.h" #include "../wifi.h"
#include "../pci.h" #include "../pci.h"
#include "../base.h" #include "../base.h"
#include "../core.h"
#include "reg.h" #include "reg.h"
#include "def.h" #include "def.h"
#include "fw.h" #include "fw.h"
...@@ -473,7 +474,7 @@ void rtl8723e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) ...@@ -473,7 +474,7 @@ void rtl8723e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
memcpy((u8 *)skb_put(skb, totalpacketlen), memcpy((u8 *)skb_put(skb, totalpacketlen),
&reserved_page_packet, totalpacketlen); &reserved_page_packet, totalpacketlen);
rtstatus = rtl8723_cmd_send_packet(hw, skb); rtstatus = rtl_cmd_send_packet(hw, skb);
if (rtstatus) if (rtstatus)
b_dlok = true; b_dlok = true;
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "../wifi.h" #include "../wifi.h"
#include "../pci.h" #include "../pci.h"
#include "../base.h" #include "../base.h"
#include "../core.h"
#include "reg.h" #include "reg.h"
#include "def.h" #include "def.h"
#include "fw.h" #include "fw.h"
...@@ -467,7 +468,7 @@ void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, ...@@ -467,7 +468,7 @@ void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
memcpy((u8 *)skb_put(skb, totalpacketlen), memcpy((u8 *)skb_put(skb, totalpacketlen),
&reserved_page_packet, totalpacketlen); &reserved_page_packet, totalpacketlen);
rtstatus = rtl8723_cmd_send_packet(hw, skb); rtstatus = rtl_cmd_send_packet(hw, skb);
if (rtstatus) if (rtstatus)
b_dlok = true; b_dlok = true;
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "../wifi.h" #include "../wifi.h"
#include "../pci.h" #include "../pci.h"
#include "../base.h" #include "../base.h"
#include "../core.h"
#include "reg.h" #include "reg.h"
#include "def.h" #include "def.h"
#include "fw.h" #include "fw.h"
...@@ -742,39 +743,6 @@ void rtl8821ae_set_fw_global_info_cmd(struct ieee80211_hw *hw) ...@@ -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); 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 BEACON_PG 0
#define PSPOLL_PG 1 #define PSPOLL_PG 1
#define NULL_PG 2 #define NULL_PG 2
...@@ -1581,7 +1549,7 @@ void rtl8812ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, ...@@ -1581,7 +1549,7 @@ void rtl8812ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
memcpy((u8 *)skb_put(skb, totalpacketlen), memcpy((u8 *)skb_put(skb, totalpacketlen),
&reserved_page_packet_8812, totalpacketlen); &reserved_page_packet_8812, totalpacketlen);
rtstatus = _rtl8821ae_cmd_send_packet(hw, skb); rtstatus = rtl_cmd_send_packet(hw, skb);
if (rtstatus) if (rtstatus)
b_dlok = true; b_dlok = true;
...@@ -1706,7 +1674,7 @@ void rtl8821ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, ...@@ -1706,7 +1674,7 @@ void rtl8821ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
memcpy((u8 *)skb_put(skb, totalpacketlen), memcpy((u8 *)skb_put(skb, totalpacketlen),
&reserved_page_packet_8821, totalpacketlen); &reserved_page_packet_8821, totalpacketlen);
rtstatus = _rtl8821ae_cmd_send_packet(hw, skb); rtstatus = rtl_cmd_send_packet(hw, skb);
if (rtstatus) if (rtstatus)
b_dlok = true; b_dlok = true;
......
...@@ -2101,7 +2101,6 @@ struct rtl_hal_ops { ...@@ -2101,7 +2101,6 @@ struct rtl_hal_ops {
void (*fill_tx_cmddesc) (struct ieee80211_hw *hw, u8 *pdesc, void (*fill_tx_cmddesc) (struct ieee80211_hw *hw, u8 *pdesc,
bool firstseg, bool lastseg, bool firstseg, bool lastseg,
struct sk_buff *skb); struct sk_buff *skb);
bool (*cmd_send_packet)(struct ieee80211_hw *hw, struct sk_buff *skb);
bool (*query_rx_desc) (struct ieee80211_hw *hw, bool (*query_rx_desc) (struct ieee80211_hw *hw,
struct rtl_stats *stats, struct rtl_stats *stats,
struct ieee80211_rx_status *rx_status, struct ieee80211_rx_status *rx_status,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment