[PATCH 4/4] Move SMD handling to wcn36xx_msm
Eugene Krasnikov
k.eugene.e at gmail.com
Thu Aug 8 03:44:30 EDT 2013
https://github.com/KrasnikovEugene/wcn36xx/pull/105
2013/8/8 Eugene Krasnikov <k.eugene.e at gmail.com>:
> 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..18c64b2 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);
> + destroy_workqueue(wmsm.wq);
> + flush_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
>
--
Best regards,
Eugene
More information about the wcn36xx
mailing list