[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