Re: [PATCH] soc: qcom: Introduce WCNSS_CTRL SMD client

2015-10-23 Thread yfw

Hi Bjorn,

On 2015/10/22 21:50, Bjorn Andersson wrote:

On Thu 22 Oct 03:25 PDT 2015, yfw wrote:


Hi Bjorn,

On 2015/9/22 1:52, Bjorn Andersson wrote:

[..]


I have a question: Do you have plan to add the nob to trigger wcnss firmware
downloading which is also common for wifi and BT?



In caf the wcnss driver is actually two drivers intermingled;
* a SMD client driver, responsible for pushing NV, something related to
   calibration, some power properties and so on

* a platform_driver implementing the wcnss specifics of the PIL through
   some hooks and providing the knob to trigger the PIL.

The first driver is related to the "OS" running on the wcnss, so that
should follow the life cycle of the SMD channel "WCNSS_CTRL". This is
what this patch provides - it loads the NV every time the wcnss core is
booted.


For the second part, I strongly believe that the PIL implementation
should deal with the specifics (e.g. regulator handling and
xo_calibration), rather than having a piece bolted on elsewhere - so
that's in the remoteproc-wcnss driver.


Yes. I meant this remoteproc-wcnss driver. Will you try to upstream it?



Left is a mechanism to trigger the thing to boot and shutdown. One
potential solution would be to have the module_init/exit call
rproc_boot/shutdown from the WiFi & BT drivers. That way if one loads
the wcn36xx driver, the core is booted. This would also fit quite nicely
for other things - e.g. load the ALSA driver to trigger the ADSP
loading.

The problem here is that we're then forced to either have a method of
deferring the rproc_boot() until the firmware is available or we always
must compile these drivers as kernel modules. This because the
file system isn't there during boot to provide the firmware.

The firmware file could be put to initrd. That should allow wcn wifi driver
builtin.



We do have the same thing in e.g. the Broadcom WiFi/BT solution and
there seems to be discussions related to this.


So for now, I punted and put a knob in the wcnss remoteproc driver.

Regards,
Bjorn



Regards
Yin, Fengwei

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] soc: qcom: Introduce WCNSS_CTRL SMD client

2015-10-23 Thread yfw

Hi Bjorn,

On 2015/10/22 21:50, Bjorn Andersson wrote:

On Thu 22 Oct 03:25 PDT 2015, yfw wrote:


Hi Bjorn,

On 2015/9/22 1:52, Bjorn Andersson wrote:

[..]


I have a question: Do you have plan to add the nob to trigger wcnss firmware
downloading which is also common for wifi and BT?



In caf the wcnss driver is actually two drivers intermingled;
* a SMD client driver, responsible for pushing NV, something related to
   calibration, some power properties and so on

* a platform_driver implementing the wcnss specifics of the PIL through
   some hooks and providing the knob to trigger the PIL.

The first driver is related to the "OS" running on the wcnss, so that
should follow the life cycle of the SMD channel "WCNSS_CTRL". This is
what this patch provides - it loads the NV every time the wcnss core is
booted.


For the second part, I strongly believe that the PIL implementation
should deal with the specifics (e.g. regulator handling and
xo_calibration), rather than having a piece bolted on elsewhere - so
that's in the remoteproc-wcnss driver.


Yes. I meant this remoteproc-wcnss driver. Will you try to upstream it?



Left is a mechanism to trigger the thing to boot and shutdown. One
potential solution would be to have the module_init/exit call
rproc_boot/shutdown from the WiFi & BT drivers. That way if one loads
the wcn36xx driver, the core is booted. This would also fit quite nicely
for other things - e.g. load the ALSA driver to trigger the ADSP
loading.

The problem here is that we're then forced to either have a method of
deferring the rproc_boot() until the firmware is available or we always
must compile these drivers as kernel modules. This because the
file system isn't there during boot to provide the firmware.

The firmware file could be put to initrd. That should allow wcn wifi driver
builtin.



We do have the same thing in e.g. the Broadcom WiFi/BT solution and
there seems to be discussions related to this.


So for now, I punted and put a knob in the wcnss remoteproc driver.

Regards,
Bjorn



Regards
Yin, Fengwei

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] soc: qcom: Introduce WCNSS_CTRL SMD client

2015-10-22 Thread yfw

Hi Bjorn,

On 2015/9/22 1:52, Bjorn Andersson wrote:

The WCNSS_CTRL SMD client is used for among other things upload nv
firmware to a newly booted WCNSS chip.

Signed-off-by: Bjorn Andersson 
---
This driver probes on the WCNSS_CTRL SMD channel as it comes up upon loading
the wcnss firmware, it currenly request version information from the wcnss and
downloads the nv binary.

This is needed for bringing up the individual functions of the wcnss chip.

  drivers/soc/qcom/Kconfig  |   7 ++
  drivers/soc/qcom/Makefile |   1 +
  drivers/soc/qcom/wcnss_ctrl.c | 272 ++
  3 files changed, 280 insertions(+)
  create mode 100644 drivers/soc/qcom/wcnss_ctrl.c

diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index ba47b70f4d85..453ceb1af682 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -48,3 +48,10 @@ config QCOM_SMEM
  Say y here to enable support for the Qualcomm Shared Memory Manager.
  The driver provides an interface to items in a heap shared among all
  processors in a Qualcomm platform.
+
+config QCOM_WCNSS_CTRL
+   tristate "Qualcomm WCNSS control driver"
+   depends on QCOM_SMD
+   help
+ Client driver for the WCNSS_CTRL SMD channel, used to download nv
+ firmware to a newly booted WCNSS chip.
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index 10a93d168e0e..9823103ea843 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_QCOM_PM)   +=  spm.o
  obj-$(CONFIG_QCOM_SMD) += smd.o
  obj-$(CONFIG_QCOM_SMD_RPM)+= smd-rpm.o
  obj-$(CONFIG_QCOM_SMEM) +=smem.o
+obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
diff --git a/drivers/soc/qcom/wcnss_ctrl.c b/drivers/soc/qcom/wcnss_ctrl.c
new file mode 100644
index ..7a986f881d5c
--- /dev/null
+++ b/drivers/soc/qcom/wcnss_ctrl.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2015, Sony Mobile Communications Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include 
+#include 
+#include 
+#include 
+
+#define WCNSS_REQUEST_TIMEOUT  (5 * HZ)
+
+#define NV_FRAGMENT_SIZE   3072
+#define NVBIN_FILE "wlan/prima/WCNSS_qcom_wlan_nv.bin"
+
+/**
+ * struct wcnss_ctrl - driver context
+ * @dev:   device handle
+ * @channel:   SMD channel handle
+ * @ack:   completion for outstanding requests
+ * @ack_status:status of the outstanding request
+ * @download_nv_work: worker for uploading nv binary
+ */
+struct wcnss_ctrl {
+   struct device *dev;
+   struct qcom_smd_channel *channel;
+
+   struct completion ack;
+   int ack_status;
+
+   struct work_struct download_nv_work;
+};
+
+/* message types */
+enum {
+   WCNSS_VERSION_REQ = 0x0100,
+   WCNSS_VERSION_RESP,
+   WCNSS_DOWNLOAD_NV_REQ,
+   WCNSS_DOWNLOAD_NV_RESP,
+   WCNSS_UPLOAD_CAL_REQ,
+   WCNSS_UPLOAD_CAL_RESP,
+   WCNSS_DOWNLOAD_CAL_REQ,
+   WCNSS_DOWNLOAD_CAL_RESP,
+};
+
+/**
+ * struct wcnss_msg_hdr - common packet header for requests and responses
+ * @type:  packet message type
+ * @len:   total length of the packet, including this header
+ */
+struct wcnss_msg_hdr {
+   u32 type;
+   u32 len;
+} __packed;
+
+/**
+ * struct wcnss_version_resp - version request response
+ * @hdr:   common packet wcnss_msg_hdr header
+ */
+struct wcnss_version_resp {
+   struct wcnss_msg_hdr hdr;
+   u8 major;
+   u8 minor;
+   u8 version;
+   u8 revision;
+} __packed;
+
+/**
+ * struct wcnss_download_nv_req - firmware fragment request
+ * @hdr:   common packet wcnss_msg_hdr header
+ * @seq:   sequence number of this fragment
+ * @last:  boolean indicator of this being the last fragment of the binary
+ * @frag_size: length of this fragment
+ * @fragment:  fragment data
+ */
+struct wcnss_download_nv_req {
+   struct wcnss_msg_hdr hdr;
+   u16 seq;
+   u16 last;
+   u32 frag_size;
+   u8 fragment[];
+} __packed;
+
+/**
+ * struct wcnss_download_nv_resp - firmware download response
+ * @hdr:   common packet wcnss_msg_hdr header
+ * @status:boolean to indicate success of the download
+ */
+struct wcnss_download_nv_resp {
+   struct wcnss_msg_hdr hdr;
+   u8 status;
+} __packed;
+
+/**
+ * wcnss_ctrl_smd_callback() - handler from SMD responses
+ * @qsdev: smd device handle
+ * @data:  pointer to the incoming data packet
+ * @count: size of the incoming data packet
+ *
+ * Handles any incoming packets from the remote 

Re: [PATCH] soc: qcom: Introduce WCNSS_CTRL SMD client

2015-10-22 Thread yfw

Hi Bjorn,

On 2015/9/22 1:52, Bjorn Andersson wrote:

The WCNSS_CTRL SMD client is used for among other things upload nv
firmware to a newly booted WCNSS chip.

Signed-off-by: Bjorn Andersson 
---
This driver probes on the WCNSS_CTRL SMD channel as it comes up upon loading
the wcnss firmware, it currenly request version information from the wcnss and
downloads the nv binary.

This is needed for bringing up the individual functions of the wcnss chip.

  drivers/soc/qcom/Kconfig  |   7 ++
  drivers/soc/qcom/Makefile |   1 +
  drivers/soc/qcom/wcnss_ctrl.c | 272 ++
  3 files changed, 280 insertions(+)
  create mode 100644 drivers/soc/qcom/wcnss_ctrl.c

diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index ba47b70f4d85..453ceb1af682 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -48,3 +48,10 @@ config QCOM_SMEM
  Say y here to enable support for the Qualcomm Shared Memory Manager.
  The driver provides an interface to items in a heap shared among all
  processors in a Qualcomm platform.
+
+config QCOM_WCNSS_CTRL
+   tristate "Qualcomm WCNSS control driver"
+   depends on QCOM_SMD
+   help
+ Client driver for the WCNSS_CTRL SMD channel, used to download nv
+ firmware to a newly booted WCNSS chip.
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index 10a93d168e0e..9823103ea843 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_QCOM_PM)   +=  spm.o
  obj-$(CONFIG_QCOM_SMD) += smd.o
  obj-$(CONFIG_QCOM_SMD_RPM)+= smd-rpm.o
  obj-$(CONFIG_QCOM_SMEM) +=smem.o
+obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
diff --git a/drivers/soc/qcom/wcnss_ctrl.c b/drivers/soc/qcom/wcnss_ctrl.c
new file mode 100644
index ..7a986f881d5c
--- /dev/null
+++ b/drivers/soc/qcom/wcnss_ctrl.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2015, Sony Mobile Communications Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include 
+#include 
+#include 
+#include 
+
+#define WCNSS_REQUEST_TIMEOUT  (5 * HZ)
+
+#define NV_FRAGMENT_SIZE   3072
+#define NVBIN_FILE "wlan/prima/WCNSS_qcom_wlan_nv.bin"
+
+/**
+ * struct wcnss_ctrl - driver context
+ * @dev:   device handle
+ * @channel:   SMD channel handle
+ * @ack:   completion for outstanding requests
+ * @ack_status:status of the outstanding request
+ * @download_nv_work: worker for uploading nv binary
+ */
+struct wcnss_ctrl {
+   struct device *dev;
+   struct qcom_smd_channel *channel;
+
+   struct completion ack;
+   int ack_status;
+
+   struct work_struct download_nv_work;
+};
+
+/* message types */
+enum {
+   WCNSS_VERSION_REQ = 0x0100,
+   WCNSS_VERSION_RESP,
+   WCNSS_DOWNLOAD_NV_REQ,
+   WCNSS_DOWNLOAD_NV_RESP,
+   WCNSS_UPLOAD_CAL_REQ,
+   WCNSS_UPLOAD_CAL_RESP,
+   WCNSS_DOWNLOAD_CAL_REQ,
+   WCNSS_DOWNLOAD_CAL_RESP,
+};
+
+/**
+ * struct wcnss_msg_hdr - common packet header for requests and responses
+ * @type:  packet message type
+ * @len:   total length of the packet, including this header
+ */
+struct wcnss_msg_hdr {
+   u32 type;
+   u32 len;
+} __packed;
+
+/**
+ * struct wcnss_version_resp - version request response
+ * @hdr:   common packet wcnss_msg_hdr header
+ */
+struct wcnss_version_resp {
+   struct wcnss_msg_hdr hdr;
+   u8 major;
+   u8 minor;
+   u8 version;
+   u8 revision;
+} __packed;
+
+/**
+ * struct wcnss_download_nv_req - firmware fragment request
+ * @hdr:   common packet wcnss_msg_hdr header
+ * @seq:   sequence number of this fragment
+ * @last:  boolean indicator of this being the last fragment of the binary
+ * @frag_size: length of this fragment
+ * @fragment:  fragment data
+ */
+struct wcnss_download_nv_req {
+   struct wcnss_msg_hdr hdr;
+   u16 seq;
+   u16 last;
+   u32 frag_size;
+   u8 fragment[];
+} __packed;
+
+/**
+ * struct wcnss_download_nv_resp - firmware download response
+ * @hdr:   common packet wcnss_msg_hdr header
+ * @status:boolean to indicate success of the download
+ */
+struct wcnss_download_nv_resp {
+   struct wcnss_msg_hdr hdr;
+   u8 status;
+} __packed;
+
+/**
+ * wcnss_ctrl_smd_callback() - handler from SMD responses
+ * @qsdev: smd device handle
+ * @data:  pointer to the incoming data packet
+ * @count: size of the incoming data packet
+ *
+ * Handles any 

Re: [PATCH v2 7/7] Bluetooth: btqcomsmd: Qualcomm WCNSS HCI driver

2015-10-14 Thread yfw



On 2015/10/10 4:48, Bjorn Andersson wrote:

The Qualcomm WCNSS chip provides two SMD channels to the BT core; one
for command and one for event packets. This driver exposes the two
channels as a hci device.

Signed-off-by: Bjorn Andersson 
---

Changes since v1:
- With the introduction of qcom_smd_open_channel() the two drivers are now one
- No more global state
- Corrected memory management of sk_buffs
- Reverted to __hci_cmd_sync_ev() for set_bdaddr
- Renamed the driver to btqcomsmd
- Split out the addition of HCI_SMD to separate patch

  drivers/bluetooth/Kconfig |  11 +++
  drivers/bluetooth/Makefile|   1 +
  drivers/bluetooth/btqcomsmd.c | 198 ++
  3 files changed, 210 insertions(+)
  create mode 100644 drivers/bluetooth/btqcomsmd.c

diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index 62999546a301..1652997e59cc 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -169,6 +169,17 @@ config BT_HCIUART_QCA

  Say Y here to compile support for QCA protocol.

+config BT_QCOMSMD
+   tristate "Qualcomm SMD based HCI support"
+   depends on QCOM_SMD
+   help
+ Qualcomm SMD based HCI driver.
+ This driver is used to bridge HCI data onto the shared memory
+ channels to the WCNSS core.
+
+ Say Y here to compile support for HCI over Qualcomm SMD into the
+ kernelor say M to compile as a module.
+
  config BT_HCIBCM203X
tristate "HCI BCM203x USB driver"
depends on USB
diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
index 07c9cf381e5a..19e313bf8c39 100644
--- a/drivers/bluetooth/Makefile
+++ b/drivers/bluetooth/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_BT_WILINK)   += btwilink.o
  obj-$(CONFIG_BT_BCM)  += btbcm.o
  obj-$(CONFIG_BT_RTL)  += btrtl.o
  obj-$(CONFIG_BT_QCA)  += btqca.o
+obj-$(CONFIG_BT_QCOMSMD)   += btqcomsmd.o

  btmrvl-y  := btmrvl_main.o
  btmrvl-$(CONFIG_DEBUG_FS) += btmrvl_debugfs.o
diff --git a/drivers/bluetooth/btqcomsmd.c b/drivers/bluetooth/btqcomsmd.c
new file mode 100644
index ..4b91c830531e
--- /dev/null
+++ b/drivers/bluetooth/btqcomsmd.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2015, Sony Mobile Communications Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define EDL_NVM_ACCESS_SET_REQ_CMD 0x01
+#define EDL_NVM_ACCESS_OPCODE  0xfc0b
+
+struct btqcomsmd {
+   struct qcom_smd_channel *acl_channel;
+   struct qcom_smd_channel *cmd_channel;
+};
+
+static int btqcomsmd_recv(struct hci_dev *hdev,
+ unsigned type,
+ const void *data,
+ size_t count)
+{
+   struct sk_buff *skb;
+   void *buf;
+
+   /* Use GFP_ATOMIC as we're in IRQ context */
+   skb = bt_skb_alloc(count, GFP_ATOMIC);
+   if (!skb)
+   return -ENOMEM;
+
+   bt_cb(skb)->pkt_type = type;
+
+   /* Use io accessor as data might be ioremapped */
+   buf = skb_put(skb, count);
+   memcpy_fromio(buf, data, count);
+
+   return hci_recv_frame(hdev, skb);
+}
+
+static int btqcomsmd_acl_callback(struct qcom_smd_device *qsdev,
+ const void *data,
+ size_t count)
+{
+   struct hci_dev *hdev = dev_get_drvdata(>dev);
+
+   return btqcomsmd_recv(hdev, HCI_ACLDATA_PKT, data, count);
+}
+
+static int btqcomsmd_cmd_callback(struct qcom_smd_device *qsdev,
+ const void *data,
+ size_t count)
+{
+   struct hci_dev *hdev = dev_get_drvdata(>dev);
+
+   return btqcomsmd_recv(hdev, HCI_EVENT_PKT, data, count);
+}
+
+static int btqcomsmd_send(struct hci_dev *hdev, struct sk_buff *skb)
+{
+   struct btqcomsmd *btq = hci_get_drvdata(hdev);
+   int ret;
+
+   switch (bt_cb(skb)->pkt_type) {
+   case HCI_ACLDATA_PKT:
+   case HCI_SCODATA_PKT:
+   ret = qcom_smd_send(btq->acl_channel, skb->data, skb->len);
+   break;
+   case HCI_COMMAND_PKT:
+   ret = qcom_smd_send(btq->cmd_channel, skb->data, skb->len);
+   break;
+   default:
+   ret = -ENODEV;
+   break;
+   }
+
+   return ret;
+}
+
+static int btqcomsmd_open(struct hci_dev *hdev)
+{
+   set_bit(HCI_RUNNING, >flags);
+   return 0;
+}
+
+static int 

