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

Commit cceb0a59 authored by Ping-Ke Shih's avatar Ping-Ke Shih Committed by Kalle Valo
Browse files

rtlwifi: Add work queue for c2h cmd.



btcoex needs to sleep, thus it must run in thread context.

Signed-off-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: default avatarLarry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 0ff78ade
Loading
Loading
Loading
Loading
+93 −0
Original line number Diff line number Diff line
@@ -475,6 +475,8 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw)
			  (void *)rtl_swlps_rfon_wq_callback);
	INIT_DELAYED_WORK(&rtlpriv->works.fwevt_wq,
			  (void *)rtl_fwevt_wq_callback);
	INIT_DELAYED_WORK(&rtlpriv->works.c2hcmd_wq,
			  (void *)rtl_c2hcmd_wq_callback);

}

@@ -489,6 +491,7 @@ void rtl_deinit_deferred_work(struct ieee80211_hw *hw)
	cancel_delayed_work(&rtlpriv->works.ps_work);
	cancel_delayed_work(&rtlpriv->works.ps_rfon_wq);
	cancel_delayed_work(&rtlpriv->works.fwevt_wq);
	cancel_delayed_work(&rtlpriv->works.c2hcmd_wq);
}
EXPORT_SYMBOL_GPL(rtl_deinit_deferred_work);

@@ -556,6 +559,7 @@ int rtl_init_core(struct ieee80211_hw *hw)
	spin_lock_init(&rtlpriv->locks.rf_lock);
	spin_lock_init(&rtlpriv->locks.waitq_lock);
	spin_lock_init(&rtlpriv->locks.entry_list_lock);
	spin_lock_init(&rtlpriv->locks.c2hcmd_lock);
	spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock);
	spin_lock_init(&rtlpriv->locks.check_sendpkt_lock);
	spin_lock_init(&rtlpriv->locks.fw_ps_lock);
@@ -563,6 +567,7 @@ int rtl_init_core(struct ieee80211_hw *hw)
	spin_lock_init(&rtlpriv->locks.iqk_lock);
	/* <5> init list */
	INIT_LIST_HEAD(&rtlpriv->entry_list);
	INIT_LIST_HEAD(&rtlpriv->c2hcmd_list);

	rtlmac->link_state = MAC80211_NOLINK;

@@ -575,6 +580,7 @@ EXPORT_SYMBOL_GPL(rtl_init_core);

void rtl_deinit_core(struct ieee80211_hw *hw)
{
	rtl_c2hcmd_launcher(hw, 0);
}
EXPORT_SYMBOL_GPL(rtl_deinit_core);

@@ -1729,6 +1735,93 @@ void rtl_fwevt_wq_callback(void *data)

	rtlpriv->cfg->ops->c2h_command_handle(hw);
}

void rtl_c2hcmd_enqueue(struct ieee80211_hw *hw, u8 tag, u8 len, u8 *val)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	unsigned long flags;
	struct rtl_c2hcmd *c2hcmd;

	c2hcmd = kmalloc(sizeof(*c2hcmd), GFP_KERNEL);

	if (!c2hcmd)
		goto label_err;

	c2hcmd->val = kmalloc(len, GFP_KERNEL);

	if (!c2hcmd->val)
		goto label_err2;

	/* fill data */
	c2hcmd->tag = tag;
	c2hcmd->len = len;
	memcpy(c2hcmd->val, val, len);

	/* enqueue */
	spin_lock_irqsave(&rtlpriv->locks.c2hcmd_lock, flags);

	list_add_tail(&c2hcmd->list, &rtlpriv->c2hcmd_list);

	spin_unlock_irqrestore(&rtlpriv->locks.c2hcmd_lock, flags);

	/* wake up wq */
	queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.c2hcmd_wq, 0);

	return;

label_err2:
	kfree(c2hcmd);

label_err:
	RT_TRACE(rtlpriv, COMP_CMD, DBG_WARNING,
		 "C2H cmd enqueue fail.\n");
}
EXPORT_SYMBOL(rtl_c2hcmd_enqueue);

