[PATCH] Move SMD handling to wcn36xx_msm

Eugene Krasnikov k.eugene.e at gmail.com
Thu Aug 8 05:23:28 EDT 2013


Platform dependent code must be located in wcn36xx_msm.

Signed-off-by: Eugene Krasnikov <k.eugene.e at gmail.com>
---
 main.c             |  14 -----
 smd.c              | 113 ++-------------------------------------
 wcn36xx.h          |   8 ---
 wcn36xx_msm/main.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 155 insertions(+), 131 deletions(-)

diff --git a/main.c b/main.c
index 50e70ab..34d2d49 100644
--- a/main.c
+++ b/main.c
@@ -204,9 +204,6 @@ static int wcn36xx_start(struct ieee80211_hw *hw)
 		goto out_err;
 	}
 
-	/* Not to receive INT until the whole buf from SMD is read */
-	smd_disable_read_intr(wcn->smd_ch);
-
 	/* Allocate memory pools for Mgmt BD headers and Data BD headers */
 	ret = wcn36xx_dxe_allocate_mem_pools(wcn);
 	if (ret) {
@@ -737,8 +734,6 @@ static int wcn36xx_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wow)
 	wcn->is_suspended = true;
 	wcn->is_con_lost_pending = false;
 
-	flush_work(&wcn->smd_work);
-
 	mutex_unlock(&wcn->pm_mutex);
 
 	return 0;
@@ -1029,12 +1024,6 @@ static int __devinit wcn36xx_probe(struct platform_device *pdev)
 	wcn36xx_read_mac_addresses(wcn);
 	SET_IEEE80211_PERM_ADDR(wcn->hw, wcn->addresses[0].addr);
 
-	wcn->wq = create_workqueue("wcn36xx_wq");
-	if (!wcn->wq) {
-		wcn36xx_error("failed to allocate wq");
-		ret = -ENOMEM;
-		goto out_hw;
-	}
 	ret = wcn36xx_platform_get_resources(wcn, pdev);
 	if (ret)
 		goto out_wq;
@@ -1049,8 +1038,6 @@ static int __devinit wcn36xx_probe(struct platform_device *pdev)
 out_unmap:
 	iounmap(wcn->mmio);
 out_wq:
-	destroy_workqueue(wcn->wq);
-out_hw:
 	ieee80211_free_hw(hw);
 out_err:
 	return ret;
@@ -1065,7 +1052,6 @@ static int __devexit wcn36xx_remove(struct platform_device *pdev)
 	mutex_destroy(&wcn->smd_mutex);
 
 	ieee80211_unregister_hw(hw);
-	destroy_workqueue(wcn->wq);
 	iounmap(wcn->mmio);
 	ieee80211_free_hw(hw);
 
diff --git a/smd.c b/smd.c
index a00f35b..87ec564 100644
--- a/smd.c
+++ b/smd.c
@@ -143,34 +143,10 @@ static void wcn36xx_smd_set_sta_params(struct wcn36xx *wcn,
 
 static int wcn36xx_smd_send_and_wait(struct wcn36xx *wcn, size_t len)
 {
-	int avail;
-	int ret = 0;
-
-	init_completion(&wcn->smd_compl);
-	avail = smd_write_avail(wcn->smd_ch);
-
+	int ret;
 	wcn36xx_dbg_dump(WCN36XX_DBG_SMD_DUMP, "SMD >>> ", wcn->smd_buf, len);
 
-	if (avail >= len) {
-		avail = smd_write(wcn->smd_ch, wcn->smd_buf, len);
-		if (avail != len) {
-			wcn36xx_error("Cannot write to SMD channel");
-			ret = -EAGAIN;
-			goto out;
-		}
-	} else {
-		wcn36xx_error("SMD channel can accept only %d bytes", avail);
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	if (wait_for_completion_timeout(&wcn->smd_compl,
-		msecs_to_jiffies(SMD_MSG_TIMEOUT)) <= 0) {
-		wcn36xx_error("Timeout while waiting SMD response");
-		ret = -ETIME;
-		goto out;
-	}
-out:
+	ret = wcn->ctrl_ops->tx(wcn->smd_buf, len);
 	mutex_unlock(&wcn->smd_mutex);
 	return ret;
 }
@@ -1356,29 +1332,6 @@ int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index)
 	return wcn36xx_smd_send_and_wait(wcn, msg_body.header.len);
 }
 
