Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -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,
+1 −0
Original line number Diff line number Diff line
@@ -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
+2 −34
Original line number Diff line number Diff line
@@ -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;
+2 −34
Original line number Diff line number Diff line
@@ -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;
+0 −1
Original line number Diff line number Diff line
@@ -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,
Loading