[PATCH] Synchronize smd commands
Eugene Krasnikov
k.eugene.e at gmail.com
Fri Jul 5 06:31:21 EDT 2013
https://github.com/KrasnikovEugene/wcn36xx/pull/66
2013/7/5 Eugene Krasnikov <k.eugene.e at gmail.com>:
> Add protection to smd api to make sure all smd
> commands are sent sequentially.
>
> Signed-off-by: Eugene Krasnikov <k.eugene.e at gmail.com>
> ---
> main.c | 2 ++
> smd.c | 24 ++++++++++++++++++++----
> wcn36xx.h | 6 ++++++
> 3 files changed, 28 insertions(+), 4 deletions(-)
>
> diff --git a/main.c b/main.c
> index 0cc3e02..cb2a5d8 100644
> --- a/main.c
> +++ b/main.c
> @@ -945,6 +945,7 @@ static int __init wcn36xx_init(void)
> wcn->is_joining = false;
>
> mutex_init(&wcn->pm_mutex);
> + mutex_init(&wcn->smd_mutex);
> wcn->hw->wiphy->n_addresses = ARRAY_SIZE(wcn->addresses);
> wcn->hw->wiphy->addresses = wcn->addresses;
>
> @@ -1002,6 +1003,7 @@ static void __exit wcn36xx_exit(void)
> struct wcn36xx *wcn = hw->priv;
>
> mutex_destroy(&wcn->pm_mutex);
> + mutex_destroy(&wcn->smd_mutex);
> ieee80211_unregister_hw(hw);
> destroy_workqueue(wcn->wq);
> iounmap(wcn->mmio);
> diff --git a/smd.c b/smd.c
> index ce09563..d291607 100644
> --- a/smd.c
> +++ b/smd.c
> @@ -20,6 +20,7 @@
> 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);
> @@ -29,19 +30,28 @@ static int wcn36xx_smd_send_and_wait(struct wcn36xx *wcn, size_t len)
> avail = smd_write(wcn->smd_ch, wcn->smd_buf, len);
> if (avail != len) {
> wcn36xx_error("Cannot write to SMD channel");
> - return -EAGAIN;
> + ret = -EAGAIN;
> + goto out;
> +
> }
> } else {
> wcn36xx_error("SMD channel can accept only %d bytes", avail);
> - return -ENOMEM;
> + 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");
> - return -ETIME;
> + ret = -ETIME;
> + goto out;
> +
> }
> - return 0;
> +out:
> + mutex_unlock(&wcn->smd_mutex);
> + return ret;
> +
> }
>
> #define INIT_HAL_MSG(msg_body, type) \
> @@ -54,6 +64,10 @@ static int wcn36xx_smd_send_and_wait(struct wcn36xx *wcn, size_t len)
>
> #define PREPARE_HAL_BUF(send_buf, msg_body) \
> do { \
> + struct wcn36xx *__wcn = \
> + container_of(&send_buf, \
> + struct wcn36xx, smd_buf); \
> + mutex_lock(&__wcn->smd_mutex); \
> memset(send_buf, 0, msg_body.header.len); \
> memcpy(send_buf, &msg_body, sizeof(msg_body)); \
> } while (0) \
> @@ -101,6 +115,8 @@ int wcn36xx_smd_load_nv(struct wcn36xx *wcn)
> msg_body.header.len = sizeof(msg_body) + fw_bytes_left;
>
> }
> + /* smd_buf must be protected with mutex */
> + mutex_lock(&wcn->smd_mutex);
>
> /* Add load NV request message header */
> memcpy(wcn->smd_buf, &msg_body, sizeof(msg_body));
> diff --git a/wcn36xx.h b/wcn36xx.h
> index 2c72349..653381f 100644
> --- a/wcn36xx.h
> +++ b/wcn36xx.h
> @@ -139,7 +139,13 @@ struct wcn36xx {
>
> /* 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
> + */
> u8 *smd_buf;
> + struct mutex smd_mutex;
> +
> struct work_struct smd_work;
> struct work_struct start_work;
> struct work_struct rx_ready_work;
> --
> 1.7.11.3
>
--
Best regards,
Eugene
More information about the wcn36xx
mailing list