-static void wcn36xx_smd_notify(void *data, unsigned event)
-{
-	struct wcn36xx *wcn = (struct wcn36xx *)data;
-
-	switch (event) {
-	case SMD_EVENT_OPEN:
-		complete(&wcn->smd_compl);
-		break;
-	case SMD_EVENT_DATA:
-		queue_work(wcn->wq, &wcn->smd_work);
-		break;
-	case SMD_EVENT_CLOSE:
-		break;
-	case SMD_EVENT_STATUS:
-		break;
-	case SMD_EVENT_REOPEN_READY:
-		break;
-	default:
-		wcn36xx_error("SMD_EVENT (%d) not supported", event);
-		break;
-	}
-}
-
 static int wcn36xx_smd_tx_compl_ind(struct wcn36xx *wcn, void *buf, size_t len)
 {
 	struct wcn36xx_hal_tx_compl_ind_msg *rsp = buf;
@@ -1527,70 +1480,12 @@ static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len)
 	}
 }
 
-static void wcn36xx_smd_work(struct work_struct *work)
-{
-	int msg_len;
-	int avail;
-	void *msg;
-	int ret;
-	struct wcn36xx *wcn =
-		container_of(work, struct wcn36xx, smd_work);
-
-	if (!wcn)
-		return;
-
-	while (1) {
-		msg_len = smd_cur_packet_size(wcn->smd_ch);
-		if (0 == msg_len) {
-			complete(&wcn->smd_compl);
-			return;
-		}
-
-		avail = smd_read_avail(wcn->smd_ch);
-		if (avail < msg_len) {
-			complete(&wcn->smd_compl);
-			return;
-		}
-		msg = kmalloc(msg_len, GFP_KERNEL);
-		if (NULL == msg) {
-			complete(&wcn->smd_compl);
-			return;
-		}
-		ret = smd_read(wcn->smd_ch, msg, msg_len);
-		if (ret != msg_len) {
-			complete(&wcn->smd_compl);
-			return;
-		}
-		wcn36xx_smd_rsp_process(wcn, msg, msg_len);
-		kfree(msg);
-	}
-}
-
 int wcn36xx_smd_open(struct wcn36xx *wcn)
 {
-	int ret, left;
-
-	INIT_WORK(&wcn->smd_work, wcn36xx_smd_work);
-	init_completion(&wcn->smd_compl);
-
-	ret = smd_named_open_on_edge("WLAN_CTRL", SMD_APPS_WCNSS,
-				     &wcn->smd_ch, wcn, wcn36xx_smd_notify);
-	if (ret) {
-		wcn36xx_error("smd_named_open_on_edge failed: %d", ret);
-		return ret;
-	}
-
-	left = wait_for_completion_interruptible_timeout(&wcn->smd_compl,
-		msecs_to_jiffies(SMD_MSG_TIMEOUT));
-	if (left <= 0) {
-		wcn36xx_error("timeout waiting for smd open: %d", ret);
-		return left;
-	}
-
-	return 0;
+	return wcn->ctrl_ops->open(wcn, wcn36xx_smd_rsp_process);
 }
 
 void wcn36xx_smd_close(struct wcn36xx *wcn)
 {
-	smd_close(wcn->smd_ch);
+	wcn->ctrl_ops->close();
 }