void rtl_c2hcmd_launcher(struct ieee80211_hw *hw, int exec)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	unsigned long flags;
	struct rtl_c2hcmd *c2hcmd;
	int i;

	for (i = 0; i < 200; i++) {
		/* dequeue a task */
		spin_lock_irqsave(&rtlpriv->locks.c2hcmd_lock, flags);

		c2hcmd = list_first_entry_or_null(&rtlpriv->c2hcmd_list,
						  struct rtl_c2hcmd, list);

		if (c2hcmd)
			list_del(&c2hcmd->list);

		spin_unlock_irqrestore(&rtlpriv->locks.c2hcmd_lock, flags);

		/* do it */
		if (!c2hcmd)
			break;

		if (rtlpriv->cfg->ops->c2h_content_parsing && exec)
			rtlpriv->cfg->ops->c2h_content_parsing(hw,
					c2hcmd->tag, c2hcmd->len, c2hcmd->val);

		/* free */
		kfree(c2hcmd->val);

		kfree(c2hcmd);
	}
}

void rtl_c2hcmd_wq_callback(void *data)
{
	struct rtl_works *rtlworks = container_of_dwork_rtl(data,
							    struct rtl_works,
							    c2hcmd_wq);
	struct ieee80211_hw *hw = rtlworks->hw;

	rtl_c2hcmd_launcher(hw, 1);
}

void rtl_easy_concurrent_retrytimer_callback(unsigned long data)
{
	struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
+3 −0
Original line number Diff line number Diff line
@@ -136,6 +136,9 @@ int rtl_rx_agg_stop(struct ieee80211_hw *hw,
		    struct ieee80211_sta *sta, u16 tid);
void rtl_watchdog_wq_callback(void *data);
void rtl_fwevt_wq_callback(void *data);
void rtl_c2hcmd_wq_callback(void *data);
void rtl_c2hcmd_launcher(struct ieee80211_hw *hw, int exec);
void rtl_c2hcmd_enqueue(struct ieee80211_hw *hw, u8 tag, u8 len, u8 *val);

void rtl_get_tcb_desc(struct ieee80211_hw *hw,
		      struct ieee80211_tx_info *info,
+12 −3
Original line number Diff line number Diff line
@@ -764,7 +764,7 @@ static void _rtl92ee_c2h_ra_report_handler(struct ieee80211_hw *hw,
	rtl92ee_dm_dynamic_arfb_select(hw, rate, collision_state);
}

static void _rtl92ee_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id,
void rtl92ee_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id,
				 u8 c2h_cmd_len, u8 *tmp_buf)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -820,5 +820,14 @@ void rtl92ee_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len)
	RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_TRACE,
		      "[C2H packet], Content Hex:\n", tmp_buf, c2h_cmd_len);

	_rtl92ee_c2h_content_parsing(hw, c2h_cmd_id, c2h_cmd_len, tmp_buf);
	switch (c2h_cmd_id) {
	case C2H_8192E_BT_INFO:
	case C2H_8192E_BT_MP:
		rtl_c2hcmd_enqueue(hw, c2h_cmd_id, c2h_cmd_len, tmp_buf);
		break;
	default:
		rtl92ee_c2h_content_parsing(hw, c2h_cmd_id, c2h_cmd_len,
					    tmp_buf);
		break;
	}
}
+2 −1
Original line number Diff line number Diff line
@@ -185,5 +185,6 @@ void rtl92ee_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus);
void rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
void rtl92ee_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state);
void rtl92ee_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len);

void rtl92ee_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id,
				 u8 c2h_cmd_len, u8 *tmp_buf);
#endif
+1 −0
Original line number Diff line number Diff line
@@ -248,6 +248,7 @@ static struct rtl_hal_ops rtl8192ee_hal_ops = {
	.fill_h2c_cmd = rtl92ee_fill_h2c_cmd,
	.get_btc_status = rtl92ee_get_btc_status,
	.rx_command_packet = rtl92ee_rx_command_packet,
	.c2h_content_parsing = rtl92ee_c2h_content_parsing,
};

static struct rtl_mod_params rtl92ee_mod_params = {
Loading