mirror of
https://github.com/torvalds/linux.git
synced 2024-12-29 14:21:47 +00:00
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>
This commit is contained in:
parent
9f087a9244
commit
557f933113
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user