Re: [PATCH v2 5/7] soc: qcom: smd: Support opening additional channels

2015-10-14 Thread yfw

Hi Bjorn,

On 2015/10/10 4:48, Bjorn Andersson wrote:

With the qcom_smd_open_channel() API we allow SMD devices to open
additional SMD channels, to allow implementation of multi-channel SMD
devices - like Bluetooth.

Channels are opened from the same edge as the calling SMD device is tied
to.

Signed-off-by: Bjorn Andersson 
---

Changes since v1:
- New patch

  drivers/soc/qcom/smd.c   | 75 
  include/linux/soc/qcom/smd.h |  4 +++
  2 files changed, 79 insertions(+)

diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c
index 4c55708aac50..3257ba488d3d 100644
--- a/drivers/soc/qcom/smd.c
+++ b/drivers/soc/qcom/smd.c
@@ -129,6 +129,8 @@ struct qcom_smd_edge {

unsigned smem_available;

+   wait_queue_head_t new_channel_event;
+
struct work_struct scan_work;
struct work_struct state_work;
  };
@@ -1042,6 +1044,76 @@ void qcom_smd_driver_unregister(struct qcom_smd_driver 
*qsdrv)
  }
  EXPORT_SYMBOL(qcom_smd_driver_unregister);

+static struct qcom_smd_channel *
+qcom_smd_find_channel(struct qcom_smd_edge *edge, const char *name)
+{
+   struct qcom_smd_channel *channel;
+   struct qcom_smd_channel *ret = NULL;
+   unsigned state;
+
+   read_lock(>channels_lock);
+   list_for_each_entry(channel, >channels, list) {
+   if (strcmp(channel->name, name))
+   continue;
+
+   state = GET_RX_CHANNEL_INFO(channel, state);
+   if (state != SMD_CHANNEL_OPENING &&
+   state != SMD_CHANNEL_OPENED)
+   continue;
+
+   ret = channel;
+   break;
+   }
+   read_unlock(>channels_lock);
+
+   return ret;
+}
+
+/**
+ * qcom_smd_open_channel() - claim additional channels on the same edge
+ * @sdev:  smd_device handle
+ * @name:  channel name
+ * @cb:callback method to use for incoming data
+ *
+ * Returns a channel handle on success, or -EPROBE_DEFER if the channel isn't
+ * ready.
+ */
+struct qcom_smd_channel *qcom_smd_open_channel(struct qcom_smd_device *sdev,
+  const char *name,
+  qcom_smd_cb_t cb)
+{
+   struct qcom_smd_channel *channel;
+   struct qcom_smd_edge *edge = sdev->channel->edge;
+   int ret;
+
+   /* Wait up to HZ for the channel to appear */
+   ret = wait_event_interruptible_timeout(edge->new_channel_event,
+   (channel = qcom_smd_find_channel(edge, name)) != NULL,
+   HZ);
+   if (!ret)
+   return ERR_PTR(-ETIMEDOUT);
+
+   if (channel->state != SMD_CHANNEL_CLOSED) {
+   dev_err(>dev, "channel %s is busy\n", channel->name);
+   return ERR_PTR(-EBUSY);
+   }
+
+   channel->qsdev = sdev;
+   ret = qcom_smd_channel_open(channel, cb);
+   if (ret) {
+   channel->qsdev = NULL;
+   return ERR_PTR(ret);
+   }
+
+   /*
+* Append the list of channel to the channels associated with the sdev
+*/
+   list_add_tail(>dev_list, >channel->dev_list);
+
+   return channel;
+}
+EXPORT_SYMBOL(qcom_smd_open_channel);
+

