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