[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