Do we need qcom_smd_close_channel API here?

Regards
Yin, Fengwei


  /*
   * Allocate the qcom_smd_channel object for a newly found smd channel,
   * retrieving and validating the smem items involved.
@@ -1178,6 +1250,8 @@ static void qcom_channel_scan_worker(struct work_struct 
*work)

dev_dbg(smd->dev, "new channel found: '%s'\n", 
channel->name);
set_bit(i, edge->allocated[tbl]);
+
+   wake_up_interruptible(>new_channel_event);
}
}

@@ -1340,6 +1414,7 @@ static int qcom_smd_probe(struct platform_device *pdev)
for_each_available_child_of_node(pdev->dev.of_node, node) {
edge = >edges[i++];
edge->smd = smd;
+   init_waitqueue_head(>new_channel_event);

ret = qcom_smd_parse_edge(>dev, node, edge);
if (ret)
diff --git a/include/linux/soc/qcom/smd.h b/include/linux/soc/qcom/smd.h
index 65a64fcdb1aa..bd51c8a9d807 100644
--- a/include/linux/soc/qcom/smd.h
+++ b/include/linux/soc/qcom/smd.h
@@ -56,4 +56,8 @@ void qcom_smd_driver_unregister(struct qcom_smd_driver *drv);

  int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int 
len);

+struct qcom_smd_channel *qcom_smd_open_channel(struct qcom_smd_device *sdev,
+  const char *name,
+  qcom_smd_cb_t cb);
+
  #endif


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 7/7] Bluetooth: btqcomsmd: Qualcomm WCNSS HCI driver

2015-10-14 Thread yfw



On 2015/10/10 4:48, Bjorn Andersson wrote:

The Qualcomm WCNSS chip provides two SMD channels to the BT core; one
for command and one for event packets. This driver exposes the two
channels as a hci device.

Signed-off-by: Bjorn Andersson 
---

Changes since v1:
- With the introduction of qcom_smd_open_channel() the two drivers are now one
- No more global state
- Corrected memory management of sk_buffs
- Reverted to __hci_cmd_sync_ev() for set_bdaddr
- Renamed the driver to btqcomsmd
- Split out the addition of HCI_SMD to separate patch

  drivers/bluetooth/Kconfig |  11 +++
  drivers/bluetooth/Makefile|   1 +
  drivers/bluetooth/btqcomsmd.c | 198 ++
  3 files changed, 210 insertions(+)
  create mode 100644 drivers/bluetooth/btqcomsmd.c

diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index 62999546a301..1652997e59cc 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -169,6 +169,17 @@ config BT_HCIUART_QCA

  Say Y here to compile support for QCA protocol.

+config BT_QCOMSMD
+   tristate "Qualcomm SMD based HCI support"
+   depends on QCOM_SMD
+   help
+ Qualcomm SMD based HCI driver.
+ This driver is used to bridge HCI data onto the shared memory
+ channels to the WCNSS core.
+
+ Say Y here to compile support for HCI over Qualcomm SMD into the
+ kernelor say M to compile as a module.
+
  config BT_HCIBCM203X
tristate "HCI BCM203x USB driver"
depends on USB
diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
index 07c9cf381e5a..19e313bf8c39 100644
--- a/drivers/bluetooth/Makefile
+++ b/drivers/bluetooth/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_BT_WILINK)   += btwilink.o
  obj-$(CONFIG_BT_BCM)  += btbcm.o
  obj-$(CONFIG_BT_RTL)  += btrtl.o
  obj-$(CONFIG_BT_QCA)  += btqca.o
+obj-$(CONFIG_BT_QCOMSMD)   += btqcomsmd.o

  btmrvl-y  := btmrvl_main.o
  btmrvl-$(CONFIG_DEBUG_FS) += btmrvl_debugfs.o
diff --git a/drivers/bluetooth/btqcomsmd.c b/drivers/bluetooth/btqcomsmd.c
new file mode 100644
index ..4b91c830531e
--- /dev/null
+++ b/drivers/bluetooth/btqcomsmd.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2015, Sony Mobile Communications Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define EDL_NVM_ACCESS_SET_REQ_CMD 0x01
+#define EDL_NVM_ACCESS_OPCODE  0xfc0b
+
+struct btqcomsmd {
+   struct qcom_smd_channel *acl_channel;
+   struct qcom_smd_channel *cmd_channel;
+};
+
+static int btqcomsmd_recv(struct hci_dev *hdev,
+ unsigned type,
+ const void *data,
+ size_t count)
+{
+   struct sk_buff *skb;
+   void *buf;
+
+   /* Use GFP_ATOMIC as we're in IRQ context */
+   skb = bt_skb_alloc(count, GFP_ATOMIC);
+   if (!skb)
+   return -ENOMEM;
+
+   bt_cb(skb)->pkt_type = type;
+
+   /* Use io accessor as data might be ioremapped */
+   buf = skb_put(skb, count);
+   memcpy_fromio(buf, data, count);
+
+   return hci_recv_frame(hdev, skb);
+}
+
+static int btqcomsmd_acl_callback(struct qcom_smd_device *qsdev,
+ const void *data,
+ size_t count)
+{
+   struct hci_dev *hdev = dev_get_drvdata(>dev);
+
+   return btqcomsmd_recv(hdev, HCI_ACLDATA_PKT, data, count);
+}
+
+static int btqcomsmd_cmd_callback(struct qcom_smd_device *qsdev,
+ const void *data,
+ size_t count)
+{
+   struct hci_dev *hdev = dev_get_drvdata(>dev);
+
+   return btqcomsmd_recv(hdev, HCI_EVENT_PKT, data, count);
+}
+
+static int btqcomsmd_send(struct hci_dev *hdev, struct sk_buff *skb)
+{
+   struct btqcomsmd *btq = hci_get_drvdata(hdev);
+   int ret;
+
+   switch (bt_cb(skb)->pkt_type) {
+   case HCI_ACLDATA_PKT:
+   case HCI_SCODATA_PKT:
+   ret = qcom_smd_send(btq->acl_channel, skb->data, skb->len);
+   break;
+   case HCI_COMMAND_PKT:
+   ret = qcom_smd_send(btq->cmd_channel, skb->data, skb->len);
+   break;
+   default:
+   ret = -ENODEV;
+   break;
+   }
+
+   return ret;
+}
+
+static int btqcomsmd_open(struct hci_dev *hdev)
+{
+   set_bit(HCI_RUNNING, >flags);
+   return 

Re: [PATCH v2 5/7] soc: qcom: smd: Support opening additional channels

2015-10-14 Thread yfw

Hi Bjorn,

On 2015/10/10 4:48, Bjorn Andersson wrote:

With the qcom_smd_open_channel() API we allow SMD devices to open
additional SMD channels, to allow implementation of multi-channel SMD
devices - like Bluetooth.

Channels are opened from the same edge as the calling SMD device is tied
to.

Signed-off-by: Bjorn Andersson 
---

Changes since v1:
- New patch

  drivers/soc/qcom/smd.c   | 75 
  include/linux/soc/qcom/smd.h |  4 +++
  2 files changed, 79 insertions(+)

diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c
index 4c55708aac50..3257ba488d3d 100644
--- a/drivers/soc/qcom/smd.c
+++ b/drivers/soc/qcom/smd.c
@@ -129,6 +129,8 @@ struct qcom_smd_edge {

unsigned smem_available;

+   wait_queue_head_t new_channel_event;
+
struct work_struct scan_work;
struct work_struct state_work;
  };
@@ -1042,6 +1044,76 @@ void qcom_smd_driver_unregister(struct qcom_smd_driver 
*qsdrv)
  }
  EXPORT_SYMBOL(qcom_smd_driver_unregister);