diff --git a/wcn36xx.h b/wcn36xx.h
index 24ea793..271020a 100644
--- a/wcn36xx.h
+++ b/wcn36xx.h
@@ -21,7 +21,6 @@
 #include <linux/completion.h>
 #include <linux/printk.h>
 #include <linux/spinlock.h>
-#include <linux/workqueue.h>
 #include <mach/msm_smd.h>
 #include <net/mac80211.h>
 
@@ -159,7 +158,6 @@ struct wcn36xx_sta {
 struct wcn36xx_dxe_ch;
 struct wcn36xx {
 	struct ieee80211_hw	*hw;
-	struct workqueue_struct	*wq;
 	struct device		*dev;
 	struct mac_address	addresses[2];
 	struct wcn36xx_hal_mac_ssid ssid;
@@ -193,8 +191,6 @@ struct wcn36xx {
 	struct wcn36xx_hal_supported_rates supported_rates;
 
 	struct wcn36xx_platform_ctrl_ops *ctrl_ops;
-	/* SMD related */
-	smd_channel_t		*smd_ch;
 	/*
 	 * smd_buf must be protected with smd_mutex to garantee
 	 * that all messages are sent one after another
@@ -202,10 +198,6 @@ struct wcn36xx {
 	u8			*smd_buf;
 	struct mutex		smd_mutex;
 
-	struct work_struct	smd_work;
-	struct work_struct	start_work;
-	struct completion	smd_compl;
-
 	bool			is_joining;
 
 	/* DXE channels */
diff --git a/wcn36xx_msm/main.c b/wcn36xx_msm/main.c
index 8827a94..db7605c 100644
--- a/wcn36xx_msm/main.c
+++ b/wcn36xx_msm/main.c
@@ -14,16 +14,164 @@
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <linux/completion.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/wcnss_wlan.h>
+#include <linux/workqueue.h>
+#include <mach/msm_smd.h>
 #include "../wcn36xx.h"
 
 struct wcn36xx_msm {
 	struct wcn36xx_platform_ctrl_ops ctrl_ops;
 	struct platform_device *core;
+	void *drv_priv;
+	void (*rsp_cb)(void *drv_priv, void *buf, size_t len);
+	/* SMD related */
+	struct workqueue_struct	*wq;
+	struct work_struct	smd_work;
+	struct completion	smd_compl;
+	smd_channel_t		*smd_ch;
 } wmsm;
 
+static int wcn36xx_msm_smd_send_and_wait(char *buf, size_t len)
+{
+	int avail;
+	int ret = 0;
+
+	init_completion(&wmsm.smd_compl);
+	avail = smd_write_avail(wmsm.smd_ch);
+
+	if (avail >= len) {
+		avail = smd_write(wmsm.smd_ch, buf, len);
+		if (avail != len) {
+			dev_err(&wmsm.core->dev,
+				"Cannot write to SMD channel\n");
+			ret = -EAGAIN;
+			goto out;
+		}
+	} else {
+		dev_err(&wmsm.core->dev,
+			"SMD channel can accept only %d bytes\n", avail);
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (wait_for_completion_timeout(&wmsm.smd_compl,
+		msecs_to_jiffies(SMD_MSG_TIMEOUT)) <= 0) {
+		dev_err(&wmsm.core->dev,
+			"Timeout while waiting SMD response\n");
+		ret = -ETIME;
+		goto out;
+	}
+out:
+	return ret;
+}
+
+static void wcn36xx_msm_smd_notify(void *data, unsigned event)
+{
+	struct wcn36xx_msm *wmsm_priv = (struct wcn36xx_msm *)data;
+
+	switch (event) {
+	case SMD_EVENT_OPEN:
+		complete(&wmsm_priv->smd_compl);
+		break;
+	case SMD_EVENT_DATA:
+		queue_work(wmsm_priv->wq, &wmsm_priv->smd_work);
+		break;
+	case SMD_EVENT_CLOSE:
+		break;
+	case SMD_EVENT_STATUS:
+		break;
+	case SMD_EVENT_REOPEN_READY:
+		break;
+	default:
+		dev_err(&wmsm_priv->core->dev,
+			"SMD_EVENT (%d) not supported\n", event);
+		break;
+	}
+}
+
+static void wcn36xx_msm_smd_work(struct work_struct *work)
+{
+	int avail;
+	int msg_len;
+	void *msg;
+	int ret;
+	struct wcn36xx_msm *wmsm_priv =
+		container_of(work, struct wcn36xx_msm, smd_work);
+
+	while (1) {
+		msg_len = smd_cur_packet_size(wmsm_priv->smd_ch);
+		if (0 == msg_len) {
+			complete(&wmsm_priv->smd_compl);
+			return;
+		}
+		avail = smd_read_avail(wmsm_priv->smd_ch);
+		if (avail < msg_len) {
+			complete(&wmsm_priv->smd_compl);
+			return;
+		}
+		msg = kmalloc(msg_len, GFP_KERNEL);
+		if (NULL == msg) {
+			complete(&wmsm_priv->smd_compl);
+			return;
+		}
+
+		ret = smd_read(wmsm_priv->smd_ch, msg, msg_len);
+		if (ret != msg_len) {
+			complete(&wmsm_priv->smd_compl);
+			return;
+		}
+		wmsm_priv->rsp_cb(wmsm_priv->drv_priv, msg, msg_len);
+		kfree(msg);
+	}
+}
+
+int wcn36xx_msm_smd_open(void *drv_priv, void *rsp_cb)
+{
+	int ret, left;
+	wmsm.drv_priv = drv_priv;
+	wmsm.rsp_cb = rsp_cb;
+	INIT_WORK(&wmsm.smd_work, wcn36xx_msm_smd_work);
+	init_completion(&wmsm.smd_compl);
+
+	wmsm.wq = create_workqueue("wcn36xx_msm_smd_wq");
+	if (!wmsm.wq) {
+		dev_err(&wmsm.core->dev, "failed to allocate wq");
+		ret = -ENOMEM;
+		return ret;
+	}
+
+	ret = smd_named_open_on_edge("WLAN_CTRL", SMD_APPS_WCNSS,
+		&wmsm.smd_ch, &wmsm, wcn36xx_msm_smd_notify);
+	if (ret) {
+		dev_err(&wmsm.core->dev,
+			"smd_named_open_on_edge failed: %d\n", ret);
+		return ret;
+	}
+
+	left = wait_for_completion_interruptible_timeout(&wmsm.smd_compl,
+		msecs_to_jiffies(SMD_MSG_TIMEOUT));
+	if (left <= 0) {
+		dev_err(&wmsm.core->dev,
+			"timeout waiting for smd open: %d\n", ret);
+		return left;
+	}
+
+	/* Not to receive INT until the whole buf from SMD is read */
+	smd_disable_read_intr(wmsm.smd_ch);
+
+	return 0;
+}
+
+void wcn36xx_msm_smd_close(void)
+{
+	smd_close(wmsm.smd_ch);
+	flush_workqueue(wmsm.wq);
+	destroy_workqueue(wmsm.wq);
+}
+
 static int __init wcn36xx_msm_init(void)
 {
 	int ret;
@@ -34,6 +182,9 @@ static int __init wcn36xx_msm_init(void)
 	wmsm.core = platform_device_alloc("wcn36xx", -1);
 
 	memset(res, 0x00, sizeof(res));
+	wmsm.ctrl_ops.open = wcn36xx_msm_smd_open;
+	wmsm.ctrl_ops.close = wcn36xx_msm_smd_close;
+	wmsm.ctrl_ops.tx = wcn36xx_msm_smd_send_and_wait;
 
 	wcnss_memory =
 		platform_get_resource_byname(wcnss_get_platform_device(),
-- 
1.8.2.2




More information about the wcn36xx mailing list