+static struct qcom_smd_channel *
+qcom_smd_find_channel(struct qcom_smd_edge *edge, const char *name)
+{
+   struct qcom_smd_channel *channel;
+   struct qcom_smd_channel *ret = NULL;
+   unsigned state;
+
+   read_lock(>channels_lock);
+   list_for_each_entry(channel, >channels, list) {
+   if (strcmp(channel->name, name))
+   continue;
+
+   state = GET_RX_CHANNEL_INFO(channel, state);
+   if (state != SMD_CHANNEL_OPENING &&
+   state != SMD_CHANNEL_OPENED)
+   continue;
+
+   ret = channel;
+   break;
+   }
+   read_unlock(>channels_lock);
+
+   return ret;
+}
+
+/**
+ * qcom_smd_open_channel() - claim additional channels on the same edge
+ * @sdev:  smd_device handle
+ * @name:  channel name
+ * @cb:callback method to use for incoming data
+ *
+ * Returns a channel handle on success, or -EPROBE_DEFER if the channel isn't
+ * ready.
+ */
+struct qcom_smd_channel *qcom_smd_open_channel(struct qcom_smd_device *sdev,
+  const char *name,
+  qcom_smd_cb_t cb)
+{
+   struct qcom_smd_channel *channel;
+   struct qcom_smd_edge *edge = sdev->channel->edge;
+   int ret;
+
+   /* Wait up to HZ for the channel to appear */
+   ret = wait_event_interruptible_timeout(edge->new_channel_event,
+   (channel = qcom_smd_find_channel(edge, name)) != NULL,
+   HZ);
+   if (!ret)
+   return ERR_PTR(-ETIMEDOUT);
+
+   if (channel->state != SMD_CHANNEL_CLOSED) {
+   dev_err(>dev, "channel %s is busy\n", channel->name);
+   return ERR_PTR(-EBUSY);
+   }
+
+   channel->qsdev = sdev;
+   ret = qcom_smd_channel_open(channel, cb);
+   if (ret) {
+   channel->qsdev = NULL;
+   return ERR_PTR(ret);
+   }
+
+   /*
+* Append the list of channel to the channels associated with the sdev
+*/
+   list_add_tail(>dev_list, >channel->dev_list);
+
+   return channel;
+}
+EXPORT_SYMBOL(qcom_smd_open_channel);
+

Do we need qcom_smd_close_channel API here?

Regards
Yin, Fengwei


  /*
   * Allocate the qcom_smd_channel object for a newly found smd channel,
   * retrieving and validating the smem items involved.
@@ -1178,6 +1250,8 @@ static void qcom_channel_scan_worker(struct work_struct 
*work)

dev_dbg(smd->dev, "new channel found: '%s'\n", 
channel->name);
set_bit(i, edge->allocated[tbl]);
+
+   wake_up_interruptible(>new_channel_event);
}
}

@@ -1340,6 +1414,7 @@ static int qcom_smd_probe(struct platform_device *pdev)
for_each_available_child_of_node(pdev->dev.of_node, node) {
edge = >edges[i++];
edge->smd = smd;
+   init_waitqueue_head(>new_channel_event);

ret = qcom_smd_parse_edge(>dev, node, edge);
if (ret)
diff --git a/include/linux/soc/qcom/smd.h b/include/linux/soc/qcom/smd.h
index 65a64fcdb1aa..bd51c8a9d807 100644
--- a/include/linux/soc/qcom/smd.h
+++ b/include/linux/soc/qcom/smd.h
@@ -56,4 +56,8 @@ void qcom_smd_driver_unregister(struct qcom_smd_driver *drv);

  int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int 
len);

+struct qcom_smd_channel *qcom_smd_open_channel(struct qcom_smd_device *sdev,
+  const char *name,
+  qcom_smd_cb_t cb);
+
  #endif


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  

Re: [PATCH] soc: qcom: Introduce WCNSS_CTRL SMD client

2015-09-22 Thread yfw
On Mon, Sep 21, 2015 at 10:52:55AM -0700, Bjorn Andersson wrote:
> The WCNSS_CTRL SMD client is used for among other things upload nv
> firmware to a newly booted WCNSS chip.
> 
> Signed-off-by: Bjorn Andersson 
> ---
> This driver probes on the WCNSS_CTRL SMD channel as it comes up upon loading
> the wcnss firmware, it currenly request version information from the wcnss and
> downloads the nv binary.
> 
> This is needed for bringing up the individual functions of the wcnss chip.
> 
>  drivers/soc/qcom/Kconfig  |   7 ++
>  drivers/soc/qcom/Makefile |   1 +
>  drivers/soc/qcom/wcnss_ctrl.c | 272 
> ++
>  3 files changed, 280 insertions(+)
>  create mode 100644 drivers/soc/qcom/wcnss_ctrl.c
> 
> diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
> index ba47b70f4d85..453ceb1af682 100644
> --- a/drivers/soc/qcom/Kconfig
> +++ b/drivers/soc/qcom/Kconfig
> @@ -48,3 +48,10 @@ config QCOM_SMEM
> Say y here to enable support for the Qualcomm Shared Memory Manager.
> The driver provides an interface to items in a heap shared among all
> processors in a Qualcomm platform.
> +
> +config QCOM_WCNSS_CTRL
> + tristate "Qualcomm WCNSS control driver"
> + depends on QCOM_SMD
> + help
> +   Client driver for the WCNSS_CTRL SMD channel, used to download nv
> +   firmware to a newly booted WCNSS chip.
> diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
> index 10a93d168e0e..9823103ea843 100644
> --- a/drivers/soc/qcom/Makefile
> +++ b/drivers/soc/qcom/Makefile
> @@ -3,3 +3,4 @@ obj-$(CONFIG_QCOM_PM) +=  spm.o
>  obj-$(CONFIG_QCOM_SMD) +=smd.o
>  obj-$(CONFIG_QCOM_SMD_RPM)   += smd-rpm.o
>  obj-$(CONFIG_QCOM_SMEM) +=   smem.o
> +obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
> diff --git a/drivers/soc/qcom/wcnss_ctrl.c b/drivers/soc/qcom/wcnss_ctrl.c
> new file mode 100644
> index ..7a986f881d5c
> --- /dev/null
> +++ b/drivers/soc/qcom/wcnss_ctrl.c
> @@ -0,0 +1,272 @@
> +/*
> + * Copyright (c) 2015, Sony Mobile Communications Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define WCNSS_REQUEST_TIMEOUT(5 * HZ)
> +
> +#define NV_FRAGMENT_SIZE 3072
> +#define NVBIN_FILE   "wlan/prima/WCNSS_qcom_wlan_nv.bin"
> +
> +/**
> + * struct wcnss_ctrl - driver context
> + * @dev: device handle
> + * @channel: SMD channel handle
> + * @ack: completion for outstanding requests
> + * @ack_status:  status of the outstanding request
> + * @download_nv_work: worker for uploading nv binary
> + */
> +struct wcnss_ctrl {
> + struct device *dev;
> + struct qcom_smd_channel *channel;
> +
> + struct completion ack;
> + int ack_status;
> +
> + struct work_struct download_nv_work;
> +};
> +
> +/* message types */
> +enum {
> + WCNSS_VERSION_REQ = 0x0100,
> + WCNSS_VERSION_RESP,
> + WCNSS_DOWNLOAD_NV_REQ,
> + WCNSS_DOWNLOAD_NV_RESP,
> + WCNSS_UPLOAD_CAL_REQ,
> + WCNSS_UPLOAD_CAL_RESP,
> + WCNSS_DOWNLOAD_CAL_REQ,
> + WCNSS_DOWNLOAD_CAL_RESP,
> +};
> +
> +/**
> + * struct wcnss_msg_hdr - common packet header for requests and responses
> + * @type:packet message type
> + * @len: total length of the packet, including this header
> + */
> +struct wcnss_msg_hdr {
> + u32 type;
> + u32 len;
> +} __packed;
> +
> +/**
> + * struct wcnss_version_resp - version request response
> + * @hdr: common packet wcnss_msg_hdr header
> + */
> +struct wcnss_version_resp {
> + struct wcnss_msg_hdr hdr;
> + u8 major;
> + u8 minor;
> + u8 version;
> + u8 revision;
> +} __packed;
> +
> +/**
> + * struct wcnss_download_nv_req - firmware fragment request
> + * @hdr: common packet wcnss_msg_hdr header
> + * @seq: sequence number of this fragment
> + * @last:boolean indicator of this being the last fragment of the binary
> + * @frag_size:   length of this fragment
> + * @fragment:fragment data
> + */
> +struct wcnss_download_nv_req {
> + struct wcnss_msg_hdr hdr;
> + u16 seq;
> + u16 last;
> + u32 frag_size;
> + u8 fragment[];
> +} __packed;
> +
> +/**
> + * struct wcnss_download_nv_resp - firmware download response
> + * @hdr: common packet wcnss_msg_hdr header
> + * @status:  boolean to indicate success of the download
> + */
> +struct wcnss_download_nv_resp {
> + struct wcnss_msg_hdr hdr;
> + u8 status;
> +} __packed;
> +
> +/**
> + * wcnss_ctrl_smd_callback() 

Re: [PATCH] soc: qcom: Introduce WCNSS_CTRL SMD client

2015-09-22 Thread yfw
On Mon, Sep 21, 2015 at 10:52:55AM -0700, Bjorn Andersson wrote:
> The WCNSS_CTRL SMD client is used for among other things upload nv
> firmware to a newly booted WCNSS chip.
> 
> Signed-off-by: Bjorn Andersson 
> ---
> This driver probes on the WCNSS_CTRL SMD channel as it comes up upon loading
> the wcnss firmware, it currenly request version information from the wcnss and
> downloads the nv binary.
> 
> This is needed for bringing up the individual functions of the wcnss chip.
> 
>  drivers/soc/qcom/Kconfig  |   7 ++
>  drivers/soc/qcom/Makefile |   1 +
>  drivers/soc/qcom/wcnss_ctrl.c | 272 
> ++
>  3 files changed, 280 insertions(+)
>  create mode 100644 drivers/soc/qcom/wcnss_ctrl.c
> 
> diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
> index ba47b70f4d85..453ceb1af682 100644
> --- a/drivers/soc/qcom/Kconfig
> +++ b/drivers/soc/qcom/Kconfig
> @@ -48,3 +48,10 @@ config QCOM_SMEM
> Say y here to enable support for the Qualcomm Shared Memory Manager.
> The driver provides an interface to items in a heap shared among all
> processors in a Qualcomm platform.
> +
> +config QCOM_WCNSS_CTRL
> + tristate "Qualcomm WCNSS control driver"
> + depends on QCOM_SMD
> + help
> +   Client driver for the WCNSS_CTRL SMD channel, used to download nv
> +   firmware to a newly booted WCNSS chip.
> diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
> index 10a93d168e0e..9823103ea843 100644
> --- a/drivers/soc/qcom/Makefile
> +++ b/drivers/soc/qcom/Makefile
> @@ -3,3 +3,4 @@ obj-$(CONFIG_QCOM_PM) +=  spm.o
>  obj-$(CONFIG_QCOM_SMD) +=smd.o
>  obj-$(CONFIG_QCOM_SMD_RPM)   += smd-rpm.o
>  obj-$(CONFIG_QCOM_SMEM) +=   smem.o
> +obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
> diff --git a/drivers/soc/qcom/wcnss_ctrl.c b/drivers/soc/qcom/wcnss_ctrl.c
> new file mode 100644
> index ..7a986f881d5c
> --- /dev/null
> +++ b/drivers/soc/qcom/wcnss_ctrl.c
> @@ -0,0 +1,272 @@
> +/*
> + * Copyright (c) 2015, Sony Mobile Communications Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define WCNSS_REQUEST_TIMEOUT(5 * HZ)
> +
> +#define NV_FRAGMENT_SIZE 3072
> +#define NVBIN_FILE   "wlan/prima/WCNSS_qcom_wlan_nv.bin"
> +
> +/**
> + * struct wcnss_ctrl - driver context
> + * @dev: device handle
> + * @channel: SMD channel handle
> + * @ack: completion for outstanding requests
> + * @ack_status:  status of the outstanding request
> + * @download_nv_work: worker for uploading nv binary
> + */
> +struct wcnss_ctrl {
> + struct device *dev;
> + struct qcom_smd_channel *channel;
> +
> + struct completion ack;
> + int ack_status;
> +
> + struct work_struct download_nv_work;
> +};
> +
> +/* message types */
> +enum {
> + WCNSS_VERSION_REQ = 0x0100,
> + WCNSS_VERSION_RESP,
> + WCNSS_DOWNLOAD_NV_REQ,
> + WCNSS_DOWNLOAD_NV_RESP,
> + WCNSS_UPLOAD_CAL_REQ,
> + WCNSS_UPLOAD_CAL_RESP,
> + WCNSS_DOWNLOAD_CAL_REQ,
> + WCNSS_DOWNLOAD_CAL_RESP,
> +};
> +
> +/**
> + * struct wcnss_msg_hdr - common packet header for requests and responses
> + * @type:packet message type
> + * @len: total length of the packet, including this header
> + */
> +struct wcnss_msg_hdr {
> + u32 type;
> + u32 len;
> +} __packed;
> +
> +/**
> + * struct wcnss_version_resp - version request response
> + * @hdr: common packet wcnss_msg_hdr header
> + */
> +struct wcnss_version_resp {
> + struct wcnss_msg_hdr hdr;
> + u8 major;
> + u8 minor;
> + u8 version;
> + u8 revision;
> +} __packed;
> +
> +/**
> + * struct wcnss_download_nv_req - firmware fragment request
> + * @hdr: common packet wcnss_msg_hdr header
> + * @seq: sequence number of this fragment
> + * @last:boolean indicator of this being the last fragment of the binary
> + * @frag_size:   length of this fragment
> + * @fragment:fragment data
> + */
> +struct wcnss_download_nv_req {
> + struct wcnss_msg_hdr hdr;
> + u16 seq;
> + u16 last;
> + u32 frag_size;
> + u8 fragment[];
> +} __packed;
> +
> +/**
> + * struct wcnss_download_nv_resp - firmware download response
> + * @hdr: common packet wcnss_msg_hdr header
> + * @status:  boolean to indicate success of the download
> + */
> +struct wcnss_download_nv_resp {
> + struct wcnss_msg_hdr hdr;
> + u8 status;
> +} __packed;
> +
> +/**