[PATCH v2 2/4] dts: arm64/sdm845: Add WCN3990 WLAN module device node

2018-10-01 Thread Govind Singh
Add device node for the ath10k SNOC platform driver probe
and add resources required for WCN3990 on SDM845 soc.

Signed-off-by: Govind Singh 
---
 arch/arm64/boot/dts/qcom/sdm845-mtp.dts |  7 +++
 arch/arm64/boot/dts/qcom/sdm845.dtsi| 26 +
 2 files changed, 33 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts 
b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
index eedfaf8922e2..4de57f7df93c 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
@@ -440,3 +440,10 @@
bias-pull-up;
};
 };
+
+ {
+   vdd-0.8-cx-mx-supply = <_l5a_0p8>;
+   vdd-1.8-xo-supply = <_l7a_1p8>;
+   vdd-1.3-rfa-supply = <_l17a_1p3>;
+   vdd-3.3-ch0-supply = <_l25a_3p3>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi 
b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index e080072cdfdb..36c716cf3a0c 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -86,6 +86,11 @@
reg = <0 0x8620 0 0x2d0>;
no-map;
};
+
+   wlan_msa_mem: reserved-memory@9670 {
+   no-map;
+   reg = <0 0x9670 0 0x10>;
+   };
};
 
cpus {
@@ -1200,5 +1205,26 @@
status = "disabled";
};
};
+
+   wifi: wifi@1880 {
+   compatible = "qcom,wcn3990-wifi";
+   status = "disabled";
+   reg = <0x1880 0x80>;
+   reg-names = "membase";
+   memory-region = <_msa_mem>;
+   interrupts =
+   <0 413 0 /* CE0 */ >,
+   <0 414 0 /* CE1 */ >,
+   <0 415 0 /* CE2 */ >,
+   <0 416 0 /* CE3 */ >,
+   <0 417 0 /* CE4 */ >,
+   <0 418 0 /* CE5 */ >,
+   <0 420 0 /* CE6 */ >,
+   <0 421 0 /* CE7 */ >,
+   <0 422 0 /* CE8 */ >,
+   <0 423 0 /* CE9 */ >,
+   <0 424 0 /* CE10 */ >,
+   <0 425 0 /* CE11 */ >;
+   };
};
 };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2 1/4] dt: bindings: add missing dt properties for WCN3990 wifi node

2018-10-01 Thread Govind Singh
Add missing optional properties in WCN3990 wifi node.

Signed-off-by: Govind Singh 
---
 .../bindings/net/wireless/qcom,ath10k.txt | 28 ++-
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt 
b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
index 7fd4e8ce4149..f831bb1c5952 100644
--- a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
+++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
@@ -37,12 +37,20 @@ Optional properties:
 - clocks: List of clock specifiers, must contain an entry for each required
   entry in clock-names.
 - clock-names: Should contain the clock names "wifi_wcss_cmd", "wifi_wcss_ref",
-   "wifi_wcss_rtc".
-- interrupts: List of interrupt lines. Must contain an entry
- for each entry in the interrupt-names property.
+  "wifi_wcss_rtc" for "qcom,ipq4019-wifi" compatible target and
+  "cxo_ref_clk_pin", "smmu_aggre2_noc_clk" for "qcom,wcn3990-wifi"
+  compatible target.
+- interrupts: reference to the list of 17 interrupt no's for 
"qcom,ipq4019-wifi"
+ compatible target.
+ reference to the list of 12 interrupt no's for "qcom,wcn3990-wifi"
+ compatible target.
+ Must contain interrupt-names property per entry for
+ "qcom,ath10k", "qcom,ipq4019-wifi" compatible targets.
+
 - interrupt-names: Must include the entries for MSI interrupt
   names ("msi0" to "msi15") and legacy interrupt
-  name ("legacy"),
+  name ("legacy") for "qcom,ath10k", "qcom,ipq4019-wifi"
+  compatible targets.
 - qcom,msi_addr: MSI interrupt address.
 - qcom,msi_base: Base value to add before writing MSI data into
MSI address register.
@@ -55,7 +63,8 @@ Optional properties:
 - qcom,ath10k-pre-calibration-data : pre calibration data as an array,
 the length can vary between hw versions.
 - -supply: handle to the regulator device tree node
-  optional "supply-name" is "vdd-0.8-cx-mx".
+  optional "supply-name" are "vdd-0.8-cx-mx",
+  "vdd-1.8-xo", "vdd-1.3-rfa" and "vdd-3.3-ch0".
 
 Example (to supply the calibration data alone):
 
@@ -133,8 +142,10 @@ wifi@1800 {
compatible = "qcom,wcn3990-wifi";
reg = <0x1880 0x80>;
reg-names = "membase";
-   clocks = <_gcc clk_aggre2_noc_clk>;
-   clock-names = "smmu_aggre2_noc_clk"
+   clocks = <_gcc clk_aggre2_noc_clk>,
+<_gcc clk_rf_clk2_pin>;
+   clock-names = "smmu_aggre2_noc_clk",
+ "cxo_ref_clk_pin";
interrupts =
   <0 130 0 /* CE0 */ >,
   <0 131 0 /* CE1 */ >,
@@ -149,4 +160,7 @@ wifi@1800 {
   <0 140 0 /* CE10 */ >,
   <0 141 0 /* CE11 */ >;
vdd-0.8-cx-mx-supply = <_l5>;
+   vdd-1.8-xo-supply = <_l7a_1p8>;
+   vdd-1.3-rfa-supply = <_l17a_1p3>;
+   vdd-3.3-ch0-supply = <_l25a_3p3>;
 };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH 07/12] ath10k: Add MSA handshake QMI mgs support

2018-05-14 Thread Govind Singh

Hi Bjorn,
Thanks for the review.


On 2018-05-12 00:13, Bjorn Andersson wrote:

On Sun 25 Mar 22:40 PDT 2018, Govind Singh wrote:


HOST allocates 2mb of region for modem and WCN3990
secure access and provides the address and access
control to target for secure access.
Add MSA handshake request/response messages.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/qmi.c | 288 
+-

 drivers/net/wireless/ath/ath10k/qmi.h |  14 ++
 2 files changed, 300 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/qmi.c 
b/drivers/net/wireless/ath/ath10k/qmi.c

index bc80b8f..763b812 100644
--- a/drivers/net/wireless/ath/ath10k/qmi.c
+++ b/drivers/net/wireless/ath/ath10k/qmi.c
@@ -26,6 +26,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include "qmi.h"
 #include "qmi_svc_v01.h"

@@ -35,6 +37,240 @@
 static struct ath10k_qmi *qmi;

 static int
+ath10k_qmi_map_msa_permissions(struct ath10k_msa_mem_region_info 
*mem_region)

+{
+   struct qcom_scm_vmperm dst_perms[3];
+   unsigned int src_perms;
+   phys_addr_t addr;
+   u32 perm_count;
+   u32 size;
+   int ret;
+
+   addr = mem_region->reg_addr;
+   size = mem_region->size;


Skip the local variables.



Sure, will do in next version.


+
+   src_perms = BIT(QCOM_SCM_VMID_HLOS);
+
+   dst_perms[0].vmid = QCOM_SCM_VMID_MSS_MSA;
+   dst_perms[0].perm = QCOM_SCM_PERM_RW;
+   dst_perms[1].vmid = QCOM_SCM_VMID_WLAN;
+   dst_perms[1].perm = QCOM_SCM_PERM_RW;
+
+   if (!mem_region->secure_flag) {


So with secure_flag equal to 0 we give less subsystems access to the
data? Is this logic inverted?



Yes with secure flag mean less privileges i,e: Copy engine hardware
can not access the region.


+   dst_perms[2].vmid = QCOM_SCM_VMID_WLAN_CE;
+   dst_perms[2].perm = QCOM_SCM_PERM_RW;
+   perm_count = 3;
+   } else {
+   dst_perms[2].vmid = 0;
+   dst_perms[2].perm = 0;
+   perm_count = 2;


If you set perm_count to 2 you don't need to clear vmid and perm of
dst_perms[2].



ok, will remove.


+   }
+
+   ret = qcom_scm_assign_mem(addr, size, _perms,
+ dst_perms, perm_count);
+   if (ret < 0)
+   pr_err("msa map permission failed=%d\n", ret);


Use dev_err()


+
+   return ret;
+}
+
+static int
+ath10k_qmi_unmap_msa_permissions(struct ath10k_msa_mem_region_info 
*mem_region)

+{
+   struct qcom_scm_vmperm dst_perms;
+   unsigned int src_perms;
+   phys_addr_t addr;
+   u32 size;
+   int ret;
+
+   addr = mem_region->reg_addr;
+   size = mem_region->size;


Skip the local variables.



Sure, will do in next version.


+
+   src_perms = BIT(QCOM_SCM_VMID_MSS_MSA) | BIT(QCOM_SCM_VMID_WLAN);
+
+   if (!mem_region->secure_flag)
+   src_perms |= BIT(QCOM_SCM_VMID_WLAN_CE);
+
+   dst_perms.vmid = QCOM_SCM_VMID_HLOS;
+   dst_perms.perm = QCOM_SCM_PERM_RW;
+
+   ret = qcom_scm_assign_mem(addr, size, _perms, _perms, 1);
+   if (ret < 0)
+   pr_err("msa unmap permission failed=%d\n", ret);
+
+   return ret;
+}
+



+static int
+   ath10k_qmi_msa_mem_info_send_sync_msg(struct ath10k_qmi *qmi)
+{
+   struct wlfw_msa_info_resp_msg_v01 *resp;


This is 40 bytes,


Sure, will do in next version for all instances.


+   struct wlfw_msa_info_req_msg_v01 *req;


This is 6 bytes.

So just put them on the stack and skip the memory management.



Sure, will do in next version.


+   struct qmi_txn txn;
+   int ret;
+   int i;
+
+   req = kzalloc(sizeof(*req), GFP_KERNEL);
+   if (!req)
+   return -ENOMEM;
+
+   resp = kzalloc(sizeof(*resp), GFP_KERNEL);
+   if (!resp) {
+   kfree(req);
+   return -ENOMEM;
+   }
+
+   req->msa_addr = qmi->msa_pa;
+   req->size = qmi->msa_mem_size;
+
+   ret = qmi_txn_init(>qmi_hdl, ,
+  wlfw_msa_info_resp_msg_v01_ei, resp);
+   if (ret < 0) {
+   pr_err("fail to init txn for MSA mem info resp %d\n",
+  ret);


Unless we have 2 billion outstanding transactions "ret" is going to be
ENOMEM here, in which case there is already a printout telling you 
about

the problem.



Sure, will remove this redundant logging.


+   goto out;
+   }
+
+   ret = qmi_send_request(>qmi_hdl, NULL, ,
+  QMI_WLFW_MSA_INFO_REQ_V01,
+  WLFW_MSA_INFO_REQ_MSG_V01_MAX_MSG_LEN,
+  wlfw_msa_info_req_msg_v01_ei, req);
+   if (ret < 0) {
+   qmi_txn_cancel();
+   pr_err("fail to send MSA mem info req %d\n", ret);


Use dev

Re: [PATCH 04/12] ath10k: add support to start and stop qmi service

2018-05-14 Thread Govind Singh

On 2018-05-11 23:13, Bjorn Andersson wrote:

On Sun 25 Mar 22:39 PDT 2018, Govind Singh wrote:


Add support to start qmi service to configure the wlan
firmware component and register event notifier to communicate
with the WLAN firmware over qmi communication interface.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/qmi.c | 155 
--

 drivers/net/wireless/ath/ath10k/qmi.h |  13 +++
 2 files changed, 160 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/qmi.c 
b/drivers/net/wireless/ath/ath10k/qmi.c

index 2235182..3a7fcc6 100644
--- a/drivers/net/wireless/ath/ath10k/qmi.c
+++ b/drivers/net/wireless/ath/ath10k/qmi.c
@@ -31,15 +31,115 @@

 static struct ath10k_qmi *qmi;

+static int ath10k_qmi_event_fw_ready_ind(struct ath10k_qmi *qmi)
+{
+   pr_debug("fw ready event received\n");


Please use dev_dbg.



I have migrated from pr_ to dev_ logging for the whole set, will share 
in next version.



+   spin_lock(>event_lock);
+   qmi->fw_ready = true;
+   spin_unlock(>event_lock);


I see no reason for not just putting this code in
ath10k_qmi_fw_ready_ind().


+


fw_ready isn't used for anything, what purpose does this code have?



fw_ready will be used in later set of changes for qmi client debugfs and
for synchronization.I will decouple this and add as bit mask in 
appropriate change.




+   return 0;
+}
+
+static void ath10k_qmi_fw_ready_ind(struct qmi_handle *qmi_hdl,
+   struct sockaddr_qrtr *sq,
+   struct qmi_txn *txn, const void *data)
+{
+	struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, 
qmi_hdl);

+
+   ath10k_qmi_event_fw_ready_ind(qmi);
+}
+
+static void ath10k_qmi_msa_ready_ind(struct qmi_handle *qmi_hdl,
+struct sockaddr_qrtr *sq,
+struct qmi_txn *txn, const void *data)
+{
+	struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, 
qmi_hdl);

+
+   qmi->msa_ready = true;


msa_ready is not only unused in this patch, it's unused after all 11
patches. Can you drop it?



Sure, will remove in next version.



+static void ath10k_qmi_event_server_arrive(struct work_struct *work)
+{
+   struct ath10k_qmi *qmi = container_of(work, struct ath10k_qmi,
+ work_svc_arrive);
+   int ret;
+
+   ret = ath10k_qmi_connect_to_fw_server(qmi);
+   if (ret)
+   return;
+
+   pr_debug("qmi server arrive\n");
+}
+



 static int ath10k_qmi_new_server(struct qmi_handle *qmi_hdl,
 struct qmi_service *service)
 {
+	struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, 
qmi_hdl);

+   struct sockaddr_qrtr *sq = >sq;
+
+   sq->sq_family = AF_QIPCRTR;
+   sq->sq_node = service->node;
+   sq->sq_port = service->port;
+
+   queue_work(qmi->event_wq, >work_svc_arrive);


This is being called in a sleepable context and kernel_connect() will
not block, so I see no reason for queue work here to invoke
ath10k_qmi_event_server_arrive() just to call
ath10k_qmi_connect_to_fw_server().

Just put the kernel_connect() call here.




In this change it just calls ath10k_qmi_connect_to_fw_server, but most 
of the handshaking is done in server arrive callback.

Successive changes adds the request/response of each handshake.
Is it ok to block new_server callback till all client handshaking gets 
completed. I thought it might block other client
notification overlapped on the same time slot(ex: IPA). Do you see any 
concern here or should be ok.

I have not profiled yet, i will share the approx time it can take.

This gives the added benefit that you don't need to use qmi->sq as a 
way

to pass parameters to ath10k_qmi_connect_to_fw_server().


+
return 0;
 }

 static void ath10k_qmi_del_server(struct qmi_handle *qmi_hdl,
  struct qmi_service *service)
 {
+   struct ath10k_qmi *qmi =
+   container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl);
+
+   queue_work(qmi->event_wq, >work_svc_exit);


I see no reason to queue work to set a boolean to false, just inline 
the

code here.



sure, this i can remove.



 static struct qmi_ops ath10k_qmi_ops = {
@@ -47,6 +147,51 @@ static void ath10k_qmi_del_server(struct 
qmi_handle *qmi_hdl,

.del_server = ath10k_qmi_del_server,
 };

+static int ath10k_alloc_qmi_resources(struct ath10k_qmi *qmi)
+{
+   int ret;
+
+   ret = qmi_handle_init(>qmi_hdl,
+ WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN,
+ _qmi_ops, qmi_msg_handler);
+   if (ret)
+   goto err;
+
+   qmi->event_wq = alloc_workqueue("qmi_driver_event",
+ 

Re: [PATCH 03/12] ath10k: Add ath10k QMI client driver

2018-05-14 Thread Govind Singh

Hi Bjorn,
Thanks for the review.

On 2018-05-11 22:55, Bjorn Andersson wrote:

On Sun 25 Mar 22:39 PDT 2018, Govind Singh wrote:


Add QMI client driver for Q6 integrated WLAN connectivity
subsystem. This module is responsible for communicating WLAN
control messages to FW over QUALCOMM MSM Interface (QMI).

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/Kconfig  |   2 +-
 drivers/net/wireless/ath/ath10k/Makefile |   4 +
 drivers/net/wireless/ath/ath10k/qmi.c| 121 
+++

 drivers/net/wireless/ath/ath10k/qmi.h|  24 ++
 4 files changed, 150 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/wireless/ath/ath10k/qmi.c
 create mode 100644 drivers/net/wireless/ath/ath10k/qmi.h

diff --git a/drivers/net/wireless/ath/ath10k/Kconfig 
b/drivers/net/wireless/ath/ath10k/Kconfig

index 84f071a..9978ad5e 100644
--- a/drivers/net/wireless/ath/ath10k/Kconfig
+++ b/drivers/net/wireless/ath/ath10k/Kconfig
@@ -42,7 +42,7 @@ config ATH10K_USB

 config ATH10K_SNOC
 tristate "Qualcomm ath10k SNOC support (EXPERIMENTAL)"
-depends on ATH10K && ARCH_QCOM
+depends on ATH10K && ARCH_QCOM && QCOM_QMI_HELPERS


QCOM_QMI_HELPERS is expected to be selected by the clients, so this
would be:

select QCOM_QMI_HELPERS


Sure, will do in next version.


+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE 
LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY 
DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 
OUT OF

+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */


SPDX headers for new files please.



Sure, will do in next version.



+static struct ath10k_qmi *qmi;


Please design your code so that you don't depend on a global state
pointer.



Actually i thought about this, i can save this in platform drvdata and 
get this at

run time by saving the pdev in qmi_service->priv.
But qmi_service is available only in new_server/del_server, but not in 
the qmi indication callbacks.

Qmi handle also does not have the reference to the qmi_service.
Can you pls suggest something here.


+
+static int ath10k_qmi_new_server(struct qmi_handle *qmi_hdl,
+struct qmi_service *service)
+{
+   return 0;
+}
+
+static void ath10k_qmi_del_server(struct qmi_handle *qmi_hdl,
+ struct qmi_service *service)
+{
+}
+
+static struct qmi_ops ath10k_qmi_ops = {
+   .new_server = ath10k_qmi_new_server,
+   .del_server = ath10k_qmi_del_server,
+};
+
+static int ath10k_qmi_probe(struct platform_device *pdev)
+{
+   int ret;
+
+   qmi = devm_kzalloc(>dev, sizeof(*qmi),
+  GFP_KERNEL);


This doesn't need to be line wrapped.



Sure, will do in next version.


+   if (!qmi)
+   return -ENOMEM;
+
+   qmi->pdev = pdev;


The only place you use this is to access pdev->dev, so carry the struct
device * instead.



Sure, will do in next version.


+   platform_set_drvdata(pdev, qmi);
+   ret = qmi_handle_init(>qmi_hdl,
+ WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN,
+ _qmi_ops, NULL);
+   if (ret < 0)
+   goto err;
+
+   ret = qmi_add_lookup(>qmi_hdl, WLFW_SERVICE_ID_V01,
+WLFW_SERVICE_VERS_V01, 0);
+   if (ret < 0)
+   goto err;
+
+   pr_debug("qmi client driver probed successfully\n");


Rather than printing a line to indicate that your driver probed you can
check /sys/bus/platform/drivers/ath10k_QMI_client for for devices,
regardless of debug level.



Sure, will do in next version.


+
+   return 0;


qmi_add_lookup() returns 0 on success, so you can have a common return,
preferably after renaming "err" to "out" or something that indicates
that it covers both cases.


+
+err:
+   return ret;
+}
+
+static int ath10k_qmi_remove(struct platform_device *pdev)
+{
+   struct ath10k_qmi *qmi = platform_get_drvdata(pdev);
+
+   qmi_handle_release(>qmi_hdl);
+
+   return 0;
+}
+
+static const struct of_device_id ath10k_qmi_dt_match[] = {
+   {.compatible = "qcom,ath10k-qmi"},
+   {}
+};
+
+MODULE_DEVICE_TABLE(of, ath10k_qmi_dt_match);
+
+static struct platform_driver ath10k_qmi_clinet = {


Spelling of "client".



Sure, will do in next version.


+   .probe  = ath10k_qmi_probe,
+   .remove = ath10k_qmi_remove,
+   .driver = {
+   .name = "ath10k QMI client",
+   .owner = THIS_MODULE,


platform_driver_register() will fill out .owner for you, so skip this.


+   .of_match_table = ath10k_qmi_dt_match,
+   },
+};
+
+static int __in

Re: [PATCH] ath10k: Replace bit shifts with the BIT() macro for rx desc bits

2018-05-09 Thread Govind Singh

On 2018-05-09 13:10, Marcus Folkesson wrote:

Hello Govind,

On Wed, May 09, 2018 at 10:18:04AM +0530, Govind Singh wrote:

Use the BIT() macro from 'linux/bitops.h' to define the rx desc
bit flags to have consistency with new definitions.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/rx_desc.h | 134 
+++---

 1 file changed, 67 insertions(+), 67 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/rx_desc.h 
b/drivers/net/wireless/ath/ath10k/rx_desc.h

index 545deb6d7af1..b3d7c6e7ac90 100644
--- a/drivers/net/wireless/ath/ath10k/rx_desc.h
+++ b/drivers/net/wireless/ath/ath10k/rx_desc.h


Looks good, but please include linux/bitops.h as well.

From the documentation [1]:

If you use a facility then #include the file that defines/declares
 that facility.  Don't depend on other header files pulling in ones
 that you use.



Thanks, addressed the comment in v2 patchset.



[1] Documentation/process/submit-checklist.rst


Best regards
Marcus Folkesson


[PATCH v2] ath10k: Replace bit shifts with the BIT() macro for rx desc bits

2018-05-09 Thread Govind Singh
Use the BIT() macro from 'linux/bitops.h' to define the rx desc
bit flags to have consistency with new definitions.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/rx_desc.h | 136 +++---
 1 file changed, 69 insertions(+), 67 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/rx_desc.h 
b/drivers/net/wireless/ath/ath10k/rx_desc.h
index 545deb6d7af1..ea4075d456fa 100644
--- a/drivers/net/wireless/ath/ath10k/rx_desc.h
+++ b/drivers/net/wireless/ath/ath10k/rx_desc.h
@@ -18,39 +18,41 @@
 #ifndef _RX_DESC_H_
 #define _RX_DESC_H_
 
+#include 
+
 enum rx_attention_flags {
-   RX_ATTENTION_FLAGS_FIRST_MPDU  = 1 << 0,
-   RX_ATTENTION_FLAGS_LAST_MPDU   = 1 << 1,
-   RX_ATTENTION_FLAGS_MCAST_BCAST = 1 << 2,
-   RX_ATTENTION_FLAGS_PEER_IDX_INVALID= 1 << 3,
-   RX_ATTENTION_FLAGS_PEER_IDX_TIMEOUT= 1 << 4,
-   RX_ATTENTION_FLAGS_POWER_MGMT  = 1 << 5,
-   RX_ATTENTION_FLAGS_NON_QOS = 1 << 6,
-   RX_ATTENTION_FLAGS_NULL_DATA   = 1 << 7,
-   RX_ATTENTION_FLAGS_MGMT_TYPE   = 1 << 8,
-   RX_ATTENTION_FLAGS_CTRL_TYPE   = 1 << 9,
-   RX_ATTENTION_FLAGS_MORE_DATA   = 1 << 10,
-   RX_ATTENTION_FLAGS_EOSP= 1 << 11,
-   RX_ATTENTION_FLAGS_U_APSD_TRIGGER  = 1 << 12,
-   RX_ATTENTION_FLAGS_FRAGMENT= 1 << 13,
-   RX_ATTENTION_FLAGS_ORDER   = 1 << 14,
-   RX_ATTENTION_FLAGS_CLASSIFICATION  = 1 << 15,
-   RX_ATTENTION_FLAGS_OVERFLOW_ERR= 1 << 16,
-   RX_ATTENTION_FLAGS_MSDU_LENGTH_ERR = 1 << 17,
-   RX_ATTENTION_FLAGS_TCP_UDP_CHKSUM_FAIL = 1 << 18,
-   RX_ATTENTION_FLAGS_IP_CHKSUM_FAIL  = 1 << 19,
-   RX_ATTENTION_FLAGS_SA_IDX_INVALID  = 1 << 20,
-   RX_ATTENTION_FLAGS_DA_IDX_INVALID  = 1 << 21,
-   RX_ATTENTION_FLAGS_SA_IDX_TIMEOUT  = 1 << 22,
-   RX_ATTENTION_FLAGS_DA_IDX_TIMEOUT  = 1 << 23,
-   RX_ATTENTION_FLAGS_ENCRYPT_REQUIRED= 1 << 24,
-   RX_ATTENTION_FLAGS_DIRECTED= 1 << 25,
-   RX_ATTENTION_FLAGS_BUFFER_FRAGMENT = 1 << 26,
-   RX_ATTENTION_FLAGS_MPDU_LENGTH_ERR = 1 << 27,
-   RX_ATTENTION_FLAGS_TKIP_MIC_ERR= 1 << 28,
-   RX_ATTENTION_FLAGS_DECRYPT_ERR = 1 << 29,
-   RX_ATTENTION_FLAGS_FCS_ERR = 1 << 30,
-   RX_ATTENTION_FLAGS_MSDU_DONE   = 1 << 31,
+   RX_ATTENTION_FLAGS_FIRST_MPDU  = BIT(0),
+   RX_ATTENTION_FLAGS_LAST_MPDU   = BIT(1),
+   RX_ATTENTION_FLAGS_MCAST_BCAST = BIT(2),
+   RX_ATTENTION_FLAGS_PEER_IDX_INVALID= BIT(3),
+   RX_ATTENTION_FLAGS_PEER_IDX_TIMEOUT= BIT(4),
+   RX_ATTENTION_FLAGS_POWER_MGMT  = BIT(5),
+   RX_ATTENTION_FLAGS_NON_QOS = BIT(6),
+   RX_ATTENTION_FLAGS_NULL_DATA   = BIT(7),
+   RX_ATTENTION_FLAGS_MGMT_TYPE   = BIT(8),
+   RX_ATTENTION_FLAGS_CTRL_TYPE   = BIT(9),
+   RX_ATTENTION_FLAGS_MORE_DATA   = BIT(10),
+   RX_ATTENTION_FLAGS_EOSP= BIT(11),
+   RX_ATTENTION_FLAGS_U_APSD_TRIGGER  = BIT(12),
+   RX_ATTENTION_FLAGS_FRAGMENT= BIT(13),
+   RX_ATTENTION_FLAGS_ORDER   = BIT(14),
+   RX_ATTENTION_FLAGS_CLASSIFICATION  = BIT(15),
+   RX_ATTENTION_FLAGS_OVERFLOW_ERR= BIT(16),
+   RX_ATTENTION_FLAGS_MSDU_LENGTH_ERR = BIT(17),
+   RX_ATTENTION_FLAGS_TCP_UDP_CHKSUM_FAIL = BIT(18),
+   RX_ATTENTION_FLAGS_IP_CHKSUM_FAIL  = BIT(19),
+   RX_ATTENTION_FLAGS_SA_IDX_INVALID  = BIT(20),
+   RX_ATTENTION_FLAGS_DA_IDX_INVALID  = BIT(21),
+   RX_ATTENTION_FLAGS_SA_IDX_TIMEOUT  = BIT(22),
+   RX_ATTENTION_FLAGS_DA_IDX_TIMEOUT  = BIT(23),
+   RX_ATTENTION_FLAGS_ENCRYPT_REQUIRED= BIT(24),
+   RX_ATTENTION_FLAGS_DIRECTED= BIT(25),
+   RX_ATTENTION_FLAGS_BUFFER_FRAGMENT = BIT(26),
+   RX_ATTENTION_FLAGS_MPDU_LENGTH_ERR = BIT(27),
+   RX_ATTENTION_FLAGS_TKIP_MIC_ERR= BIT(28),
+   RX_ATTENTION_FLAGS_DECRYPT_ERR = BIT(29),
+   RX_ATTENTION_FLAGS_FCS_ERR = BIT(30),
+   RX_ATTENTION_FLAGS_MSDU_DONE   = BIT(31),
 };
 
 struct rx_attention {
@@ -254,15 +256,15 @@ enum htt_rx_mpdu_encrypt_type {
 #define RX_MPDU_START_INFO0_SEQ_NUM_LSB   16
 #define RX_MPDU_START_INFO0_ENCRYPT_TYPE_MASK 0xf000
 #define RX_MPDU_START_INFO0_ENCRYPT_TYPE_LSB  28
-#define RX_MPDU_START_INFO0_FROM_DS   (1 << 11)
-#define RX_MPDU_START_INFO0_TO_DS (1 << 12)
-#define RX_MPDU_START_INFO0_ENCRYPTED (1 << 13)
-#define RX_MPDU

[PATCH] ath10k: Replace bit shifts with the BIT() macro for rx desc bits

2018-05-08 Thread Govind Singh
Use the BIT() macro from 'linux/bitops.h' to define the rx desc
bit flags to have consistency with new definitions.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/rx_desc.h | 134 +++---
 1 file changed, 67 insertions(+), 67 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/rx_desc.h 
b/drivers/net/wireless/ath/ath10k/rx_desc.h
index 545deb6d7af1..b3d7c6e7ac90 100644
--- a/drivers/net/wireless/ath/ath10k/rx_desc.h
+++ b/drivers/net/wireless/ath/ath10k/rx_desc.h
@@ -19,38 +19,38 @@
 #define _RX_DESC_H_
 
 enum rx_attention_flags {
-   RX_ATTENTION_FLAGS_FIRST_MPDU  = 1 << 0,
-   RX_ATTENTION_FLAGS_LAST_MPDU   = 1 << 1,
-   RX_ATTENTION_FLAGS_MCAST_BCAST = 1 << 2,
-   RX_ATTENTION_FLAGS_PEER_IDX_INVALID= 1 << 3,
-   RX_ATTENTION_FLAGS_PEER_IDX_TIMEOUT= 1 << 4,
-   RX_ATTENTION_FLAGS_POWER_MGMT  = 1 << 5,
-   RX_ATTENTION_FLAGS_NON_QOS = 1 << 6,
-   RX_ATTENTION_FLAGS_NULL_DATA   = 1 << 7,
-   RX_ATTENTION_FLAGS_MGMT_TYPE   = 1 << 8,
-   RX_ATTENTION_FLAGS_CTRL_TYPE   = 1 << 9,
-   RX_ATTENTION_FLAGS_MORE_DATA   = 1 << 10,
-   RX_ATTENTION_FLAGS_EOSP= 1 << 11,
-   RX_ATTENTION_FLAGS_U_APSD_TRIGGER  = 1 << 12,
-   RX_ATTENTION_FLAGS_FRAGMENT= 1 << 13,
-   RX_ATTENTION_FLAGS_ORDER   = 1 << 14,
-   RX_ATTENTION_FLAGS_CLASSIFICATION  = 1 << 15,
-   RX_ATTENTION_FLAGS_OVERFLOW_ERR= 1 << 16,
-   RX_ATTENTION_FLAGS_MSDU_LENGTH_ERR = 1 << 17,
-   RX_ATTENTION_FLAGS_TCP_UDP_CHKSUM_FAIL = 1 << 18,
-   RX_ATTENTION_FLAGS_IP_CHKSUM_FAIL  = 1 << 19,
-   RX_ATTENTION_FLAGS_SA_IDX_INVALID  = 1 << 20,
-   RX_ATTENTION_FLAGS_DA_IDX_INVALID  = 1 << 21,
-   RX_ATTENTION_FLAGS_SA_IDX_TIMEOUT  = 1 << 22,
-   RX_ATTENTION_FLAGS_DA_IDX_TIMEOUT  = 1 << 23,
-   RX_ATTENTION_FLAGS_ENCRYPT_REQUIRED= 1 << 24,
-   RX_ATTENTION_FLAGS_DIRECTED= 1 << 25,
-   RX_ATTENTION_FLAGS_BUFFER_FRAGMENT = 1 << 26,
-   RX_ATTENTION_FLAGS_MPDU_LENGTH_ERR = 1 << 27,
-   RX_ATTENTION_FLAGS_TKIP_MIC_ERR= 1 << 28,
-   RX_ATTENTION_FLAGS_DECRYPT_ERR = 1 << 29,
-   RX_ATTENTION_FLAGS_FCS_ERR = 1 << 30,
-   RX_ATTENTION_FLAGS_MSDU_DONE   = 1 << 31,
+   RX_ATTENTION_FLAGS_FIRST_MPDU  = BIT(0),
+   RX_ATTENTION_FLAGS_LAST_MPDU   = BIT(1),
+   RX_ATTENTION_FLAGS_MCAST_BCAST = BIT(2),
+   RX_ATTENTION_FLAGS_PEER_IDX_INVALID= BIT(3),
+   RX_ATTENTION_FLAGS_PEER_IDX_TIMEOUT= BIT(4),
+   RX_ATTENTION_FLAGS_POWER_MGMT  = BIT(5),
+   RX_ATTENTION_FLAGS_NON_QOS = BIT(6),
+   RX_ATTENTION_FLAGS_NULL_DATA   = BIT(7),
+   RX_ATTENTION_FLAGS_MGMT_TYPE   = BIT(8),
+   RX_ATTENTION_FLAGS_CTRL_TYPE   = BIT(9),
+   RX_ATTENTION_FLAGS_MORE_DATA   = BIT(10),
+   RX_ATTENTION_FLAGS_EOSP= BIT(11),
+   RX_ATTENTION_FLAGS_U_APSD_TRIGGER  = BIT(12),
+   RX_ATTENTION_FLAGS_FRAGMENT= BIT(13),
+   RX_ATTENTION_FLAGS_ORDER   = BIT(14),
+   RX_ATTENTION_FLAGS_CLASSIFICATION  = BIT(15),
+   RX_ATTENTION_FLAGS_OVERFLOW_ERR= BIT(16),
+   RX_ATTENTION_FLAGS_MSDU_LENGTH_ERR = BIT(17),
+   RX_ATTENTION_FLAGS_TCP_UDP_CHKSUM_FAIL = BIT(18),
+   RX_ATTENTION_FLAGS_IP_CHKSUM_FAIL  = BIT(19),
+   RX_ATTENTION_FLAGS_SA_IDX_INVALID  = BIT(20),
+   RX_ATTENTION_FLAGS_DA_IDX_INVALID  = BIT(21),
+   RX_ATTENTION_FLAGS_SA_IDX_TIMEOUT  = BIT(22),
+   RX_ATTENTION_FLAGS_DA_IDX_TIMEOUT  = BIT(23),
+   RX_ATTENTION_FLAGS_ENCRYPT_REQUIRED= BIT(24),
+   RX_ATTENTION_FLAGS_DIRECTED= BIT(25),
+   RX_ATTENTION_FLAGS_BUFFER_FRAGMENT = BIT(26),
+   RX_ATTENTION_FLAGS_MPDU_LENGTH_ERR = BIT(27),
+   RX_ATTENTION_FLAGS_TKIP_MIC_ERR= BIT(28),
+   RX_ATTENTION_FLAGS_DECRYPT_ERR = BIT(29),
+   RX_ATTENTION_FLAGS_FCS_ERR = BIT(30),
+   RX_ATTENTION_FLAGS_MSDU_DONE   = BIT(31),
 };
 
 struct rx_attention {
@@ -254,15 +254,15 @@ enum htt_rx_mpdu_encrypt_type {
 #define RX_MPDU_START_INFO0_SEQ_NUM_LSB   16
 #define RX_MPDU_START_INFO0_ENCRYPT_TYPE_MASK 0xf000
 #define RX_MPDU_START_INFO0_ENCRYPT_TYPE_LSB  28
-#define RX_MPDU_START_INFO0_FROM_DS   (1 << 11)
-#define RX_MPDU_START_INFO0_TO_DS (1 << 12)
-#define RX_MPDU_START_INFO0_ENCRYPTED (1 << 13)
-#define RX_MPDU_START_INFO0_RETRY (1 << 14)
-#define

Re: [PATCH v3 00/12] *** Add support for wifi QMI client driver ***

2018-05-08 Thread Govind Singh

On 2018-05-08 23:07, Bjorn Andersson wrote:

On Sun 25 Mar 22:37 PDT 2018, Govind Singh wrote:


Add QMI client driver for Q6 integrated WLAN connectivity subsystem.
This module is responsible for communicating WLAN control messages to 
FW

over QMI interface.

“QUALCOMM Messaging Interface”(QMI) provides the control interface 
between
components running b/w remote processors with underlying transport 
layer
based on integrated chipset(shared memory) or discrete 
chipset(PCI/USB/SDIO/UART).


QMI client driver implementation is based on qmi frmework 
https://lwn.net/Articles/729924/.


Below is the sequence of qmi handshake.

   QMI CLIENT(APPS) QMI 
SERVER(FW in Q6)


 <--wlan service discoverd

   -connect to wlam qmi service->

   wlan info request->

   <wlan info resp

   msa info req>

 <msa info resp

 msa ready req>

 <msa ready resp

 <msa ready indication---

 capability req--->

<capability resp

qmi bdf req->

 <qmi bdf resp

  qmi cal trigger--->

  < QMI FW ready indication---


Does the responsibility of the driver ends here? I mean is this a 
driver

for setting up the firmware and then there's something else doing the
actual wifi operation, or does it simply hand over execution to the
common ath10k logic at this point?



From wlan qmi client point of view once wlan qmi service is discovered, 
it connects to the service and
does the above handshakes and later it handover the execution to common 
ath10k logic.

These handshakes will be done as part of pd restart as well.



Govind Singh (12):
  ath10k: Add qmi service for wlan qmi client
  dt: bindings: add bindings for ath10k qmi client
  ath10k: Add WCN3990 QMI client driver
  ath10k: add support to start and stop qmi service
  ath10k: Add support of QMI indication message
  firmware: qcom: scm: Add WLAN VMID for Qualcomm SCM interface
  ath10k: Add MSA handshake QMI mgs support
  ath10k: Add QMI CAP request support
  ath10k: Add QMI HOST CAP request support
  ath10k: add bdf/cal indication support
  ath10k: Add wlan mode on/off qmi message
  ath10k: Add qmi wlan enable/disable support for WCN3990


I'm missing this last patch in my mailbox, and it would be nice if all
the patches where in-reply-to the cover letter, to make them easier to
find.

Regards,
Bjorn


Sure, I will take care this while submitting next version of this patch 
series.


BR,
Govind


Re: [PATCH 06/12] firmware: qcom: scm: Add WLAN VMID for Qualcomm SCM interface

2018-05-08 Thread Govind Singh

On 2018-05-08 02:12, Bjorn Andersson wrote:

On Sun 25 Mar 22:40 PDT 2018, Govind Singh wrote:


Add WLAN related VMID's to support wlan driver to set up
the remote's permissions call via TrustZone.

Signed-off-by: Govind Singh <govi...@codeaurora.org>


Please use ./scripts/get_maintainer.pl for each patch to get a hint
about whom to send your patches to.

While I think it's okay that Kalle picks it through his tree Andy 
should

give his ack first.


Acked-by: Bjorn Andersson <bjorn.anders...@linaro.org>

Regards,
Bjorn



Thanks Bjorn for the review.
I will take care this point while sending the next version of the qmi 
patch set.



---
 include/linux/qcom_scm.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h
index b401b96..da63d84 100644
--- a/include/linux/qcom_scm.h
+++ b/include/linux/qcom_scm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2015, The Linux Foundation. All rights 
reserved.
+/* Copyright (c) 2010-2015, 2018, The Linux Foundation. All rights 
reserved.

  * Copyright (C) 2015 Linaro Ltd.
  *
  * This program is free software; you can redistribute it and/or 
modify

@@ -33,6 +33,8 @@ struct qcom_scm_vmperm {

 #define QCOM_SCM_VMID_HLOS   0x3
 #define QCOM_SCM_VMID_MSS_MSA0xF
+#define QCOM_SCM_VMID_WLAN   0x18
+#define QCOM_SCM_VMID_WLAN_CE0x19
 #define QCOM_SCM_PERM_READ   0x4
 #define QCOM_SCM_PERM_WRITE  0x2
 #define QCOM_SCM_PERM_EXEC   0x1
--
1.9.1



[PATCH] ath10k: Fix fw path name for WCN3990 target

2018-04-15 Thread Govind Singh
FW path is mapped incorrectly for the WCN3990
hw version. Fix fw path with correct hw1.0 name.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/hw.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net/wireless/ath/ath10k/hw.h
index 3041eba..b025a1b 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -131,7 +131,7 @@ enum qca9377_chip_id_rev {
 
 /* WCN3990 1.0 definitions */
 #define WCN3990_HW_1_0_DEV_VERSION ATH10K_HW_WCN3990
-#define WCN3990_HW_1_0_FW_DIR  ATH10K_FW_DIR "/WCN3990/hw3.0"
+#define WCN3990_HW_1_0_FW_DIR  ATH10K_FW_DIR "/WCN3990/hw1.0"
 
 #define ATH10K_FW_FILE_BASE"firmware"
 #define ATH10K_FW_API_MAX  6
-- 
1.9.1



[PATCH v2 13/13] dt: bindings: add bindings for wcn3990 wifi block

2018-04-10 Thread Govind Singh
Add device tree binding documentation details for wcn3990
wifi block present in Qualcomm SDM845/APQ8098 SoC into
"qcom,ath10k.txt".

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 .../bindings/net/wireless/qcom,ath10k.txt  | 31 ++
 1 file changed, 31 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt 
b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
index 3d2a031..34e4f98 100644
--- a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
+++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
@@ -4,6 +4,7 @@ Required properties:
 - compatible: Should be one of the following:
* "qcom,ath10k"
* "qcom,ipq4019-wifi"
+   * "qcom,wcn3990-wifi"
 
 PCI based devices uses compatible string "qcom,ath10k" and takes calibration
 data along with board specific data via "qcom,ath10k-calibration-data".
@@ -18,8 +19,12 @@ In general, entry "qcom,ath10k-pre-calibration-data" and
 "qcom,ath10k-calibration-data" conflict with each other and only one
 can be provided per device.
 
+SNOC based devices (i.e. wcn3990) uses compatible string "qcom,wcn3990-wifi".
+
 Optional properties:
 - reg: Address and length of the register set for the device.
+- reg-names: Must include the list of following reg names,
+"membase"
 - resets: Must contain an entry for each entry in reset-names.
   See ../reset/reseti.txt for details.
 - reset-names: Must include the list of following reset names,
@@ -49,6 +54,8 @@ Optional properties:
 hw versions.
 - qcom,ath10k-pre-calibration-data : pre calibration data as an array,
 the length can vary between hw versions.
+- -supply: handle to the regulator device tree node
+  optional "supply-name" is "vdd-0.8-cx-mx".
 
 Example (to supply the calibration data alone):
 
@@ -119,3 +126,27 @@ wifi0: wifi@a00 {
qcom,msi_base = <0x40>;
qcom,ath10k-pre-calibration-data = [ 01 02 03 ... ];
 };
+
+Example (to supply wcn3990 SoC wifi block details):
+
+qcom,wifi@1800 {
+   compatible = "qcom,wcn3990-wifi";
+   reg = <0x1880 0x80>;
+   reg-names = "membase";
+   clocks = <_gcc clk_aggre2_noc_clk>;
+   clock-names = "smmu_aggre2_noc_clk"
+   interrupts =
+  <0 130 0 /* CE0 */ >,
+  <0 131 0 /* CE1 */ >,
+  <0 132 0 /* CE2 */ >,
+  <0 133 0 /* CE3 */ >,
+  <0 134 0 /* CE4 */ >,
+  <0 135 0 /* CE5 */ >,
+  <0 136 0 /* CE6 */ >,
+  <0 137 0 /* CE7 */ >,
+  <0 138 0 /* CE8 */ >,
+  <0 139 0 /* CE9 */ >,
+  <0 140 0 /* CE10 */ >,
+  <0 141 0 /* CE11 */ >;
+   vdd-0.8-cx-mx-supply = <_l5>;
+};
-- 
1.9.1



[PATCH 12/12] ath10k: Add qmi wlan enable/disable support for WCN3990

2018-03-25 Thread Govind Singh
Send wlan mode on/off request dynamically to bring up
target to active state during load and put in power
down state during unload.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/snoc.c | 179 -
 1 file changed, 178 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/snoc.c 
b/drivers/net/wireless/ath/ath10k/snoc.c
index 2e490ff..f6592a9 100644
--- a/drivers/net/wireless/ath/ath10k/snoc.c
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -21,6 +21,7 @@
 #include "htc.h"
 #include "ce.h"
 #include "snoc.h"
+#include "qmi.h"
 #include 
 #include 
 #include 
@@ -67,6 +68,24 @@
.dma_mask = DMA_BIT_MASK(37),
 };
 
+#define WCN3990_SRC_WR_INDEX_OFFSET 0x3C
+#define WCN3990_DST_WR_INDEX_OFFSET 0x40
+
+static struct ath10k_shadow_reg_cfg target_shadow_reg_cfg_map[] = {
+   { 0, WCN3990_SRC_WR_INDEX_OFFSET},
+   { 3, WCN3990_SRC_WR_INDEX_OFFSET},
+   { 4, WCN3990_SRC_WR_INDEX_OFFSET},
+   { 5, WCN3990_SRC_WR_INDEX_OFFSET},
+   { 7, WCN3990_SRC_WR_INDEX_OFFSET},
+   { 1, WCN3990_DST_WR_INDEX_OFFSET},
+   { 2, WCN3990_DST_WR_INDEX_OFFSET},
+   { 7, WCN3990_DST_WR_INDEX_OFFSET},
+   { 8, WCN3990_DST_WR_INDEX_OFFSET},
+   { 9, WCN3990_DST_WR_INDEX_OFFSET},
+   { 10, WCN3990_DST_WR_INDEX_OFFSET},
+   { 11, WCN3990_DST_WR_INDEX_OFFSET},
+};
+
 static struct ce_attr host_ce_config_wlan[] = {
/* CE0: host->target HTC control streams */
{
@@ -174,6 +193,128 @@
},
 };
 
+static struct ce_pipe_config target_ce_config_wlan[] = {
+   /* CE0: host->target HTC control and raw streams */
+   {
+   .pipenum = __cpu_to_le32(0),
+   .pipedir = __cpu_to_le32(PIPEDIR_OUT),
+   .nentries = __cpu_to_le32(32),
+   .nbytes_max = __cpu_to_le32(2048),
+   .flags = __cpu_to_le32(CE_ATTR_FLAGS),
+   .reserved = __cpu_to_le32(0),
+   },
+
+   /* CE1: target->host HTT + HTC control */
+   {
+   .pipenum = __cpu_to_le32(1),
+   .pipedir = __cpu_to_le32(PIPEDIR_IN),
+   .nentries = __cpu_to_le32(32),
+   .nbytes_max = __cpu_to_le32(2048),
+   .flags = __cpu_to_le32(CE_ATTR_FLAGS),
+   .reserved = __cpu_to_le32(0),
+   },
+
+   /* CE2: target->host WMI */
+   {
+   .pipenum = __cpu_to_le32(2),
+   .pipedir = __cpu_to_le32(PIPEDIR_IN),
+   .nentries = __cpu_to_le32(64),
+   .nbytes_max = __cpu_to_le32(2048),
+   .flags = __cpu_to_le32(CE_ATTR_FLAGS),
+   .reserved = __cpu_to_le32(0),
+   },
+
+   /* CE3: host->target WMI */
+   {
+   .pipenum = __cpu_to_le32(3),
+   .pipedir = __cpu_to_le32(PIPEDIR_OUT),
+   .nentries = __cpu_to_le32(32),
+   .nbytes_max = __cpu_to_le32(2048),
+   .flags = __cpu_to_le32(CE_ATTR_FLAGS),
+   .reserved = __cpu_to_le32(0),
+   },
+
+   /* CE4: host->target HTT */
+   {
+   .pipenum = __cpu_to_le32(4),
+   .pipedir = __cpu_to_le32(PIPEDIR_OUT),
+   .nentries = __cpu_to_le32(256),
+   .nbytes_max = __cpu_to_le32(256),
+   .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
+   .reserved = __cpu_to_le32(0),
+   },
+
+   /* CE5: target->host HTT (HIF->HTT) */
+   {
+   .pipenum = __cpu_to_le32(5),
+   .pipedir = __cpu_to_le32(PIPEDIR_OUT),
+   .nentries = __cpu_to_le32(1024),
+   .nbytes_max = __cpu_to_le32(64),
+   .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
+   .reserved = __cpu_to_le32(0),
+   },
+
+   /* CE6: Reserved for target autonomous hif_memcpy */
+   {
+   .pipenum = __cpu_to_le32(6),
+   .pipedir = __cpu_to_le32(PIPEDIR_INOUT),
+   .nentries = __cpu_to_le32(32),
+   .nbytes_max = __cpu_to_le32(16384),
+   .flags = __cpu_to_le32(CE_ATTR_FLAGS),
+   .reserved = __cpu_to_le32(0),
+   },
+
+   /* CE7 used only by Host */
+   {
+   .pipenum = __cpu_to_le32(7),
+   .pipedir = __cpu_to_le32(4),
+   .nentries = __cpu_to_le32(0),
+   .nbytes_max = __cpu_to_le32(0),
+   .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
+   .reserved = __cpu_to_le32(0),
+   },
+
+   /* CE8 Target to uMC */
+   {
+   .pipenum = __cpu_to_le32(8),
+   .pipedir = __cpu_to_le32(PIPEDIR_IN),
+   .nentries = __cpu_to_le32(32),
+   .nbytes_max = __cpu_to_le32(2048)

[PATCH 09/12] ath10k: Add QMI HOST CAP request support

2018-03-25 Thread Govind Singh
Add support for host capablity request
qmi message for wcn3990 target.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/qmi.c | 65 +++
 1 file changed, 65 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/qmi.c 
b/drivers/net/wireless/ath/ath10k/qmi.c
index 65a43af..a33681d 100644
--- a/drivers/net/wireless/ath/ath10k/qmi.c
+++ b/drivers/net/wireless/ath/ath10k/qmi.c
@@ -357,6 +357,67 @@ static int ath10k_qmi_cap_send_sync_msg(struct ath10k_qmi 
*qmi)
return ret;
 }
 
+static int ath10k_qmi_host_cap_send_sync(struct ath10k_qmi *qmi)
+{
+   struct wlfw_host_cap_resp_msg_v01 *resp;
+   struct wlfw_host_cap_req_msg_v01 *req;
+   struct qmi_txn txn;
+   int ret;
+
+   req = kzalloc(sizeof(*req), GFP_KERNEL);
+   if (!req)
+   return -ENOMEM;
+
+   resp = kzalloc(sizeof(*resp), GFP_KERNEL);
+   if (!resp) {
+   kfree(req);
+   return -ENOMEM;
+   }
+
+   req->daemon_support_valid = 1;
+   req->daemon_support = 0;
+
+   pr_debug("daemon_support is %d\n", req->daemon_support);
+
+   ret = qmi_txn_init(>qmi_hdl, ,
+  wlfw_host_cap_resp_msg_v01_ei, resp);
+   if (ret < 0) {
+   pr_err("Fail to init txn for Capability resp %d\n", ret);
+   goto out;
+   }
+
+   ret = qmi_send_request(>qmi_hdl, NULL, ,
+  QMI_WLFW_HOST_CAP_REQ_V01,
+  WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN,
+  wlfw_host_cap_req_msg_v01_ei, req);
+   if (ret < 0) {
+   qmi_txn_cancel();
+   pr_err("Fail to send Capability req %d\n", ret);
+   goto out;
+   }
+
+   ret = qmi_txn_wait(, WLFW_TIMEOUT * HZ);
+   if (ret < 0)
+   goto out;
+
+   if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
+   pr_err("qmi host capability req rejected, result:%d error:%d\n",
+  resp->resp.result, resp->resp.error);
+   ret = -resp->resp.result;
+   goto out;
+   }
+
+   pr_debug("host cap request completed\n");
+   kfree(resp);
+   kfree(req);
+   return 0;
+
+out:
+   kfree(resp);
+   kfree(req);
+   return ret;
+}
+
 static int
 ath10k_qmi_ind_register_send_sync_msg(struct ath10k_qmi *qmi)
 {
@@ -500,6 +561,10 @@ static void ath10k_qmi_event_server_arrive(struct 
work_struct *work)
if (ret)
return;
 
+   ret = ath10k_qmi_host_cap_send_sync(qmi);
+   if (ret)
+   return;
+
ret = ath10k_qmi_msa_mem_info_send_sync_msg(qmi);
if (ret)
return;
-- 
1.9.1



[PATCH 11/12] ath10k: Add wlan mode on/off qmi message

2018-03-25 Thread Govind Singh
Add qmi message required for enabling and disabling
target to qmi server running in Q6.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/qmi.c | 226 +-
 drivers/net/wireless/ath/ath10k/qmi.h |  62 ++
 2 files changed, 264 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/qmi.c 
b/drivers/net/wireless/ath/ath10k/qmi.c
index f23d0fe..331a528 100644
--- a/drivers/net/wireless/ath/ath10k/qmi.c
+++ b/drivers/net/wireless/ath/ath10k/qmi.c
@@ -35,7 +35,30 @@
 #define WLFW_CLIENT_ID 0x4b4e454c
 #define WLFW_TIMEOUT   500
 
-static struct ath10k_qmi *qmi;
+static struct ath10k_qmi {
+   struct platform_device *pdev;
+   struct qmi_handle qmi_hdl;
+   struct sockaddr_qrtr sq;
+   bool fw_ready;
+   bool msa_ready;
+   struct work_struct work_svc_arrive;
+   struct work_struct work_svc_exit;
+   struct work_struct work_msa_ready;
+   struct workqueue_struct *event_wq;
+   spinlock_t event_lock; /* spinlock for fw ready status*/
+   u32 nr_mem_region;
+   struct ath10k_msa_mem_region_info
+   mem_region[MAX_NUM_MEMORY_REGIONS];
+   phys_addr_t msa_pa;
+   u32 msa_mem_size;
+   void *msa_va;
+   struct ath10k_qmi_chip_info chip_info;
+   struct ath10k_qmi_board_info board_info;
+   struct ath10k_qmi_soc_info soc_info;
+   struct ath10k_qmi_fw_version_info fw_version_info;
+   char fw_build_id[MAX_BUILD_ID_LEN + 1];
+   struct ath10k_qmi_cal_data cal_data[MAX_NUM_CAL_V01];
+} *qmi;
 
 static int
 ath10k_qmi_map_msa_permissions(struct ath10k_msa_mem_region_info *mem_region)
@@ -444,6 +467,207 @@ int ath10k_qmi_send_cal_report_req(struct ath10k_qmi *qmi)
return ret;
 }
 
+static int
+ath10k_qmi_mode_send_sync_msg(enum wlfw_driver_mode_enum_v01 mode)
+{
+   struct wlfw_wlan_mode_resp_msg_v01 *resp;
+   struct wlfw_wlan_mode_req_msg_v01 *req;
+   struct qmi_txn txn;
+   int ret;
+
+   req = kzalloc(sizeof(*req), GFP_KERNEL);
+   if (!req)
+   return -ENOMEM;
+
+   resp = kzalloc(sizeof(*resp), GFP_KERNEL);
+   if (!resp) {
+   kfree(req);
+   return -ENOMEM;
+   }
+
+   ret = qmi_txn_init(>qmi_hdl, ,
+  wlfw_wlan_mode_resp_msg_v01_ei,
+  resp);
+   if (ret < 0) {
+   pr_err("fail to init txn for mode req %d ret %d\n", mode, ret);
+   goto out;
+   }
+
+   req->mode = mode;
+   req->hw_debug_valid = 1;
+   req->hw_debug = 0;
+
+   ret = qmi_send_request(>qmi_hdl, NULL, ,
+  QMI_WLFW_WLAN_MODE_REQ_V01,
+  WLFW_WLAN_MODE_REQ_MSG_V01_MAX_MSG_LEN,
+  wlfw_wlan_mode_req_msg_v01_ei, req);
+   if (ret < 0) {
+   qmi_txn_cancel();
+   pr_err("send mode req failed, mode: %d ret: %d\n",
+  mode, ret);
+   goto out;
+   }
+
+   ret = qmi_txn_wait(, WLFW_TIMEOUT * HZ);
+   if (ret < 0)
+   goto out;
+
+   if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
+   pr_err("qmi mode request rejected:");
+   pr_err("mode:%d result:%d error:%d\n",
+  mode, resp->resp.result, resp->resp.error);
+   ret = resp->resp.result;
+   goto out;
+   }
+
+   pr_debug("wlan Mode request completed, mode: %d\n", mode);
+   kfree(resp);
+   kfree(req);
+   return 0;
+
+out:
+   kfree(resp);
+   kfree(req);
+   return ret;
+}
+
+static int
+ath10k_qmi_cfg_send_sync_msg(struct wlfw_wlan_cfg_req_msg_v01 *data)
+{
+   struct wlfw_wlan_cfg_resp_msg_v01 *resp;
+   struct wlfw_wlan_cfg_req_msg_v01 *req;
+   struct qmi_txn txn;
+   int ret;
+
+   req = kzalloc(sizeof(*req), GFP_KERNEL);
+   if (!req)
+   return -ENOMEM;
+
+   resp = kzalloc(sizeof(*resp), GFP_KERNEL);
+   if (!resp) {
+   kfree(req);
+   return -ENOMEM;
+   }
+
+   ret = qmi_txn_init(>qmi_hdl, ,
+  wlfw_wlan_cfg_resp_msg_v01_ei,
+  resp);
+   if (ret < 0) {
+   pr_err("fail to init txn for config req %d\n", ret);
+   goto out;
+   }
+
+   memcpy(req, data, sizeof(*req));
+
+   ret = qmi_send_request(>qmi_hdl, NULL, ,
+  QMI_WLFW_WLAN_CFG_REQ_V01,
+  WLFW_WLAN_CFG_REQ_MSG_V01_MAX_MSG_LEN,
+  wlfw_wlan_cfg_req_msg_v01_ei, req);
+   if (ret < 0) {
+   qmi_txn_cancel();
+   pr_err("send config req failed %d\n", ret);
+   

[PATCH 10/12] ath10k: add bdf/cal indication support

2018-03-25 Thread Govind Singh
Add support for bdf download and cold boot
calibration trigger qmi message support.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/qmi.c | 195 ++
 drivers/net/wireless/ath/ath10k/qmi.h |  10 ++
 2 files changed, 205 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/qmi.c 
b/drivers/net/wireless/ath/ath10k/qmi.c
index a33681d..f23d0fe 100644
--- a/drivers/net/wireless/ath/ath10k/qmi.c
+++ b/drivers/net/wireless/ath/ath10k/qmi.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "qmi.h"
 #include "qmi_svc_v01.h"
 
@@ -270,6 +271,179 @@ static int ath10k_qmi_msa_ready_send_sync_msg(struct 
ath10k_qmi *qmi)
return ret;
 }
 
+int ath10k_qmi_bdf_dnld_send_sync(struct ath10k_qmi *qmi)
+{
+   struct wlfw_bdf_download_resp_msg_v01 *resp;
+   struct wlfw_bdf_download_req_msg_v01 *req;
+   const struct firmware *fw_entry;
+   unsigned int remaining;
+   struct qmi_txn txn;
+   const u8 *temp;
+   int ret;
+
+   req = kzalloc(sizeof(*req), GFP_KERNEL);
+   if (!req)
+   return -ENOMEM;
+
+   resp = kzalloc(sizeof(*resp), GFP_KERNEL);
+   if (!resp) {
+   kfree(req);
+   return -ENOMEM;
+   }
+
+   ret = request_firmware(_entry, BDF_FILE_NAME, >pdev->dev);
+   if (ret < 0) {
+   pr_err("fail to load bdf: %s\n", BDF_FILE_NAME);
+   goto err_req_fw;
+   }
+
+   temp = fw_entry->data;
+   remaining = fw_entry->size;
+
+   pr_debug("downloading bdf: %s, size: %u\n",
+BDF_FILE_NAME, remaining);
+
+   while (remaining) {
+   req->valid = 1;
+   req->file_id_valid = 1;
+   req->file_id = 0;
+   req->total_size_valid = 1;
+   req->total_size = fw_entry->size;
+   req->seg_id_valid = 1;
+   req->data_valid = 1;
+   req->end_valid = 1;
+
+   if (remaining > QMI_WLFW_MAX_DATA_SIZE_V01) {
+   req->data_len = QMI_WLFW_MAX_DATA_SIZE_V01;
+   } else {
+   req->data_len = remaining;
+   req->end = 1;
+   }
+
+   memcpy(req->data, temp, req->data_len);
+
+   ret = qmi_txn_init(>qmi_hdl, ,
+  wlfw_bdf_download_resp_msg_v01_ei,
+  resp);
+   if (ret < 0) {
+   pr_err("fail to init txn for bdf download %d\n", ret);
+   goto out;
+   }
+
+   ret =
+   qmi_send_request(>qmi_hdl, NULL, ,
+QMI_WLFW_BDF_DOWNLOAD_REQ_V01,
+WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN,
+wlfw_bdf_download_req_msg_v01_ei, req);
+   if (ret < 0) {
+   qmi_txn_cancel();
+   goto err_send;
+   }
+
+   ret = qmi_txn_wait(, WLFW_TIMEOUT * HZ);
+
+   if (ret < 0)
+   goto err_send;
+
+   if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
+   pr_err("bdf download failed, res:%d, err:%d\n",
+  resp->resp.result, resp->resp.error);
+   ret = resp->resp.result;
+   goto err_send;
+   }
+
+   remaining -= req->data_len;
+   temp += req->data_len;
+   req->seg_id++;
+   }
+
+   pr_debug("bdf download request completed\n");
+
+   kfree(resp);
+   kfree(req);
+   return 0;
+
+err_send:
+   release_firmware(fw_entry);
+
+err_req_fw:
+   kfree(req);
+   kfree(resp);
+
+out:
+   return ret;
+}
+
+int ath10k_qmi_send_cal_report_req(struct ath10k_qmi *qmi)
+{
+   struct wlfw_cal_report_resp_msg_v01 *resp;
+   struct wlfw_cal_report_req_msg_v01 *req;
+   struct qmi_txn txn;
+   int i, j = 0;
+   int ret;
+
+   pr_debug("sending cal report\n");
+
+   req = kzalloc(sizeof(*req), GFP_KERNEL);
+   if (!req)
+   return -ENOMEM;
+
+   resp = kzalloc(sizeof(*resp), GFP_KERNEL);
+   if (!resp) {
+   kfree(req);
+   return -ENOMEM;
+   }
+
+   ret = qmi_txn_init(>qmi_hdl, , wlfw_cal_report_resp_msg_v01_ei,
+  resp);
+   if (ret < 0) {
+   pr_err("fail to init txn for bdf download req %d\n", ret);
+   goto out;
+   }
+
+   for (i = 0; i < QMI_WLFW_MAX_NUM_CAL_V01; i++) {
+   if (qmi->cal_data[i].total_size &&
+   

[PATCH 08/12] ath10k: Add QMI CAP request support

2018-03-25 Thread Govind Singh
Add support for target capablity request
qmi message for wcn3990 target.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/qmi.c | 91 +++
 drivers/net/wireless/ath/ath10k/qmi.h | 25 ++
 2 files changed, 116 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/qmi.c 
b/drivers/net/wireless/ath/ath10k/qmi.c
index 763b812..65a43af 100644
--- a/drivers/net/wireless/ath/ath10k/qmi.c
+++ b/drivers/net/wireless/ath/ath10k/qmi.c
@@ -270,6 +270,93 @@ static int ath10k_qmi_msa_ready_send_sync_msg(struct 
ath10k_qmi *qmi)
return ret;
 }
 
+static int ath10k_qmi_cap_send_sync_msg(struct ath10k_qmi *qmi)
+{
+   struct wlfw_cap_resp_msg_v01 *resp;
+   struct wlfw_cap_req_msg_v01 *req;
+   struct qmi_txn txn;
+   int ret;
+
+   req = kzalloc(sizeof(*req), GFP_KERNEL);
+   if (!req)
+   return -ENOMEM;
+
+   resp = kzalloc(sizeof(*resp), GFP_KERNEL);
+   if (!resp) {
+   kfree(req);
+   return -ENOMEM;
+   }
+
+   ret = qmi_txn_init(>qmi_hdl, , wlfw_cap_resp_msg_v01_ei, resp);
+   if (ret < 0) {
+   pr_err("fail to init txn for capability resp %d\n", ret);
+   goto out;
+   }
+
+   ret = qmi_send_request(>qmi_hdl, NULL, ,
+  QMI_WLFW_CAP_REQ_V01,
+  WLFW_CAP_REQ_MSG_V01_MAX_MSG_LEN,
+  wlfw_cap_req_msg_v01_ei, req);
+   if (ret < 0) {
+   qmi_txn_cancel();
+   pr_err("fail to send capability req %d\n", ret);
+   goto out;
+   }
+
+   ret = qmi_txn_wait(, WLFW_TIMEOUT * HZ);
+   if (ret < 0)
+   goto out;
+
+   if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
+   pr_err("qmi capability request rejected, result:%d error:%d\n",
+  resp->resp.result, resp->resp.error);
+   ret = -resp->resp.result;
+   goto out;
+   }
+
+   if (resp->chip_info_valid) {
+   qmi->chip_info.chip_id = resp->chip_info.chip_id;
+   qmi->chip_info.chip_family = resp->chip_info.chip_family;
+   }
+
+   if (resp->board_info_valid)
+   qmi->board_info.board_id = resp->board_info.board_id;
+   else
+   qmi->board_info.board_id = 0xFF;
+
+   if (resp->soc_info_valid)
+   qmi->soc_info.soc_id = resp->soc_info.soc_id;
+
+   if (resp->fw_version_info_valid) {
+   qmi->fw_version_info.fw_version =
+   resp->fw_version_info.fw_version;
+   strlcpy(qmi->fw_version_info.fw_build_timestamp,
+   resp->fw_version_info.fw_build_timestamp,
+   MAX_TIMESTAMP_LEN + 1);
+   }
+
+   if (resp->fw_build_id_valid)
+   strlcpy(qmi->fw_build_id, resp->fw_build_id,
+   MAX_BUILD_ID_LEN + 1);
+
+   pr_debug("chip_id: 0x%x, chip_family: 0x%x, board_id: 0x%x, soc_id: 
0x%x, fw_version: 0x%x, fw_build_timestamp: %s, fw_build_id: %s",
+qmi->chip_info.chip_id, qmi->chip_info.chip_family,
+qmi->board_info.board_id, qmi->soc_info.soc_id,
+qmi->fw_version_info.fw_version,
+qmi->fw_version_info.fw_build_timestamp,
+qmi->fw_build_id);
+
+   pr_debug("target cap request completed\n");
+   kfree(resp);
+   kfree(req);
+
+   return 0;
+out:
+   kfree(resp);
+   kfree(req);
+   return ret;
+}
+
 static int
 ath10k_qmi_ind_register_send_sync_msg(struct ath10k_qmi *qmi)
 {
@@ -425,6 +512,10 @@ static void ath10k_qmi_event_server_arrive(struct 
work_struct *work)
if (ret)
goto err_setup_msa;
 
+   ret = ath10k_qmi_cap_send_sync_msg(qmi);
+   if (ret)
+   goto err_setup_msa;
+
return;
 
 err_setup_msa:
diff --git a/drivers/net/wireless/ath/ath10k/qmi.h 
b/drivers/net/wireless/ath/ath10k/qmi.h
index 47af020..09d20a0 100644
--- a/drivers/net/wireless/ath/ath10k/qmi.h
+++ b/drivers/net/wireless/ath/ath10k/qmi.h
@@ -17,6 +17,8 @@
 #define _QMI_H_
 
 #define MAX_NUM_MEMORY_REGIONS 2
+#define MAX_TIMESTAMP_LEN  32
+#define MAX_BUILD_ID_LEN   128
 
 enum ath10k_qmi_driver_event_type {
ATH10K_QMI_EVENT_SERVER_ARRIVE,
@@ -31,6 +33,24 @@ struct ath10k_msa_mem_region_info {
u8 secure_flag;
 };
 
+struct ath10k_qmi_chip_info {
+   u32 chip_id;
+   u32 chip_family;
+};
+
+struct ath10k_qmi_board_info {
+   u32 board_id;
+};
+
+struct ath10k_qmi_soc_info {
+   u32 soc_id;
+};
+
+struct ath10k_qmi_fw_version_info {
+   u32 fw_version;
+   char fw_build_timest

[PATCH 06/12] firmware: qcom: scm: Add WLAN VMID for Qualcomm SCM interface

2018-03-25 Thread Govind Singh
Add WLAN related VMID's to support wlan driver to set up
the remote's permissions call via TrustZone.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 include/linux/qcom_scm.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h
index b401b96..da63d84 100644
--- a/include/linux/qcom_scm.h
+++ b/include/linux/qcom_scm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2015, 2018, The Linux Foundation. All rights reserved.
  * Copyright (C) 2015 Linaro Ltd.
  *
  * This program is free software; you can redistribute it and/or modify
@@ -33,6 +33,8 @@ struct qcom_scm_vmperm {
 
 #define QCOM_SCM_VMID_HLOS   0x3
 #define QCOM_SCM_VMID_MSS_MSA0xF
+#define QCOM_SCM_VMID_WLAN   0x18
+#define QCOM_SCM_VMID_WLAN_CE0x19
 #define QCOM_SCM_PERM_READ   0x4
 #define QCOM_SCM_PERM_WRITE  0x2
 #define QCOM_SCM_PERM_EXEC   0x1
-- 
1.9.1



[PATCH 07/12] ath10k: Add MSA handshake QMI mgs support

2018-03-25 Thread Govind Singh
HOST allocates 2mb of region for modem and WCN3990
secure access and provides the address and access
control to target for secure access.
Add MSA handshake request/response messages.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/qmi.c | 288 +-
 drivers/net/wireless/ath/ath10k/qmi.h |  14 ++
 2 files changed, 300 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/qmi.c 
b/drivers/net/wireless/ath/ath10k/qmi.c
index bc80b8f..763b812 100644
--- a/drivers/net/wireless/ath/ath10k/qmi.c
+++ b/drivers/net/wireless/ath/ath10k/qmi.c
@@ -26,6 +26,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include "qmi.h"
 #include "qmi_svc_v01.h"
 
@@ -35,6 +37,240 @@
 static struct ath10k_qmi *qmi;
 
 static int
+ath10k_qmi_map_msa_permissions(struct ath10k_msa_mem_region_info *mem_region)
+{
+   struct qcom_scm_vmperm dst_perms[3];
+   unsigned int src_perms;
+   phys_addr_t addr;
+   u32 perm_count;
+   u32 size;
+   int ret;
+
+   addr = mem_region->reg_addr;
+   size = mem_region->size;
+
+   src_perms = BIT(QCOM_SCM_VMID_HLOS);
+
+   dst_perms[0].vmid = QCOM_SCM_VMID_MSS_MSA;
+   dst_perms[0].perm = QCOM_SCM_PERM_RW;
+   dst_perms[1].vmid = QCOM_SCM_VMID_WLAN;
+   dst_perms[1].perm = QCOM_SCM_PERM_RW;
+
+   if (!mem_region->secure_flag) {
+   dst_perms[2].vmid = QCOM_SCM_VMID_WLAN_CE;
+   dst_perms[2].perm = QCOM_SCM_PERM_RW;
+   perm_count = 3;
+   } else {
+   dst_perms[2].vmid = 0;
+   dst_perms[2].perm = 0;
+   perm_count = 2;
+   }
+
+   ret = qcom_scm_assign_mem(addr, size, _perms,
+ dst_perms, perm_count);
+   if (ret < 0)
+   pr_err("msa map permission failed=%d\n", ret);
+
+   return ret;
+}
+
+static int
+ath10k_qmi_unmap_msa_permissions(struct ath10k_msa_mem_region_info *mem_region)
+{
+   struct qcom_scm_vmperm dst_perms;
+   unsigned int src_perms;
+   phys_addr_t addr;
+   u32 size;
+   int ret;
+
+   addr = mem_region->reg_addr;
+   size = mem_region->size;
+
+   src_perms = BIT(QCOM_SCM_VMID_MSS_MSA) | BIT(QCOM_SCM_VMID_WLAN);
+
+   if (!mem_region->secure_flag)
+   src_perms |= BIT(QCOM_SCM_VMID_WLAN_CE);
+
+   dst_perms.vmid = QCOM_SCM_VMID_HLOS;
+   dst_perms.perm = QCOM_SCM_PERM_RW;
+
+   ret = qcom_scm_assign_mem(addr, size, _perms, _perms, 1);
+   if (ret < 0)
+   pr_err("msa unmap permission failed=%d\n", ret);
+
+   return ret;
+}
+
+static int ath10k_qmi_setup_msa_permissions(struct ath10k_qmi *qmi)
+{
+   int ret;
+   int i;
+
+   for (i = 0; i < qmi->nr_mem_region; i++) {
+   ret = ath10k_qmi_map_msa_permissions(>mem_region[i]);
+   if (ret)
+   goto err_unmap;
+   }
+
+   return 0;
+
+err_unmap:
+   for (i--; i >= 0; i--)
+   ath10k_qmi_unmap_msa_permissions(>mem_region[i]);
+   return ret;
+}
+
+static void ath10k_qmi_remove_msa_permissions(struct ath10k_qmi *qmi)
+{
+   int i;
+
+   for (i = 0; i < qmi->nr_mem_region; i++)
+   ath10k_qmi_unmap_msa_permissions(>mem_region[i]);
+}
+
+static int
+   ath10k_qmi_msa_mem_info_send_sync_msg(struct ath10k_qmi *qmi)
+{
+   struct wlfw_msa_info_resp_msg_v01 *resp;
+   struct wlfw_msa_info_req_msg_v01 *req;
+   struct qmi_txn txn;
+   int ret;
+   int i;
+
+   req = kzalloc(sizeof(*req), GFP_KERNEL);
+   if (!req)
+   return -ENOMEM;
+
+   resp = kzalloc(sizeof(*resp), GFP_KERNEL);
+   if (!resp) {
+   kfree(req);
+   return -ENOMEM;
+   }
+
+   req->msa_addr = qmi->msa_pa;
+   req->size = qmi->msa_mem_size;
+
+   ret = qmi_txn_init(>qmi_hdl, ,
+  wlfw_msa_info_resp_msg_v01_ei, resp);
+   if (ret < 0) {
+   pr_err("fail to init txn for MSA mem info resp %d\n",
+  ret);
+   goto out;
+   }
+
+   ret = qmi_send_request(>qmi_hdl, NULL, ,
+  QMI_WLFW_MSA_INFO_REQ_V01,
+  WLFW_MSA_INFO_REQ_MSG_V01_MAX_MSG_LEN,
+  wlfw_msa_info_req_msg_v01_ei, req);
+   if (ret < 0) {
+   qmi_txn_cancel();
+   pr_err("fail to send MSA mem info req %d\n", ret);
+   goto out;
+   }
+
+   ret = qmi_txn_wait(, WLFW_TIMEOUT * HZ);
+   if (ret < 0)
+   goto out;
+
+   if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
+   pr_err("MSA mem info request rejected, result:%d error:%d\n",
+  resp->

[PATCH 05/12] ath10k: Add support of QMI indication message

2018-03-25 Thread Govind Singh
Add support of indication qmi message to communicate
with wlan qmi server. Indication message request
describes client capability and in response client
gets the state of wlan qmi service.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/qmi.c | 71 ++-
 1 file changed, 70 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/qmi.c 
b/drivers/net/wireless/ath/ath10k/qmi.c
index 3a7fcc6..bc80b8f 100644
--- a/drivers/net/wireless/ath/ath10k/qmi.c
+++ b/drivers/net/wireless/ath/ath10k/qmi.c
@@ -29,8 +29,76 @@
 #include "qmi.h"
 #include "qmi_svc_v01.h"
 
+#define WLFW_CLIENT_ID 0x4b4e454c
+#define WLFW_TIMEOUT   500
+
 static struct ath10k_qmi *qmi;
 
+static int
+ath10k_qmi_ind_register_send_sync_msg(struct ath10k_qmi *qmi)
+{
+   struct wlfw_ind_register_resp_msg_v01 *resp;
+   struct wlfw_ind_register_req_msg_v01 *req;
+   struct qmi_txn txn;
+   int ret;
+
+   req = kzalloc(sizeof(*req), GFP_KERNEL);
+   if (!req)
+   return -ENOMEM;
+
+   resp = kzalloc(sizeof(*resp), GFP_KERNEL);
+   if (!resp) {
+   kfree(req);
+   return -ENOMEM;
+   }
+
+   req->client_id_valid = 1;
+   req->client_id = WLFW_CLIENT_ID;
+   req->fw_ready_enable_valid = 1;
+   req->fw_ready_enable = 1;
+   req->msa_ready_enable_valid = 1;
+   req->msa_ready_enable = 1;
+
+   ret = qmi_txn_init(>qmi_hdl, ,
+  wlfw_ind_register_resp_msg_v01_ei, resp);
+   if (ret < 0) {
+   pr_err("fail to init txn for ind register resp %d\n",
+  ret);
+   goto out;
+   }
+
+   ret = qmi_send_request(>qmi_hdl, NULL, ,
+  QMI_WLFW_IND_REGISTER_REQ_V01,
+  WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN,
+  wlfw_ind_register_req_msg_v01_ei, req);
+   if (ret < 0) {
+   qmi_txn_cancel();
+   pr_err("fail to send ind register req %d\n", ret);
+   goto out;
+   }
+
+   ret = qmi_txn_wait(, WLFW_TIMEOUT * HZ);
+   if (ret < 0)
+   goto out;
+
+   if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
+   pr_err("qmi indication register request rejected:");
+   pr_err("resut:%d error:%d\n",
+  resp->resp.result, resp->resp.error);
+   ret = resp->resp.result;
+   }
+
+   pr_debug("indication register request completed\n");
+   kfree(resp);
+   kfree(req);
+   return 0;
+
+out:
+   kfree(resp);
+   kfree(req);
+   return ret;
+}
+
 static int ath10k_qmi_event_fw_ready_ind(struct ath10k_qmi *qmi)
 {
pr_debug("fw ready event received\n");
@@ -100,11 +168,12 @@ static void ath10k_qmi_event_server_arrive(struct 
work_struct *work)
  work_svc_arrive);
int ret;
 
+   pr_debug("wlan qmi server arrive\n");
ret = ath10k_qmi_connect_to_fw_server(qmi);
if (ret)
return;
 
-   pr_debug("qmi server arrive\n");
+   ath10k_qmi_ind_register_send_sync_msg(qmi);
 }
 
 static void ath10k_qmi_event_server_exit(struct work_struct *work)
-- 
1.9.1



[PATCH 02/12] dt: bindings: add bindings for ath10k qmi client

2018-03-25 Thread Govind Singh
Add device tree binding documentation details for ath10k
qmi client for SDM845/APQ8098 SoC into "qcom,ath10k.txt".

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt | 8 
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt 
b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
index 34e4f98..8076ae3 100644
--- a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
+++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
@@ -5,6 +5,7 @@ Required properties:
* "qcom,ath10k"
* "qcom,ipq4019-wifi"
* "qcom,wcn3990-wifi"
+   * "qcom,ath10k-qmi"
 
 PCI based devices uses compatible string "qcom,ath10k" and takes calibration
 data along with board specific data via "qcom,ath10k-calibration-data".
@@ -21,6 +22,8 @@ can be provided per device.
 
 SNOC based devices (i.e. wcn3990) uses compatible string "qcom,wcn3990-wifi".
 
+- qcom,wlan-msa-memory: MSA memory size
+
 Optional properties:
 - reg: Address and length of the register set for the device.
 - reg-names: Must include the list of following reg names,
@@ -150,3 +153,8 @@ qcom,wifi@1800 {
   <0 141 0 /* CE11 */ >;
vdd-0.8-cx-mx-supply = <_l5>;
 };
+
+qcom,ath10k-qmi {
+   compatible = "qcom,ath10k-qmi";
+   qcom,wlan-msa-memory = <0x10>;
+};
-- 
1.9.1



[PATCH 03/12] ath10k: Add ath10k QMI client driver

2018-03-25 Thread Govind Singh
Add QMI client driver for Q6 integrated WLAN connectivity
subsystem. This module is responsible for communicating WLAN
control messages to FW over QUALCOMM MSM Interface (QMI).

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/Kconfig  |   2 +-
 drivers/net/wireless/ath/ath10k/Makefile |   4 +
 drivers/net/wireless/ath/ath10k/qmi.c| 121 +++
 drivers/net/wireless/ath/ath10k/qmi.h|  24 ++
 4 files changed, 150 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/wireless/ath/ath10k/qmi.c
 create mode 100644 drivers/net/wireless/ath/ath10k/qmi.h

diff --git a/drivers/net/wireless/ath/ath10k/Kconfig 
b/drivers/net/wireless/ath/ath10k/Kconfig
index 84f071a..9978ad5e 100644
--- a/drivers/net/wireless/ath/ath10k/Kconfig
+++ b/drivers/net/wireless/ath/ath10k/Kconfig
@@ -42,7 +42,7 @@ config ATH10K_USB
 
 config ATH10K_SNOC
 tristate "Qualcomm ath10k SNOC support (EXPERIMENTAL)"
-depends on ATH10K && ARCH_QCOM
+depends on ATH10K && ARCH_QCOM && QCOM_QMI_HELPERS
 ---help---
   This module adds support for integrated WCN3990 chip connected
   to system NOC(SNOC). Currently work in progress and will not
diff --git a/drivers/net/wireless/ath/ath10k/Makefile 
b/drivers/net/wireless/ath/ath10k/Makefile
index 44d60a6..1730d1d 100644
--- a/drivers/net/wireless/ath/ath10k/Makefile
+++ b/drivers/net/wireless/ath/ath10k/Makefile
@@ -38,5 +38,9 @@ ath10k_usb-y += usb.o
 obj-$(CONFIG_ATH10K_SNOC) += ath10k_snoc.o
 ath10k_snoc-y += snoc.o
 
+obj-$(CONFIG_ATH10K_SNOC) += ath10k_qmi.o
+ath10k_qmi-y += qmi.o \
+   qmi_svc_v01.o
+
 # for tracing framework to find trace.h
 CFLAGS_trace.o := -I$(src)
diff --git a/drivers/net/wireless/ath/ath10k/qmi.c 
b/drivers/net/wireless/ath/ath10k/qmi.c
new file mode 100644
index 000..2235182
--- /dev/null
+++ b/drivers/net/wireless/ath/ath10k/qmi.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "qmi.h"
+#include "qmi_svc_v01.h"
+
+static struct ath10k_qmi *qmi;
+
+static int ath10k_qmi_new_server(struct qmi_handle *qmi_hdl,
+struct qmi_service *service)
+{
+   return 0;
+}
+
+static void ath10k_qmi_del_server(struct qmi_handle *qmi_hdl,
+ struct qmi_service *service)
+{
+}
+
+static struct qmi_ops ath10k_qmi_ops = {
+   .new_server = ath10k_qmi_new_server,
+   .del_server = ath10k_qmi_del_server,
+};
+
+static int ath10k_qmi_probe(struct platform_device *pdev)
+{
+   int ret;
+
+   qmi = devm_kzalloc(>dev, sizeof(*qmi),
+  GFP_KERNEL);
+   if (!qmi)
+   return -ENOMEM;
+
+   qmi->pdev = pdev;
+   platform_set_drvdata(pdev, qmi);
+   ret = qmi_handle_init(>qmi_hdl,
+ WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN,
+ _qmi_ops, NULL);
+   if (ret < 0)
+   goto err;
+
+   ret = qmi_add_lookup(>qmi_hdl, WLFW_SERVICE_ID_V01,
+WLFW_SERVICE_VERS_V01, 0);
+   if (ret < 0)
+   goto err;
+
+   pr_debug("qmi client driver probed successfully\n");
+
+   return 0;
+
+err:
+   return ret;
+}
+
+static int ath10k_qmi_remove(struct platform_device *pdev)
+{
+   struct ath10k_qmi *qmi = platform_get_drvdata(pdev);
+
+   qmi_handle_release(>qmi_hdl);
+
+   return 0;
+}
+
+static const struct of_device_id ath10k_qmi_dt_match[] = {
+   {.compatible = "qcom,ath10k-qmi"},
+   {}
+};
+
+MODULE_DEVICE_TABLE(of, ath10k_qmi_dt_match);
+
+static struct platform_driver ath10k_qmi_clinet = {
+   .probe  = ath10k_qmi_probe,
+   .remove = ath10k_qmi_remove,
+   .driver = {
+   .name = "ath10k QMI client",
+   .owner = THIS_MODULE,
+   .of_match_table = ath10k_qmi_dt_match,
+   },
+};
+
+static int __init ath

[PATCH 04/12] ath10k: add support to start and stop qmi service

2018-03-25 Thread Govind Singh
Add support to start qmi service to configure the wlan
firmware component and register event notifier to communicate
with the WLAN firmware over qmi communication interface.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/qmi.c | 155 --
 drivers/net/wireless/ath/ath10k/qmi.h |  13 +++
 2 files changed, 160 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/qmi.c 
b/drivers/net/wireless/ath/ath10k/qmi.c
index 2235182..3a7fcc6 100644
--- a/drivers/net/wireless/ath/ath10k/qmi.c
+++ b/drivers/net/wireless/ath/ath10k/qmi.c
@@ -31,15 +31,115 @@
 
 static struct ath10k_qmi *qmi;
 
+static int ath10k_qmi_event_fw_ready_ind(struct ath10k_qmi *qmi)
+{
+   pr_debug("fw ready event received\n");
+   spin_lock(>event_lock);
+   qmi->fw_ready = true;
+   spin_unlock(>event_lock);
+
+   return 0;
+}
+
+static void ath10k_qmi_fw_ready_ind(struct qmi_handle *qmi_hdl,
+   struct sockaddr_qrtr *sq,
+   struct qmi_txn *txn, const void *data)
+{
+   struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, 
qmi_hdl);
+
+   ath10k_qmi_event_fw_ready_ind(qmi);
+}
+
+static void ath10k_qmi_msa_ready_ind(struct qmi_handle *qmi_hdl,
+struct sockaddr_qrtr *sq,
+struct qmi_txn *txn, const void *data)
+{
+   struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, 
qmi_hdl);
+
+   qmi->msa_ready = true;
+}
+
+static struct qmi_msg_handler qmi_msg_handler[] = {
+   {
+   .type = QMI_INDICATION,
+   .msg_id = QMI_WLFW_FW_READY_IND_V01,
+   .ei = wlfw_fw_ready_ind_msg_v01_ei,
+   .decoded_size = sizeof(struct wlfw_fw_ready_ind_msg_v01),
+   .fn = ath10k_qmi_fw_ready_ind,
+   },
+   {
+   .type = QMI_INDICATION,
+   .msg_id = QMI_WLFW_MSA_READY_IND_V01,
+   .ei = wlfw_msa_ready_ind_msg_v01_ei,
+   .decoded_size = sizeof(struct wlfw_msa_ready_ind_msg_v01),
+   .fn = ath10k_qmi_msa_ready_ind,
+   },
+   {}
+};
+
+static int ath10k_qmi_connect_to_fw_server(struct ath10k_qmi *qmi)
+{
+   struct qmi_handle *qmi_hdl = >qmi_hdl;
+   int ret;
+
+   ret = kernel_connect(qmi_hdl->sock, (struct sockaddr *)>sq,
+sizeof(qmi->sq), 0);
+   if (ret) {
+   pr_err("fail to connect to remote service port\n");
+   return ret;
+   }
+
+   pr_info("wlan qmi service connected\n");
+
+   return 0;
+}
+
+static void ath10k_qmi_event_server_arrive(struct work_struct *work)
+{
+   struct ath10k_qmi *qmi = container_of(work, struct ath10k_qmi,
+ work_svc_arrive);
+   int ret;
+
+   ret = ath10k_qmi_connect_to_fw_server(qmi);
+   if (ret)
+   return;
+
+   pr_debug("qmi server arrive\n");
+}
+
+static void ath10k_qmi_event_server_exit(struct work_struct *work)
+{
+   struct ath10k_qmi *qmi = container_of(work, struct ath10k_qmi,
+ work_svc_exit);
+
+   spin_lock(>event_lock);
+   qmi->fw_ready = false;
+   spin_unlock(>event_lock);
+   pr_info("wlan fw service disconnected\n");
+}
+
 static int ath10k_qmi_new_server(struct qmi_handle *qmi_hdl,
 struct qmi_service *service)
 {
+   struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, 
qmi_hdl);
+   struct sockaddr_qrtr *sq = >sq;
+
+   sq->sq_family = AF_QIPCRTR;
+   sq->sq_node = service->node;
+   sq->sq_port = service->port;
+
+   queue_work(qmi->event_wq, >work_svc_arrive);
+
return 0;
 }
 
 static void ath10k_qmi_del_server(struct qmi_handle *qmi_hdl,
  struct qmi_service *service)
 {
+   struct ath10k_qmi *qmi =
+   container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl);
+
+   queue_work(qmi->event_wq, >work_svc_exit);
 }
 
 static struct qmi_ops ath10k_qmi_ops = {
@@ -47,6 +147,51 @@ static void ath10k_qmi_del_server(struct qmi_handle 
*qmi_hdl,
.del_server = ath10k_qmi_del_server,
 };
 
+static int ath10k_alloc_qmi_resources(struct ath10k_qmi *qmi)
+{
+   int ret;
+
+   ret = qmi_handle_init(>qmi_hdl,
+ WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN,
+ _qmi_ops, qmi_msg_handler);
+   if (ret)
+   goto err;
+
+   qmi->event_wq = alloc_workqueue("qmi_driver_event",
+   WQ_UNBOUND, 1);
+   if (!qmi->event_wq) {
+   pr_err("workqueue alloc failed\n");
+   

[PATCH 01/12] ath10k: Add qmi service for wlan qmi client

2018-03-25 Thread Govind Singh
WLAN qmi server running in Q6 dsp exposes host
to target cold boot qmi handshake.
Add WLAN QMI service helpers for WLAN serivice.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/qmi_svc_v01.c | 2323 +
 drivers/net/wireless/ath/ath10k/qmi_svc_v01.h |  685 
 2 files changed, 3008 insertions(+)
 create mode 100644 drivers/net/wireless/ath/ath10k/qmi_svc_v01.c
 create mode 100644 drivers/net/wireless/ath/ath10k/qmi_svc_v01.h

diff --git a/drivers/net/wireless/ath/ath10k/qmi_svc_v01.c 
b/drivers/net/wireless/ath/ath10k/qmi_svc_v01.c
new file mode 100644
index 000..5857c0c
--- /dev/null
+++ b/drivers/net/wireless/ath/ath10k/qmi_svc_v01.c
@@ -0,0 +1,2323 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "qmi_svc_v01.h"
+
+static struct qmi_elem_info wlfw_ce_tgt_pipe_cfg_s_v01_ei[] = {
+   {
+   .data_type  = QMI_UNSIGNED_4_BYTE,
+   .elem_len   = 1,
+   .elem_size  = sizeof(u32),
+   .array_type = NO_ARRAY,
+   .tlv_type   = 0,
+   .offset = offsetof(struct wlfw_ce_tgt_pipe_cfg_s_v01,
+  pipe_num),
+   },
+   {
+   .data_type  = QMI_SIGNED_4_BYTE_ENUM,
+   .elem_len   = 1,
+   .elem_size  = sizeof(enum wlfw_pipedir_enum_v01),
+   .array_type = NO_ARRAY,
+   .tlv_type   = 0,
+   .offset = offsetof(struct wlfw_ce_tgt_pipe_cfg_s_v01,
+  pipe_dir),
+   },
+   {
+   .data_type  = QMI_UNSIGNED_4_BYTE,
+   .elem_len   = 1,
+   .elem_size  = sizeof(u32),
+   .array_type = NO_ARRAY,
+   .tlv_type   = 0,
+   .offset = offsetof(struct wlfw_ce_tgt_pipe_cfg_s_v01,
+  nentries),
+   },
+   {
+   .data_type  = QMI_UNSIGNED_4_BYTE,
+   .elem_len   = 1,
+   .elem_size  = sizeof(u32),
+   .array_type = NO_ARRAY,
+   .tlv_type   = 0,
+   .offset = offsetof(struct wlfw_ce_tgt_pipe_cfg_s_v01,
+  nbytes_max),
+   },
+   {
+   .data_type  = QMI_UNSIGNED_4_BYTE,
+   .elem_len   = 1,
+   .elem_size  = sizeof(u32),
+   .array_type = NO_ARRAY,
+   .tlv_type   = 0,
+   .offset = offsetof(struct wlfw_ce_tgt_pipe_cfg_s_v01,
+  flags),
+   },
+   {
+   .data_type  = QMI_EOTI,
+   .array_type = NO_ARRAY,
+   .tlv_type   = QMI_COMMON_TLV_TYPE,
+   },
+};
+
+static struct qmi_elem_info wlfw_ce_svc_pipe_cfg_s_v01_ei[] = {
+   {
+   .data_type  = QMI_UNSIGNED_4_BYTE,
+   .elem_len   = 1,
+   .elem_size  = sizeof(u32),
+   .array_type = NO_ARRAY,
+   .tlv_type   = 0,
+   .offset = offsetof(struct wlfw_ce_svc_pipe_cfg_s_v01,
+  service_id),
+   },
+   {
+   .data_type  = QMI_SIGNED_4_BYTE_ENUM,
+   .elem_len   = 1,
+   .elem_size  = sizeof(enum wlfw_pipedir_enum_v01),
+   .array_type = NO_ARRAY,
+   .tlv_type   = 0,
+   .offset = offsetof(struct wlfw_ce_svc_pipe_cfg_s_v01,
+  pipe_dir),
+   },
+   {
+   .data_type  = QMI_UNSIGNED_4_BYTE,
+   .elem_len   = 1,
+   .elem_size  = sizeof(u32),
+   .array_type = NO_ARRAY,
+   .tlv_type   = 0,
+   .offset = offsetof(struct wlfw_ce_svc_pipe_cfg_s_v01,
+

[PATCH v3 00/12] *** Add support for wifi QMI client driver ***

2018-03-25 Thread Govind Singh
Add QMI client driver for Q6 integrated WLAN connectivity subsystem.
This module is responsible for communicating WLAN control messages to FW
over QMI interface.

“QUALCOMM Messaging Interface”(QMI) provides the control interface between
components running b/w remote processors with underlying transport layer
based on integrated chipset(shared memory) or discrete 
chipset(PCI/USB/SDIO/UART).

QMI client driver implementation is based on qmi frmework 
https://lwn.net/Articles/729924/.

Below is the sequence of qmi handshake.

   QMI CLIENT(APPS) QMI SERVER(FW 
in Q6)

 <--wlan service discoverd

   -connect to wlam qmi service->

   wlan info request->

   <wlan info resp

   msa info req>

 <msa info resp

 msa ready req>

 <msa ready resp

 <msa ready indication---

 capability req--->

<capability resp

qmi bdf req->

 <qmi bdf resp

  qmi cal trigger--->

  <---- QMI FW ready indication---

Govind Singh (12):
  ath10k: Add qmi service for wlan qmi client
  dt: bindings: add bindings for ath10k qmi client
  ath10k: Add WCN3990 QMI client driver
  ath10k: add support to start and stop qmi service
  ath10k: Add support of QMI indication message
  firmware: qcom: scm: Add WLAN VMID for Qualcomm SCM interface
  ath10k: Add MSA handshake QMI mgs support
  ath10k: Add QMI CAP request support
  ath10k: Add QMI HOST CAP request support
  ath10k: add bdf/cal indication support
  ath10k: Add wlan mode on/off qmi message
  ath10k: Add qmi wlan enable/disable support for WCN3990

 .../bindings/net/wireless/qcom,ath10k.txt  |8 +
 drivers/net/wireless/ath/ath10k/Makefile   |4 +
 drivers/net/wireless/ath/ath10k/qmi.c  | 1188 ++
 drivers/net/wireless/ath/ath10k/qmi.h  |  102 +
 drivers/net/wireless/ath/ath10k/qmi_svc_v01.c  | 2323 
 drivers/net/wireless/ath/ath10k/qmi_svc_v01.h  |  685 ++
 drivers/net/wireless/ath/ath10k/snoc.c |  179 +-
 include/linux/qcom_scm.h   |4 +-
 8 files changed, 4491 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath10k/qmi.c
 create mode 100644 drivers/net/wireless/ath/ath10k/qmi.h
 create mode 100644 drivers/net/wireless/ath/ath10k/qmi_svc_v01.c
 create mode 100644 drivers/net/wireless/ath/ath10k/qmi_svc_v01.h

-- 
1.9.1



[PATCH v2 08/13] ath10k: Add hif rx methods for wcn3990

2018-03-22 Thread Govind Singh
Add hif rx methods in rx path for wcn3990
target.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/snoc.c | 171 +
 1 file changed, 153 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/snoc.c 
b/drivers/net/wireless/ath/ath10k/snoc.c
index 899f0a3..6d9ccce 100644
--- a/drivers/net/wireless/ath/ath10k/snoc.c
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -26,6 +26,7 @@
 #include 
 #define  WCN3990_CE_ATTR_FLAGS 0
 #define ATH10K_SNOC_RX_POST_RETRY_MS 50
+#define CE_POLL_PIPE 4
 
 static char *const ce_name[] = {
"WLAN_CE_0",
@@ -44,6 +45,9 @@
 
 static void ath10k_snoc_htc_tx_cb(struct ath10k_ce_pipe *ce_state);
 static void ath10k_snoc_htt_tx_cb(struct ath10k_ce_pipe *ce_state);
+static void ath10k_snoc_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
+static void ath10k_snoc_htt_rx_cb(struct ath10k_ce_pipe *ce_state);
+static void ath10k_snoc_htt_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
 
 static const struct ath10k_snoc_drv_priv drv_priv = {
.hw_rev = ATH10K_HW_WCN3990,
@@ -53,7 +57,7 @@
 static struct ce_attr host_ce_config_wlan[] = {
/* CE0: host->target HTC control streams */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 16,
.src_sz_max = 2048,
.dest_nentries = 0,
@@ -62,25 +66,25 @@
 
/* CE1: target->host HTT + HTC control */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
.dest_nentries = 512,
-   .recv_cb = NULL,
+   .recv_cb = ath10k_snoc_htt_htc_rx_cb,
},
 
/* CE2: target->host WMI */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
.dest_nentries = 64,
-   .recv_cb = NULL,
+   .recv_cb = ath10k_snoc_htc_rx_cb,
},
 
/* CE3: host->target WMI */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 32,
.src_sz_max = 2048,
.dest_nentries = 0,
@@ -89,7 +93,7 @@
 
/* CE4: host->target HTT */
{
-   .flags = WCN3990_CE_ATTR_FLAGS | CE_ATTR_DIS_INTR,
+   .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR,
.src_nentries = 256,
.src_sz_max = 256,
.dest_nentries = 0,
@@ -98,16 +102,16 @@
 
/* CE5: target->host HTT (ipa_uc->target ) */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 512,
.dest_nentries = 512,
-   .recv_cb = NULL,
+   .recv_cb = ath10k_snoc_htt_rx_cb,
},
 
/* CE6: target autonomous hif_memcpy */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 0,
.dest_nentries = 0,
@@ -115,7 +119,7 @@
 
/* CE7: ce_diag, the Diagnostic Window */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 2,
.src_sz_max = 2048,
.dest_nentries = 2,
@@ -123,7 +127,7 @@
 
/* CE8: Target to uMC */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
.dest_nentries = 128,
@@ -131,29 +135,29 @@
 
/* CE9 target->host HTT */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
.dest_nentries = 512,
-   .recv_cb = NULL,
+   .recv_cb = ath10k_snoc_htt_htc_rx_cb,
},
 
/* CE10: target->host HTT */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
.dest_nentries = 512,
-   .recv_cb = NULL,
+   .recv_cb = ath10k_snoc_htt_htc_rx_cb,
},
 
/* CE11: target -> host PKTLOG */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
.dest_nentries = 512,
-   .recv_cb = NULL,
+   .recv_cb = ath10k_snoc_htt_htc_rx_cb,
},
 };
 
@@ -362,6 +366,82 @@ sta

[PATCH v2 03/13] ath10k: Add hif start/stop methods for wcn3990 snoc layer

2018-03-22 Thread Govind Singh
Add hif start/stop callback for allocating/freeing buffers
on tx/rx pipe and enabling/disabling the tx/rx pipe
interrupts.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/snoc.c | 189 -
 1 file changed, 187 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/snoc.c 
b/drivers/net/wireless/ath/ath10k/snoc.c
index 575355c..dcd8bb7 100644
--- a/drivers/net/wireless/ath/ath10k/snoc.c
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #define  WCN3990_CE_ATTR_FLAGS 0
+#define ATH10K_SNOC_RX_POST_RETRY_MS 50
 
 static char *const ce_name[] = {
"WLAN_CE_0",
@@ -170,9 +171,193 @@ u32 ath10k_snoc_read32(struct ath10k *ar, u32 offset)
return val;
 }
 
+static int __ath10k_snoc_rx_post_buf(struct ath10k_snoc_pipe *pipe)
+{
+   struct ath10k_ce_pipe *ce_pipe = pipe->ce_hdl;
+   struct ath10k *ar = pipe->hif_ce_state;
+   struct ath10k_ce *ce = ath10k_ce_priv(ar);
+   struct sk_buff *skb;
+   dma_addr_t paddr;
+   int ret;
+
+   skb = dev_alloc_skb(pipe->buf_sz);
+   if (!skb)
+   return -ENOMEM;
+
+   WARN_ONCE((unsigned long)skb->data & 3, "unaligned skb");
+
+   paddr = dma_map_single(ar->dev, skb->data,
+  skb->len + skb_tailroom(skb),
+  DMA_FROM_DEVICE);
+   if (unlikely(dma_mapping_error(ar->dev, paddr))) {
+   ath10k_warn(ar, "failed to dma map snoc rx buf\n");
+   dev_kfree_skb_any(skb);
+   return -EIO;
+   }
+
+   ATH10K_SKB_RXCB(skb)->paddr = paddr;
+
+   spin_lock_bh(>ce_lock);
+   ret = ce_pipe->ops->ce_rx_post_buf(ce_pipe, skb, paddr);
+   spin_unlock_bh(>ce_lock);
+   if (ret) {
+   dma_unmap_single(ar->dev, paddr, skb->len + skb_tailroom(skb),
+DMA_FROM_DEVICE);
+   dev_kfree_skb_any(skb);
+   return ret;
+   }
+
+   return 0;
+}
+
+static void ath10k_snoc_rx_post_pipe(struct ath10k_snoc_pipe *pipe)
+{
+   struct ath10k *ar = pipe->hif_ce_state;
+   struct ath10k_ce *ce = ath10k_ce_priv(ar);
+   struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+   struct ath10k_ce_pipe *ce_pipe = pipe->ce_hdl;
+   int ret, num;
+
+   if (pipe->buf_sz == 0)
+   return;
+
+   if (!ce_pipe->dest_ring)
+   return;
+
+   spin_lock_bh(>ce_lock);
+   num = __ath10k_ce_rx_num_free_bufs(ce_pipe);
+   spin_unlock_bh(>ce_lock);
+   while (num--) {
+   ret = __ath10k_snoc_rx_post_buf(pipe);
+   if (ret) {
+   if (ret == -ENOSPC)
+   break;
+   ath10k_warn(ar, "failed to post rx buf: %d\n", ret);
+   mod_timer(_snoc->rx_post_retry, jiffies +
+ ATH10K_SNOC_RX_POST_RETRY_MS);
+   break;
+   }
+   }
+}
+
+static void ath10k_snoc_rx_post(struct ath10k *ar)
+{
+   struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+   int i;
+
+   for (i = 0; i < CE_COUNT; i++)
+   ath10k_snoc_rx_post_pipe(_snoc->pipe_info[i]);
+}
+
+static inline void ath10k_snoc_irq_disable(struct ath10k *ar)
+{
+   ath10k_ce_disable_interrupts(ar);
+}
+
+static inline void ath10k_snoc_irq_enable(struct ath10k *ar)
+{
+   ath10k_ce_enable_interrupts(ar);
+}
+
+static void ath10k_snoc_rx_pipe_cleanup(struct ath10k_snoc_pipe *snoc_pipe)
+{
+   struct ath10k_ce_pipe *ce_pipe;
+   struct ath10k_ce_ring *ce_ring;
+   struct sk_buff *skb;
+   struct ath10k *ar;
+   int i;
+
+   ar = snoc_pipe->hif_ce_state;
+   ce_pipe = snoc_pipe->ce_hdl;
+   ce_ring = ce_pipe->dest_ring;
+
+   if (!ce_ring)
+   return;
+
+   if (!snoc_pipe->buf_sz)
+   return;
+
+   for (i = 0; i < ce_ring->nentries; i++) {
+   skb = ce_ring->per_transfer_context[i];
+   if (!skb)
+   continue;
+
+   ce_ring->per_transfer_context[i] = NULL;
+
+   dma_unmap_single(ar->dev, ATH10K_SKB_RXCB(skb)->paddr,
+skb->len + skb_tailroom(skb),
+DMA_FROM_DEVICE);
+   dev_kfree_skb_any(skb);
+   }
+}
+
+static void ath10k_snoc_tx_pipe_cleanup(struct ath10k_snoc_pipe *snoc_pipe)
+{
+   struct ath10k_ce_pipe *ce_pipe;
+   struct ath10k_ce_ring *ce_ring;
+   struct ath10k_snoc *ar_snoc;
+   struct sk_buff *skb;
+   struct ath10k *ar;
+   int i;
+
+   ar = snoc_pipe->hif_ce_state;
+   ar_snoc = ath10k_snoc_priv(ar);
+   ce_pipe = snoc_pipe->ce_hdl

[PATCH v2 00/13] ***Set4: Add support of WCN3990 bus layer support ***

2018-03-22 Thread Govind Singh
This change adds support for integrated wcn3990 chipset on
MSM platforms. WCN3990 is 2x2 802.11ac chipset where wlan
subsystem is interfaced over system interconnect.
Wlan fw runs in Q6 DSP. WCN3990 chipset uses 12 copy engine
for host to target and target to host communication. It has
extra 2 copy engine in rx data path and packet log capability
is exposed via new HTC service over dedicated copy engine.
Each CE has dedicated interrupt of rx path and tx completion.

[CE0] :host->target control and raw streams
[CE1] :target->host HTT
[CE2] :target->host WMI
[CE3] :host->target WMI
[CE4] :host->target HTT
[CE5] :reserved
[CE6] :Target autonomous HIF_memcpy
[CE7] :reserved
[CE8] :reserved
[CE9] :target->host HTT
[CE10] :target->host HTT
[CE11] :target -> host PKTLOG

Changes in V2:
Rebased the set on top of https://patchwork.kernel.org/patch/10298657/.
Removed qcom,-config and minor clean up in dt binding documentation.

Govind Singh (11):
  ath10k: platform driver for WCN3990 SNOC WLAN module
  ath10k: add resource init and deinit for WCN3990
  ath10k: Add hif start/stop methods for wcn3990 snoc layer
  ath10k: Add HTC services for WCN3990
  ath10k: Map HTC services to tx/rx pipes for wcn3990
  ath10k: Add hif power-up/power-down methods
  ath10k: Add hif tx methods for wcn3990
  ath10k: Add hif rx methods for wcn3990
  ath10k: Modify hif tx paddr to dma_addr_t type
  ath10k: Vote for hardware resources for WCN3990
  dt: bindings: add bindings for wcn3990 wifi block

Rakesh Pillai (2):
  ath10k: Add support to get target info from hif ops
  ath10k: Check all CE for data if irq summary is not retained

 .../bindings/net/wireless/qcom,ath10k.txt  |   31 +
 drivers/net/wireless/ath/ath10k/Kconfig|8 +
 drivers/net/wireless/ath/ath10k/Makefile   |3 +
 drivers/net/wireless/ath/ath10k/ce.h   |   10 +-
 drivers/net/wireless/ath/ath10k/core.c |   21 +
 drivers/net/wireless/ath/ath10k/hif.h  |   15 +-
 drivers/net/wireless/ath/ath10k/htc.c  |6 +
 drivers/net/wireless/ath/ath10k/htc.h  |4 +
 drivers/net/wireless/ath/ath10k/hw.h   |3 +
 drivers/net/wireless/ath/ath10k/pci.c  |8 +-
 drivers/net/wireless/ath/ath10k/snoc.c | 1411 
 drivers/net/wireless/ath/ath10k/snoc.h |   95 ++
 12 files changed, 1607 insertions(+), 8 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath10k/snoc.c
 create mode 100644 drivers/net/wireless/ath/ath10k/snoc.h

-- 
1.9.1



[PATCH v2 07/13] ath10k: Add hif tx methods for wcn3990

2018-03-22 Thread Govind Singh
Add hif tx/tx-complete methods for wcn3990
target.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/snoc.c | 123 -
 1 file changed, 120 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/snoc.c 
b/drivers/net/wireless/ath/ath10k/snoc.c
index 9d402e4..899f0a3 100644
--- a/drivers/net/wireless/ath/ath10k/snoc.c
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -42,6 +42,9 @@
"WLAN_CE_11",
 };
 
+static void ath10k_snoc_htc_tx_cb(struct ath10k_ce_pipe *ce_state);
+static void ath10k_snoc_htt_tx_cb(struct ath10k_ce_pipe *ce_state);
+
 static const struct ath10k_snoc_drv_priv drv_priv = {
.hw_rev = ATH10K_HW_WCN3990,
.dma_mask = DMA_BIT_MASK(37),
@@ -54,7 +57,7 @@
.src_nentries = 16,
.src_sz_max = 2048,
.dest_nentries = 0,
-   .send_cb = NULL,
+   .send_cb = ath10k_snoc_htc_tx_cb,
},
 
/* CE1: target->host HTT + HTC control */
@@ -81,7 +84,7 @@
.src_nentries = 32,
.src_sz_max = 2048,
.dest_nentries = 0,
-   .send_cb = NULL,
+   .send_cb = ath10k_snoc_htc_tx_cb,
},
 
/* CE4: host->target HTT */
@@ -90,7 +93,7 @@
.src_nentries = 256,
.src_sz_max = 256,
.dest_nentries = 0,
-   .send_cb = NULL,
+   .send_cb = ath10k_snoc_htt_tx_cb,
},
 
/* CE5: target->host HTT (ipa_uc->target ) */
@@ -359,6 +362,117 @@ static void ath10k_snoc_rx_post(struct ath10k *ar)
ath10k_snoc_rx_post_pipe(_snoc->pipe_info[i]);
 }
 
+static void ath10k_snoc_htc_tx_cb(struct ath10k_ce_pipe *ce_state)
+{
+   struct ath10k *ar = ce_state->ar;
+   struct sk_buff_head list;
+   struct sk_buff *skb;
+
+   __skb_queue_head_init();
+   while (ath10k_ce_completed_send_next(ce_state, (void **)) == 0) {
+   if (!skb)
+   continue;
+
+   __skb_queue_tail(, skb);
+   }
+
+   while ((skb = __skb_dequeue()))
+   ath10k_htc_tx_completion_handler(ar, skb);
+}
+
+static void ath10k_snoc_htt_tx_cb(struct ath10k_ce_pipe *ce_state)
+{
+   struct ath10k *ar = ce_state->ar;
+   struct sk_buff *skb;
+
+   while (ath10k_ce_completed_send_next(ce_state, (void **)) == 0) {
+   if (!skb)
+   continue;
+
+   dma_unmap_single(ar->dev, ATH10K_SKB_CB(skb)->paddr,
+skb->len, DMA_TO_DEVICE);
+   ath10k_htt_hif_tx_complete(ar, skb);
+   }
+}
+
+static int ath10k_snoc_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
+struct ath10k_hif_sg_item *items, int n_items)
+{
+   struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+   struct ath10k_ce *ce = ath10k_ce_priv(ar);
+   struct ath10k_snoc_pipe *snoc_pipe;
+   struct ath10k_ce_pipe *ce_pipe;
+   int err, i = 0;
+
+   snoc_pipe = _snoc->pipe_info[pipe_id];
+   ce_pipe = snoc_pipe->ce_hdl;
+   spin_lock_bh(>ce_lock);
+
+   for (i = 0; i < n_items - 1; i++) {
+   ath10k_dbg(ar, ATH10K_DBG_SNOC,
+  "snoc tx item %d paddr %pad len %d n_items %d\n",
+  i, [i].paddr, items[i].len, n_items);
+
+   err = ath10k_ce_send_nolock(ce_pipe,
+   items[i].transfer_context,
+   items[i].paddr,
+   items[i].len,
+   items[i].transfer_id,
+   CE_SEND_FLAG_GATHER);
+   if (err)
+   goto err;
+   }
+
+   ath10k_dbg(ar, ATH10K_DBG_SNOC,
+  "snoc tx item %d paddr %pad len %d n_items %d\n",
+  i, [i].paddr, items[i].len, n_items);
+
+   err = ath10k_ce_send_nolock(ce_pipe,
+   items[i].transfer_context,
+   items[i].paddr,
+   items[i].len,
+   items[i].transfer_id,
+   0);
+   if (err)
+   goto err;
+
+   spin_unlock_bh(>ce_lock);
+
+   return 0;
+
+err:
+   for (; i > 0; i--)
+   __ath10k_ce_send_revert(ce_pipe);
+
+   spin_unlock_bh(>ce_lock);
+   return err;
+}
+
+static u16 ath10k_snoc_hif_get_free_queue_number(struct ath10k *ar, u8 pipe)
+{
+   struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+
+   ath10k_dbg(ar, ATH10K_DBG_SNOC, "hif get free queue number\n");
+
+   return ath10k_ce_num_free_src_entries(ar_snoc->pipe_

[PATCH v2 13/13] dt: bindings: add bindings for wcn3990 wifi block

2018-03-22 Thread Govind Singh
Add device tree binding documentation details for wcn3990
wifi block present in Qualcomm SDM845/APQ8098 SoC into
"qcom,ath10k.txt".

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 .../bindings/net/wireless/qcom,ath10k.txt  | 31 ++
 1 file changed, 31 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt 
b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
index 3d2a031..34e4f98 100644
--- a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
+++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
@@ -4,6 +4,7 @@ Required properties:
 - compatible: Should be one of the following:
* "qcom,ath10k"
* "qcom,ipq4019-wifi"
+   * "qcom,wcn3990-wifi"
 
 PCI based devices uses compatible string "qcom,ath10k" and takes calibration
 data along with board specific data via "qcom,ath10k-calibration-data".
@@ -18,8 +19,12 @@ In general, entry "qcom,ath10k-pre-calibration-data" and
 "qcom,ath10k-calibration-data" conflict with each other and only one
 can be provided per device.
 
+SNOC based devices (i.e. wcn3990) uses compatible string "qcom,wcn3990-wifi".
+
 Optional properties:
 - reg: Address and length of the register set for the device.
+- reg-names: Must include the list of following reg names,
+"membase"
 - resets: Must contain an entry for each entry in reset-names.
   See ../reset/reseti.txt for details.
 - reset-names: Must include the list of following reset names,
@@ -49,6 +54,8 @@ Optional properties:
 hw versions.
 - qcom,ath10k-pre-calibration-data : pre calibration data as an array,
 the length can vary between hw versions.
+- -supply: handle to the regulator device tree node
+  optional "supply-name" is "vdd-0.8-cx-mx".
 
 Example (to supply the calibration data alone):
 
@@ -119,3 +126,27 @@ wifi0: wifi@a00 {
qcom,msi_base = <0x40>;
qcom,ath10k-pre-calibration-data = [ 01 02 03 ... ];
 };
+
+Example (to supply wcn3990 SoC wifi block details):
+
+qcom,wifi@1800 {
+   compatible = "qcom,wcn3990-wifi";
+   reg = <0x1880 0x80>;
+   reg-names = "membase";
+   clocks = <_gcc clk_aggre2_noc_clk>;
+   clock-names = "smmu_aggre2_noc_clk"
+   interrupts =
+  <0 130 0 /* CE0 */ >,
+  <0 131 0 /* CE1 */ >,
+  <0 132 0 /* CE2 */ >,
+  <0 133 0 /* CE3 */ >,
+  <0 134 0 /* CE4 */ >,
+  <0 135 0 /* CE5 */ >,
+  <0 136 0 /* CE6 */ >,
+  <0 137 0 /* CE7 */ >,
+  <0 138 0 /* CE8 */ >,
+  <0 139 0 /* CE9 */ >,
+  <0 140 0 /* CE10 */ >,
+  <0 141 0 /* CE11 */ >;
+   vdd-0.8-cx-mx-supply = <_l5>;
+};
-- 
1.9.1



[PATCH v2 06/13] ath10k: Add hif power-up/power-down methods

2018-03-22 Thread Govind Singh
Add hif power-up/power-down methods for wcn3990
target.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/snoc.c | 61 ++
 1 file changed, 61 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/snoc.c 
b/drivers/net/wireless/ath/ath10k/snoc.c
index a39eee7..9d402e4 100644
--- a/drivers/net/wireless/ath/ath10k/snoc.c
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -519,6 +519,65 @@ static int ath10k_snoc_hif_start(struct ath10k *ar)
return 0;
 }
 
+static int ath10k_snoc_init_pipes(struct ath10k *ar)
+{
+   int i, ret;
+
+   for (i = 0; i < CE_COUNT; i++) {
+   ret = ath10k_ce_init_pipe(ar, i, _ce_config_wlan[i]);
+   if (ret) {
+   ath10k_err(ar, "failed to initialize copy engine pipe 
%d: %d\n",
+  i, ret);
+   return ret;
+   }
+   }
+
+   return 0;
+}
+
+static int ath10k_snoc_wlan_enable(struct ath10k *ar)
+{
+   return 0;
+}
+
+static void ath10k_snoc_wlan_disable(struct ath10k *ar)
+{
+}
+
+static void ath10k_snoc_hif_power_down(struct ath10k *ar)
+{
+   ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power down\n");
+
+   ath10k_snoc_wlan_disable(ar);
+}
+
+static int ath10k_snoc_hif_power_up(struct ath10k *ar)
+{
+   int ret;
+
+   ath10k_dbg(ar, ATH10K_DBG_SNOC, "%s:WCN3990 driver state = %d\n",
+  __func__, ar->state);
+
+   ret = ath10k_snoc_wlan_enable(ar);
+   if (ret) {
+   ath10k_err(ar, "failed to enable wcn3990: %d\n", ret);
+   return ret;
+   }
+
+   ret = ath10k_snoc_init_pipes(ar);
+   if (ret) {
+   ath10k_err(ar, "failed to initialize CE: %d\n", ret);
+   goto err_wlan_enable;
+   }
+
+   return 0;
+
+err_wlan_enable:
+   ath10k_snoc_wlan_disable(ar);
+
+   return ret;
+}
+
 static const struct ath10k_hif_ops ath10k_snoc_hif_ops = {
.read32 = ath10k_snoc_read32,
.write32= ath10k_snoc_write32,
@@ -526,6 +585,8 @@ static int ath10k_snoc_hif_start(struct ath10k *ar)
.stop   = ath10k_snoc_hif_stop,
.map_service_to_pipe= ath10k_snoc_hif_map_service_to_pipe,
.get_default_pipe   = ath10k_snoc_hif_get_default_pipe,
+   .power_up   = ath10k_snoc_hif_power_up,
+   .power_down = ath10k_snoc_hif_power_down,
 };
 
 static const struct ath10k_bus_ops ath10k_snoc_bus_ops = {
-- 
1.9.1



[PATCH v2 10/13] ath10k: Add support to get target info from hif ops

2018-03-22 Thread Govind Singh
From: Rakesh Pillai <pill...@codeaurora.org>

wcn3990 does not use bmi.
Add support to get target info from hif ops.

Signed-off-by: Rakesh Pillai <pill...@codeaurora.org>
Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/core.c |  8 
 drivers/net/wireless/ath/ath10k/hif.h  | 13 +
 drivers/net/wireless/ath/ath10k/snoc.c | 10 ++
 3 files changed, 31 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index 830b7fe..61443f5 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -2468,6 +2468,14 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
ar->hw->wiphy->hw_version = target_info.version;
break;
case ATH10K_BUS_SNOC:
+   memset(_info, 0, sizeof(target_info));
+   ret = ath10k_hif_get_target_info(ar, _info);
+   if (ret) {
+   ath10k_err(ar, "could not get target info (%d)\n", ret);
+   goto err_power_down;
+   }
+   ar->target_version = target_info.version;
+   ar->hw->wiphy->hw_version = target_info.version;
break;
default:
ath10k_err(ar, "incorrect hif bus type: %d\n", ar->hif.bus);
diff --git a/drivers/net/wireless/ath/ath10k/hif.h 
b/drivers/net/wireless/ath/ath10k/hif.h
index 7abb13c..1a59ea0 100644
--- a/drivers/net/wireless/ath/ath10k/hif.h
+++ b/drivers/net/wireless/ath/ath10k/hif.h
@@ -20,6 +20,7 @@
 
 #include 
 #include "core.h"
+#include "bmi.h"
 #include "debug.h"
 
 struct ath10k_hif_sg_item {
@@ -93,6 +94,9 @@ struct ath10k_hif_ops {
/* fetch calibration data from target eeprom */
int (*fetch_cal_eeprom)(struct ath10k *ar, void **data,
size_t *data_len);
+
+   int (*get_target_info)(struct ath10k *ar,
+  struct bmi_target_info *target_info);
 };
 
 static inline int ath10k_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
@@ -218,4 +222,13 @@ static inline int ath10k_hif_fetch_cal_eeprom(struct 
ath10k *ar,
return ar->hif.ops->fetch_cal_eeprom(ar, data, data_len);
 }
 
+static inline int ath10k_hif_get_target_info(struct ath10k *ar,
+struct bmi_target_info *tgt_info)
+{
+   if (!ar->hif.ops->get_target_info)
+   return -EOPNOTSUPP;
+
+   return ar->hif.ops->get_target_info(ar, tgt_info);
+}
+
 #endif /* _HIF_H_ */
diff --git a/drivers/net/wireless/ath/ath10k/snoc.c 
b/drivers/net/wireless/ath/ath10k/snoc.c
index 6d9ccce..1ef0d3b 100644
--- a/drivers/net/wireless/ath/ath10k/snoc.c
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -528,6 +528,15 @@ static int ath10k_snoc_hif_tx_sg(struct ath10k *ar, u8 
pipe_id,
return err;
 }
 
+static int ath10k_snoc_hif_get_target_info(struct ath10k *ar,
+  struct bmi_target_info *target_info)
+{
+   target_info->version = ATH10K_HW_WCN3990;
+   target_info->type = ATH10K_HW_WCN3990;
+
+   return 0;
+}
+
 static u16 ath10k_snoc_hif_get_free_queue_number(struct ath10k *ar, u8 pipe)
 {
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
@@ -787,6 +796,7 @@ static int ath10k_snoc_hif_power_up(struct ath10k *ar)
.tx_sg  = ath10k_snoc_hif_tx_sg,
.send_complete_check= ath10k_snoc_hif_send_complete_check,
.get_free_queue_number  = ath10k_snoc_hif_get_free_queue_number,
+   .get_target_info= ath10k_snoc_hif_get_target_info,
 };
 
 static const struct ath10k_bus_ops ath10k_snoc_bus_ops = {
-- 
1.9.1



[PATCH v2 05/13] ath10k: Map HTC services to tx/rx pipes for wcn3990

2018-03-22 Thread Govind Singh
Add mapping of HTC endpoint services supported
by wcn3990 target to tx/rx pipe.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/snoc.c | 168 +
 1 file changed, 168 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/snoc.c 
b/drivers/net/wireless/ath/ath10k/snoc.c
index dcd8bb7..a39eee7 100644
--- a/drivers/net/wireless/ath/ath10k/snoc.c
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -154,6 +154,116 @@
},
 };
 
+static struct service_to_pipe target_service_to_ce_map_wlan[] = {
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO),
+   __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
+   __cpu_to_le32(3),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(2),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BK),
+   __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
+   __cpu_to_le32(3),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BK),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(2),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BE),
+   __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
+   __cpu_to_le32(3),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BE),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(2),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VI),
+   __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
+   __cpu_to_le32(3),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VI),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(2),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_CONTROL),
+   __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
+   __cpu_to_le32(3),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_CONTROL),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(2),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_RSVD_CTRL),
+   __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
+   __cpu_to_le32(0),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_RSVD_CTRL),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(2),
+   },
+   { /* not used */
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS),
+   __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
+   __cpu_to_le32(0),
+   },
+   { /* not used */
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(2),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA_MSG),
+   __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
+   __cpu_to_le32(4),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA_MSG),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(1),
+   },
+   { /* not used */
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS),
+   __cpu_to_le32(PIPEDIR_OUT),
+   __cpu_to_le32(5),
+   },
+   { /* in = DL = target -> host */
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA2_MSG),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(9),
+   },
+   { /* in = DL = target -> host */
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA3_MSG),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(10),
+   },
+   { /* in = DL = target -> host pktlog */
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_LOG_MSG),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(11),
+   },
+   /* (Additions here) */
+
+   { /* must be last */
+   __cpu_to_le32(0),
+   __cpu_to_le32(0),
+   __cpu_to_le32(0),
+   },
+};
+
 void ath10k_snoc_write32(struct ath10k *ar, u32 offset, u32 value)
 {
struct ath10k_snoc *ar_snoc = at

[PATCH v2 09/13] ath10k: Modify hif tx paddr to dma_addr_t type

2018-03-22 Thread Govind Singh
Change type of hif sg tx paddr to dma_addr_t for
supporting target having addressing mode greater than
32 bit.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/hif.h | 2 +-
 drivers/net/wireless/ath/ath10k/pci.c | 8 
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/hif.h 
b/drivers/net/wireless/ath/ath10k/hif.h
index 6da4e33..7abb13c 100644
--- a/drivers/net/wireless/ath/ath10k/hif.h
+++ b/drivers/net/wireless/ath/ath10k/hif.h
@@ -26,7 +26,7 @@ struct ath10k_hif_sg_item {
u16 transfer_id;
void *transfer_context; /* NULL = tx completion callback not called */
void *vaddr; /* for debugging mostly */
-   u32 paddr;
+   dma_addr_t paddr;
u16 len;
 };
 
diff --git a/drivers/net/wireless/ath/ath10k/pci.c 
b/drivers/net/wireless/ath/ath10k/pci.c
index 808f3d6..e7c544b 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -1379,8 +1379,8 @@ int ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
 
for (i = 0; i < n_items - 1; i++) {
ath10k_dbg(ar, ATH10K_DBG_PCI,
-  "pci tx item %d paddr 0x%08x len %d n_items %d\n",
-  i, items[i].paddr, items[i].len, n_items);
+  "pci tx item %d paddr %pad len %d n_items %d\n",
+  i, [i].paddr, items[i].len, n_items);
ath10k_dbg_dump(ar, ATH10K_DBG_PCI_DUMP, NULL, "pci tx data: ",
items[i].vaddr, items[i].len);
 
@@ -1397,8 +1397,8 @@ int ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
/* `i` is equal to `n_items -1` after for() */
 
ath10k_dbg(ar, ATH10K_DBG_PCI,
-  "pci tx item %d paddr 0x%08x len %d n_items %d\n",
-  i, items[i].paddr, items[i].len, n_items);
+  "pci tx item %d paddr %pad len %d n_items %d\n",
+  i, [i].paddr, items[i].len, n_items);
ath10k_dbg_dump(ar, ATH10K_DBG_PCI_DUMP, NULL, "pci tx data: ",
items[i].vaddr, items[i].len);
 
-- 
1.9.1



[PATCH v2 04/13] ath10k: Add HTC services for WCN3990

2018-03-22 Thread Govind Singh
WCN3990 target uses 3 Copy engine(CE1/CE9/CE10) in RX path
and CE 11 for pktlog.
Add data path HTC ep services and PKTLOG services for WCN3990.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/htc.c | 6 ++
 drivers/net/wireless/ath/ath10k/htc.h | 4 
 2 files changed, 10 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/htc.c 
b/drivers/net/wireless/ath/ath10k/htc.c
index 492dc5b..8902720 100644
--- a/drivers/net/wireless/ath/ath10k/htc.c
+++ b/drivers/net/wireless/ath/ath10k/htc.c
@@ -542,8 +542,14 @@ static const char *htc_service_name(enum ath10k_htc_svc_id 
id)
return "NMI Data";
case ATH10K_HTC_SVC_ID_HTT_DATA_MSG:
return "HTT Data";
+   case ATH10K_HTC_SVC_ID_HTT_DATA2_MSG:
+   return "HTT Data";
+   case ATH10K_HTC_SVC_ID_HTT_DATA3_MSG:
+   return "HTT Data";
case ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS:
return "RAW";
+   case ATH10K_HTC_SVC_ID_HTT_LOG_MSG:
+   return "PKTLOG";
}
 
return "Unknown";
diff --git a/drivers/net/wireless/ath/ath10k/htc.h 
b/drivers/net/wireless/ath/ath10k/htc.h
index a2f8814..3487759 100644
--- a/drivers/net/wireless/ath/ath10k/htc.h
+++ b/drivers/net/wireless/ath/ath10k/htc.h
@@ -248,6 +248,7 @@ enum ath10k_htc_svc_gid {
ATH10K_HTC_SVC_GRP_WMI = 1,
ATH10K_HTC_SVC_GRP_NMI = 2,
ATH10K_HTC_SVC_GRP_HTT = 3,
+   ATH10K_LOG_SERVICE_GROUP = 6,
 
ATH10K_HTC_SVC_GRP_TEST = 254,
ATH10K_HTC_SVC_GRP_LAST = 255,
@@ -273,6 +274,9 @@ enum ath10k_htc_svc_id {
 
ATH10K_HTC_SVC_ID_HTT_DATA_MSG  = SVC(ATH10K_HTC_SVC_GRP_HTT, 0),
 
+   ATH10K_HTC_SVC_ID_HTT_DATA2_MSG = SVC(ATH10K_HTC_SVC_GRP_HTT, 1),
+   ATH10K_HTC_SVC_ID_HTT_DATA3_MSG = SVC(ATH10K_HTC_SVC_GRP_HTT, 2),
+   ATH10K_HTC_SVC_ID_HTT_LOG_MSG = SVC(ATH10K_LOG_SERVICE_GROUP, 0),
/* raw stream service (i.e. flash, tcmd, calibration apps) */
ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS = SVC(ATH10K_HTC_SVC_GRP_TEST, 0),
 };
-- 
1.9.1



[PATCH v2 11/13] ath10k: Check all CE for data if irq summary is not retained

2018-03-22 Thread Govind Singh
From: Rakesh Pillai <pill...@codeaurora.org>

WCN3990 has interrupts per CE and the interrupt summary
is not retained after the interrupt handler has finished
execution. We need to check if we received any
ce in rx and tx completion path.

Generate a interrupt summary with all CE interrupts if
the target does not retain interrupt summary after the
execution of interrupt handler.

Signed-off-by: Rakesh Pillai <pill...@codeaurora.org>
Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/ce.h   | 10 +++---
 drivers/net/wireless/ath/ath10k/core.c | 13 +
 drivers/net/wireless/ath/ath10k/hw.h   |  3 +++
 3 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/ce.h 
b/drivers/net/wireless/ath/ath10k/ce.h
index 2c3c8f5..d8f9da3 100644
--- a/drivers/net/wireless/ath/ath10k/ce.h
+++ b/drivers/net/wireless/ath/ath10k/ce.h
@@ -355,14 +355,18 @@ static inline u32 ath10k_ce_base_address(struct ath10k 
*ar, unsigned int ce_id)
(((x) & CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK) >> \
CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB)
 #define CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS   0x
+#define CE_INTERRUPT_SUMMARY   (GENMASK(CE_COUNT_MAX - 1, 0))
 
 static inline u32 ath10k_ce_interrupt_summary(struct ath10k *ar)
 {
struct ath10k_ce *ce = ath10k_ce_priv(ar);
 
-   return CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET(
-   ce->bus_ops->read32((ar), CE_WRAPPER_BASE_ADDRESS +
-   CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS));
+   if (!ar->hw_params.per_ce_irq)
+   return CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET(
+   ce->bus_ops->read32((ar), CE_WRAPPER_BASE_ADDRESS +
+   CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS));
+   else
+   return CE_INTERRUPT_SUMMARY;
 }
 
 #endif /* _CE_H_ */
diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index 61443f5..64479ac 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -119,6 +119,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
+   .per_ce_irq = false,
},
{
.id = QCA9887_HW_1_0_VERSION,
@@ -148,6 +149,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
+   .per_ce_irq = false,
},
{
.id = QCA6174_HW_2_1_VERSION,
@@ -176,6 +178,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
+   .per_ce_irq = false,
},
{
.id = QCA6174_HW_2_1_VERSION,
@@ -204,6 +207,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
+   .per_ce_irq = false,
},
{
.id = QCA6174_HW_3_0_VERSION,
@@ -232,6 +236,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
+   .per_ce_irq = false,
},
{
.id = QCA6174_HW_3_2_VERSION,
@@ -263,6 +268,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
+   .per_ce_irq = false,
},
{
.id = QCA99X0_HW_2_0_DEV_VERSION,
@@ -297,6 +303,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
+   .per_ce_irq = false,
},
{
.id = QCA9984_HW_1_0_DEV_VERSION,
@@ -336,6 +343,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
+   .per_ce_irq = false,
},
{
.id = QCA9888_HW_2_0_DEV_VERSION,
@@ -374,6 +382,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
+   .per_ce_irq = false,
},
{
.id = QCA9377_HW_1_0_DEV_VERSION,
@@ -402,6 +411,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
+   .per_ce_irq = false,
},
{
.id = QCA9377_HW_1_1_DEV_VERSION,
@@ -432,6 +442,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.

[PATCH v2 12/13] ath10k: Vote for hardware resources for WCN3990

2018-03-22 Thread Govind Singh
Add clock and regulator votes for WCN3990 WLAN
chipset.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/snoc.c | 313 -
 drivers/net/wireless/ath/ath10k/snoc.h |  19 ++
 2 files changed, 331 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/snoc.c 
b/drivers/net/wireless/ath/ath10k/snoc.c
index 1ef0d3b..2e490ff 100644
--- a/drivers/net/wireless/ath/ath10k/snoc.c
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -24,6 +24,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #define  WCN3990_CE_ATTR_FLAGS 0
 #define ATH10K_SNOC_RX_POST_RETRY_MS 50
 #define CE_POLL_PIPE 4
@@ -43,6 +45,17 @@
"WLAN_CE_11",
 };
 
+static struct ath10k_wcn3990_vreg_info vreg_cfg[] = {
+   {NULL, "vdd-0.8-cx-mx", 80, 80, 0, 0, false},
+   {NULL, "vdd-1.8-xo", 180, 180, 0, 0, false},
+   {NULL, "vdd-1.3-rfa", 1304000, 1304000, 0, 0, false},
+   {NULL, "vdd-3.3-ch0", 3312000, 3312000, 0, 0, false},
+};
+
+static struct ath10k_wcn3990_clk_info clk_cfg[] = {
+   {NULL, "cxo_ref_clk_pin", 0, false},
+};
+
 static void ath10k_snoc_htc_tx_cb(struct ath10k_ce_pipe *ce_state);
 static void ath10k_snoc_htt_tx_cb(struct ath10k_ce_pipe *ce_state);
 static void ath10k_snoc_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
@@ -969,6 +982,277 @@ static void ath10k_snoc_release_resource(struct ath10k 
*ar)
ath10k_ce_free_pipe(ar, i);
 }
 
+static int ath10k_get_vreg_info(struct ath10k *ar, struct device *dev,
+   struct ath10k_wcn3990_vreg_info *vreg_info)
+{
+   struct regulator *reg;
+   int ret = 0;
+
+   reg = devm_regulator_get_optional(dev, vreg_info->name);
+
+   if (IS_ERR(reg)) {
+   ret = PTR_ERR(reg);
+
+   if (ret  == -EPROBE_DEFER) {
+   ath10k_err(ar, "EPROBE_DEFER for regulator: %s\n",
+  vreg_info->name);
+   return ret;
+   }
+   if (vreg_info->required) {
+   ath10k_err(ar, "Regulator %s doesn't exist: %d\n",
+  vreg_info->name, ret);
+   return ret;
+   }
+   ath10k_dbg(ar, ATH10K_DBG_SNOC,
+  "Optional regulator %s doesn't exist: %d\n",
+  vreg_info->name, ret);
+   goto done;
+   }
+
+   vreg_info->reg = reg;
+
+done:
+   ath10k_dbg(ar, ATH10K_DBG_SNOC,
+  "snog vreg %s min_v %u max_v %u load_ua %u settle_delay 
%lu\n",
+  vreg_info->name, vreg_info->min_v, vreg_info->max_v,
+  vreg_info->load_ua, vreg_info->settle_delay);
+
+   return 0;
+}
+
+static int ath10k_get_clk_info(struct ath10k *ar, struct device *dev,
+  struct ath10k_wcn3990_clk_info *clk_info)
+{
+   struct clk *handle;
+   int ret = 0;
+
+   handle = devm_clk_get(dev, clk_info->name);
+   if (IS_ERR(handle)) {
+   ret = PTR_ERR(handle);
+   if (clk_info->required) {
+   ath10k_err(ar, "snoc clock %s isn't available: %d\n",
+  clk_info->name, ret);
+   return ret;
+   }
+   ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc ignoring clock %s: %d\n",
+  clk_info->name,
+  ret);
+   return 0;
+   }
+
+   ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc clock %s freq %u\n",
+  clk_info->name, clk_info->freq);
+
+   clk_info->handle = handle;
+
+   return ret;
+}
+
+static int ath10k_wcn3990_vreg_on(struct ath10k *ar)
+{
+   struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+   struct ath10k_wcn3990_vreg_info *vreg_info;
+   int ret = 0;
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(vreg_cfg); i++) {
+   vreg_info = _snoc->vreg[i];
+
+   if (!vreg_info->reg)
+   continue;
+
+   ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc regulator %s being 
enabled\n",
+  vreg_info->name);
+
+   ret = regulator_set_voltage(vreg_info->reg, vreg_info->min_v,
+   vreg_info->max_v);
+   if (ret) {
+   ath10k_err(ar,
+  "failed to set regulator %s voltage-min: %d 
voltage-max: %d\n",
+  vreg_info->name, vreg_info->min_v, 
vreg_info->max_v);
+   goto err_reg_config;
+   }
+
+   if (v

[PATCH] ath10k: build ce layer in ath10k core module

2018-03-21 Thread Govind Singh
CE layer is shared between pci and snoc target and results
in duplicate object inclusion if both modules are compiled
together statically and undefined KBUILD_MODNAME if
compiled as module.

Fix this by building ce layer in ath10k core module by
adding ce object inclusion with ATH10K_CE boolean CONFIG.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/Kconfig  |  4 
 drivers/net/wireless/ath/ath10k/Makefile |  4 ++--
 drivers/net/wireless/ath/ath10k/ce.c | 22 ++
 3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/Kconfig 
b/drivers/net/wireless/ath/ath10k/Kconfig
index deb5ae2..d266f27 100644
--- a/drivers/net/wireless/ath/ath10k/Kconfig
+++ b/drivers/net/wireless/ath/ath10k/Kconfig
@@ -4,12 +4,16 @@ config ATH10K
select ATH_COMMON
select CRC32
select WANT_DEV_COREDUMP
+   select ATH10K_CE
 ---help---
   This module adds support for wireless adapters based on
   Atheros IEEE 802.11ac family of chipsets.
 
   If you choose to build a module, it'll be called ath10k.
 
+config ATH10K_CE
+   bool
+
 config ATH10K_PCI
tristate "Atheros ath10k PCI support"
depends on ATH10K && PCI
diff --git a/drivers/net/wireless/ath/ath10k/Makefile 
b/drivers/net/wireless/ath/ath10k/Makefile
index 6739ac2..536f3df 100644
--- a/drivers/net/wireless/ath/ath10k/Makefile
+++ b/drivers/net/wireless/ath/ath10k/Makefile
@@ -22,10 +22,10 @@ ath10k_core-$(CONFIG_THERMAL) += thermal.o
 ath10k_core-$(CONFIG_MAC80211_DEBUGFS) += debugfs_sta.o
 ath10k_core-$(CONFIG_PM) += wow.o
 ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o
+ath10k_core-$(CONFIG_ATH10K_CE) += ce.o
 
 obj-$(CONFIG_ATH10K_PCI) += ath10k_pci.o
-ath10k_pci-y += pci.o \
-   ce.o
+ath10k_pci-y += pci.o
 
 ath10k_pci-$(CONFIG_ATH10K_AHB) += ahb.o
 
diff --git a/drivers/net/wireless/ath/ath10k/ce.c 
b/drivers/net/wireless/ath/ath10k/ce.c
index b9def7b..e7e7b34 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -464,6 +464,7 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
return ce_state->ops->ce_send_nolock(ce_state, per_transfer_context,
buffer, nbytes, transfer_id, flags);
 }
+EXPORT_SYMBOL(ath10k_ce_send_nolock);
 
 void __ath10k_ce_send_revert(struct ath10k_ce_pipe *pipe)
 {
@@ -491,6 +492,7 @@ void __ath10k_ce_send_revert(struct ath10k_ce_pipe *pipe)
 
src_ring->per_transfer_context[src_ring->write_index] = NULL;
 }
+EXPORT_SYMBOL(__ath10k_ce_send_revert);
 
 int ath10k_ce_send(struct ath10k_ce_pipe *ce_state,
   void *per_transfer_context,
@@ -510,6 +512,7 @@ int ath10k_ce_send(struct ath10k_ce_pipe *ce_state,
 
return ret;
 }
+EXPORT_SYMBOL(ath10k_ce_send);
 
 int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe)
 {
@@ -525,6 +528,7 @@ int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe 
*pipe)
 
return delta;
 }
+EXPORT_SYMBOL(ath10k_ce_num_free_src_entries);
 
 int __ath10k_ce_rx_num_free_bufs(struct ath10k_ce_pipe *pipe)
 {
@@ -539,6 +543,7 @@ int __ath10k_ce_rx_num_free_bufs(struct ath10k_ce_pipe 
*pipe)
 
return CE_RING_DELTA(nentries_mask, write_index, sw_index - 1);
 }
+EXPORT_SYMBOL(__ath10k_ce_rx_num_free_bufs);
 
 static int __ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx,
   dma_addr_t paddr)
@@ -622,6 +627,7 @@ void ath10k_ce_rx_update_write_idx(struct ath10k_ce_pipe 
*pipe, u32 nentries)
ath10k_ce_dest_ring_write_index_set(ar, ctrl_addr, write_index);
dest_ring->write_index = write_index;
 }
+EXPORT_SYMBOL(ath10k_ce_rx_update_write_idx);
 
 int ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx,
  dma_addr_t paddr)
@@ -636,6 +642,7 @@ int ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void 
*ctx,
 
return ret;
 }
+EXPORT_SYMBOL(ath10k_ce_rx_post_buf);
 
 /*
  * Guts of ath10k_ce_completed_recv_next.
@@ -748,6 +755,7 @@ int ath10k_ce_completed_recv_next_nolock(struct 
ath10k_ce_pipe *ce_state,
per_transfer_ctx,
nbytesp);
 }
+EXPORT_SYMBOL(ath10k_ce_completed_recv_next_nolock);
 
 int ath10k_ce_completed_recv_next(struct ath10k_ce_pipe *ce_state,
  void **per_transfer_contextp,
@@ -766,6 +774,7 @@ int ath10k_ce_completed_recv_next(struct ath10k_ce_pipe 
*ce_state,
 
return ret;
 }
+EXPORT_SYMBOL(ath10k_ce_completed_recv_next);
 
 static int _ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state,
   void **per_transfer_contextp,
@@ -882,6 +891,7 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe 
*ce_state,

RE: [PATCH] ath10k: Enable IOMMU support for WCN3990 target

2018-03-01 Thread Govind Singh
>> The asm/dma-iommu.h header file exsists only on arm32, no other architecture.
>> I'm not sure about the purpose of the patch to start with:
>> it's normally up to the platform code to allocate IOMMU domains, device 
>> drivers should only need to manually interact with the IOMMU layer if they 
>> need more than one domain, but this ath10k patch appears to be using the 
>> default domain and should have no effect as long as the platform code works 
>> correctly.
Thanks Arnd, I have fixed this and migrated to  64bit 
API's(iommu_attach_device/iommu_detach_device/ iommu_get_domain_for_dev), will 
share the next revision.
I tried using the default domain by adding the stream ID and mask in dt and no 
manual interaction, but it is resulting in TZ error and unhandled context fault.
Seems I need to provide explicit mapping range(aperture_start/ aperture_end) as 
this is only working combination for me..

BR,
Govind

-Original Message-
From: ath10k [mailto:ath10k-boun...@lists.infradead.org] On Behalf Of Arnd 
Bergmann
Sent: Thursday, March 1, 2018 3:40 PM
To: Kalle Valo <kv...@codeaurora.org>
Cc: Govind Singh <govi...@codeaurora.org>; linux-wireless 
<linux-wireless@vger.kernel.org>; ath...@lists.infradead.org
Subject: Re: [PATCH] ath10k: Enable IOMMU support for WCN3990 target

On Thu, Mar 1, 2018 at 11:01 AM, Kalle Valo <kv...@codeaurora.org> wrote:
> Govind Singh <govi...@codeaurora.org> writes:
>
>> When an IOMMU device is available on the platform bus, allocate an 
>> IOMMU domain and attach the wlan target to it.
>> WCN3990 target can then attach an DMA I/O virtual address space to 
>> scan out of bound transactions.
>>
>> Signed-off-by: Govind Singh <govi...@codeaurora.org>
>> ---
>>  drivers/net/wireless/ath/ath10k/snoc.c | 100 
>> -
>>  drivers/net/wireless/ath/ath10k/snoc.h |   3 +
>>  2 files changed, 101 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/net/wireless/ath/ath10k/snoc.c 
>> b/drivers/net/wireless/ath/ath10k/snoc.c
>> index cd21b25..502263d 100644
>> --- a/drivers/net/wireless/ath/ath10k/snoc.c
>> +++ b/drivers/net/wireless/ath/ath10k/snoc.c
>> @@ -26,6 +26,10 @@
>>  #include 
>>  #include   #include 
>> +#include 
>> +#include 
>> +#include 
>
> Kbuild bot reported a problem with arm64 but strangely I cannot find 
> the full report. Anyway, this was the warning:
>
> drivers/net/wireless/ath/ath10k/snoc.c:29:10: fatal error:
> asm/dma-iommu.h: No such file or directory
>
> Any ideas? Adding also Arnd, the grand master of compilation problems 
> :)
>
> Full patch here:
>
> https://patchwork.kernel.org/patch/10220719/
>

The asm/dma-iommu.h header file exsists only on arm32, no other architecture.

I'm not sure about the purpose of the patch to start with:
it's normally up to the platform code to allocate IOMMU domains, device drivers 
should only need to manually interact with the IOMMU layer if they need more 
than one domain, but this ath10k patch appears to be using the default domain 
and should have no effect as long as the platform code works correctly.

   Arnd

___
ath10k mailing list
ath...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k


RE: [PATCH 01/13] ath10k: platform driver for WCN3990 SNOC WLAN module

2018-03-01 Thread Govind Singh
Hi Kalle,

I didn't encountered this issue as in my defconfig only CONFIG_ATH10K_SNOC was 
defined.
This problem is coming when we define CONFIG_ATH10K_SNOC and CONFIG_ATH10K_PCI 
simultaneously in defconfig and this is 
known issue when multiple modules share objects(in this case ce.o). I saw 
similar reported problem and found https://patchwork.kernel.org/patch/10060825/.

After picking the below change issue is not seen.

BR,
Govind

-Original Message-
From: ath10k [mailto:ath10k-boun...@lists.infradead.org] On Behalf Of Kalle Valo
Sent: Thursday, March 1, 2018 3:37 PM
To: Govind Singh <govi...@codeaurora.org>
Cc: linux-wireless@vger.kernel.org; ath...@lists.infradead.org
Subject: Re: [PATCH 01/13] ath10k: platform driver for WCN3990 SNOC WLAN module

Govind Singh <govi...@codeaurora.org> writes:

> WCN3990 is integrated 802.11ac chipset with SNOC bus interface. Add 
> snoc layer driver registration and associated ops.
>
> WCN3990 support is not yet complete as cold-boot handshake is done 
> using qmi(Qualcomm-MSM-Interface) and qmi client support will be added 
> once qmi framework is available.
>
> Signed-off-by: Govind Singh <govi...@codeaurora.org>

Kbuild bot found an odd problem with this patch:

 include/linux/dynamic_debug.h:77:14: error: 'KBUILD_MODNAME'
 undeclared (first use in this function); did you mean  'KBUILD_BASENAME'?

Full report:

http://lists.infradead.org/pipermail/ath10k/2018-February/010907.html

Any ideas? Is this is some unrelated issue or what? This patch is not even 
touching hif.h or ce.c.

--
Kalle Valo

___
ath10k mailing list
ath...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k


[PATCH v2] dt: bindings: add bindings for wcn3990 wifi block

2018-02-15 Thread Govind Singh
Add device tree binding documentation details for wcn3990
wifi block present in Qualcomm SDM845/APQ8098 SoC into
"qcom,ath10k.txt".

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 .../bindings/net/wireless/qcom,ath10k.txt  | 35 ++
 1 file changed, 35 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt 
b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
index 3d2a031..e34d8f8 100644
--- a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
+++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
@@ -4,6 +4,7 @@ Required properties:
 - compatible: Should be one of the following:
* "qcom,ath10k"
* "qcom,ipq4019-wifi"
+   * "qcom,wcn3990-wifi"
 
 PCI based devices uses compatible string "qcom,ath10k" and takes calibration
 data along with board specific data via "qcom,ath10k-calibration-data".
@@ -18,8 +19,11 @@ In general, entry "qcom,ath10k-pre-calibration-data" and
 "qcom,ath10k-calibration-data" conflict with each other and only one
 can be provided per device.
 
+SNOC based devices (i.e. wcn3990) uses compatible string "qcom,wcn3990-wifi".
+
 Optional properties:
 - reg: Address and length of the register set for the device.
+- reg-names: Names of the memory regions defined in reg entry.
 - resets: Must contain an entry for each entry in reset-names.
   See ../reset/reseti.txt for details.
 - reset-names: Must include the list of following reset names,
@@ -49,6 +53,12 @@ Optional properties:
 hw versions.
 - qcom,ath10k-pre-calibration-data : pre calibration data as an array,
 the length can vary between hw versions.
+- qcom,-supply: handle to the regulator device tree node
+  optional "supply-name" is "vdd-0.8-cx-mx".
+- qcom,-config: Specifies voltage levels for supply. Should be
+ specified in pairs (min, max), units uV.  There can
+  be optional load in uA and Regulator settle delay in
+  uS.
 
 Example (to supply the calibration data alone):
 
@@ -119,3 +129,28 @@ wifi0: wifi@a00 {
qcom,msi_base = <0x40>;
qcom,ath10k-pre-calibration-data = [ 01 02 03 ... ];
 };
+
+Example (to supply wcn3990 SoC wifi block details):
+
+qcom,msm_ath10k@1800 {
+   compatible = "qcom,wcn3990-wifi";
+   reg = <0x1880 0x80>;
+   reg-names = "membase";
+   clocks = <_gcc clk_aggre2_noc_clk>;
+   clock-names = "smmu_aggre2_noc_clk"
+   interrupts =
+  <0 130 0 /* CE0 */ >,
+  <0 131 0 /* CE1 */ >,
+  <0 132 0 /* CE2 */ >,
+  <0 133 0 /* CE3 */ >,
+  <0 134 0 /* CE4 */ >,
+  <0 135 0 /* CE5 */ >,
+  <0 136 0 /* CE6 */ >,
+  <0 137 0 /* CE7 */ >,
+  <0 138 0 /* CE8 */ >,
+  <0 139 0 /* CE9 */ >,
+  <0 140 0 /* CE10 */ >,
+  <0 141 0 /* CE11 */ >;
+   qcom,vdd-0.8-cx-mx-supply = <_l5>;
+   qcom,vdd-0.8-cx-mx-config = <80 80 2400 1000>;
+};
-- 
1.9.1



RE: [PATCH 13/13] dt: bindings: add bindings for wcn3990 wifi block

2018-02-15 Thread Govind Singh
>> You've omitted the "qcom," you specify above.
Thanks, Julian, I will correct this in v2 revision.

Thanks,
Govind

-Original Message-
From: ath10k [mailto:ath10k-boun...@lists.infradead.org] On Behalf Of Julian 
Calaby
Sent: Thursday, February 15, 2018 7:36 PM
To: Govind Singh <govi...@codeaurora.org>
Cc: devicetree <devicet...@vger.kernel.org>; linux-wireless 
<linux-wireless@vger.kernel.org>; ath...@lists.infradead.org
Subject: Re: [PATCH 13/13] dt: bindings: add bindings for wcn3990 wifi block

Hi Govind,

On Thu, Feb 15, 2018 at 7:56 PM, Govind Singh <govi...@codeaurora.org> wrote:
> Add device tree binding documentation details for wcn3990 wifi block 
> present in Qualcomm SDM845/APQ8098 SoC into "qcom,ath10k.txt".
>
> Signed-off-by: Govind Singh <govi...@codeaurora.org>
> ---
>  .../bindings/net/wireless/qcom,ath10k.txt  | 35 
> ++
>  1 file changed, 35 insertions(+)
>
> diff --git 
> a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt 
> b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
> index 3d2a031..07b0f13 100644
> --- a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
> +++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
> @@ -4,6 +4,7 @@ Required properties:
>  - compatible: Should be one of the following:
> * "qcom,ath10k"
> * "qcom,ipq4019-wifi"
> +   * "qcom,wcn3990-wifi"
>
>  PCI based devices uses compatible string "qcom,ath10k" and takes 
> calibration  data along with board specific data via 
> "qcom,ath10k-calibration-data".
> @@ -18,8 +19,11 @@ In general, entry 
> "qcom,ath10k-pre-calibration-data" and  "qcom,ath10k-calibration-data" 
> conflict with each other and only one  can be provided per device.
>
> +SNOC based devices (i.e. wcn3990) uses compatible string "qcom,wcn3990-wifi".
> +
>  Optional properties:
>  - reg: Address and length of the register set for the device.
> +- reg-names: Names of the memory regions defined in reg entry.
>  - resets: Must contain an entry for each entry in reset-names.
>See ../reset/reseti.txt for details.
>  - reset-names: Must include the list of following reset names, @@ 
> -49,6 +53,12 @@ Optional properties:
>  hw versions.
>  - qcom,ath10k-pre-calibration-data : pre calibration data as an array,
>  the length can vary between hw versions.
> +- qcom,-supply: handle to the regulator device tree node
> +  optional "supply-name" is "vdd-0.8-cx-mx".
> +- qcom,-config: Specifies voltage levels for supply. Should be
> + specified in pairs (min, max), units uV.  There can
> +  be optional load in uA and Regulator settle delay 
> in
> +  uS.
>
>  Example (to supply the calibration data alone):
>
> @@ -119,3 +129,28 @@ wifi0: wifi@a00 {
> qcom,msi_base = <0x40>;
> qcom,ath10k-pre-calibration-data = [ 01 02 03 ... ];  };
> +
> +Example (to supply wcn3990 SoC wifi block details):
> +
> +qcom,msm_ath10k@1800 {
> +   compatible = "qcom,wcn3990-wifi";
> +   reg = <0x1880 0x80>;
> +   reg-names = "membase";
> +   clocks = <_gcc clk_aggre2_noc_clk>;
> +   clock-names = "smmu_aggre2_noc_clk"
> +   interrupts =
> +  <0 130 0 /* CE0 */ >,
> +  <0 131 0 /* CE1 */ >,
> +  <0 132 0 /* CE2 */ >,
> +  <0 133 0 /* CE3 */ >,
> +  <0 134 0 /* CE4 */ >,
> +  <0 135 0 /* CE5 */ >,
> +  <0 136 0 /* CE6 */ >,
> +  <0 137 0 /* CE7 */ >,
> +  <0 138 0 /* CE8 */ >,
> +  <0 139 0 /* CE9 */ >,
> +  <0 140 0 /* CE10 */ >,
> +  <0 141 0 /* CE11 */ >;
> +   vdd-0.8-cx-mx-supply = <_l5>;

You've omitted the "qcom," you specify above.

> +   qcom,vdd-0.8-cx-mx-config = <80 80 2400 1000>; 
> +};
> --
> 1.9.1
>

Thanks,

--
Julian Calaby

Email: julian.cal...@gmail.com
Profile: http://www.google.com/profiles/julian.calaby/

___
ath10k mailing list
ath...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k


[PATCH] ath10k: Enable IOMMU support for WCN3990 target

2018-02-15 Thread Govind Singh
When an IOMMU device is available on the platform bus, allocate
an IOMMU domain and attach the wlan target to it.
WCN3990 target can then attach an DMA I/O virtual address
space to scan out of bound transactions.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/snoc.c | 100 -
 drivers/net/wireless/ath/ath10k/snoc.h |   3 +
 2 files changed, 101 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/snoc.c 
b/drivers/net/wireless/ath/ath10k/snoc.c
index cd21b25..502263d 100644
--- a/drivers/net/wireless/ath/ath10k/snoc.c
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -26,6 +26,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+
 #define  WCN3990_CE_ATTR_FLAGS 0
 #define ATH10K_SNOC_RX_POST_RETRY_MS 50
 #define CE_POLL_PIPE 4
@@ -1292,6 +1296,88 @@ static int ath10k_hw_power_off(struct ath10k *ar)
return ret;
 }
 
+static int ath10k_smmu_attach(struct ath10k *ar)
+{
+   struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+   struct dma_iommu_mapping *mapping;
+   struct platform_device *pdev;
+   int ret = 0;
+
+   ath10k_dbg(ar, ATH10K_DBG_SNOC, "Initializing SMMU\n");
+
+   pdev = ar_snoc->dev;
+   mapping = arm_iommu_create_mapping(_bus_type,
+  ar_snoc->smmu_iova_start,
+  ar_snoc->smmu_iova_len);
+   if (IS_ERR(mapping)) {
+   ath10k_err(ar, "create mapping failed, err = %d\n", ret);
+   ret = PTR_ERR(mapping);
+   goto map_fail;
+   }
+
+   ret = arm_iommu_attach_device(>dev, mapping);
+   if (ret < 0 && ret != -EEXIST) {
+   ath10k_err(ar, "iommu attach device failed, err = %d\n", ret);
+   goto attach_fail;
+   } else if (ret == -EEXIST) {
+   ret = 0;
+   }
+
+   ar_snoc->smmu_mapping = mapping;
+
+   return ret;
+
+attach_fail:
+   arm_iommu_release_mapping(mapping);
+map_fail:
+   return ret;
+}
+
+static void ath10k_smmu_deinit(struct ath10k *ar)
+{
+   struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+   struct platform_device *pdev;
+
+   pdev = ar_snoc->dev;
+
+   if (!ar_snoc->smmu_mapping)
+   return;
+
+   arm_iommu_detach_device(>dev);
+   arm_iommu_release_mapping(ar_snoc->smmu_mapping);
+
+   ar_snoc->smmu_mapping = NULL;
+}
+
+static int ath10k_smmu_init(struct ath10k *ar)
+{
+   struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+   struct platform_device *pdev;
+   struct resource *res;
+   int ret = 0;
+
+   pdev = ar_snoc->dev;
+   res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+  "smmu_iova_base");
+   if (!res) {
+   ath10k_err(ar, "SMMU iova base not found\n");
+   } else {
+   ar_snoc->smmu_iova_start = res->start;
+   ar_snoc->smmu_iova_len = resource_size(res);
+   ath10k_dbg(ar, ATH10K_DBG_SNOC, "SMMU iova start: %pa, len: 
%zu\n",
+  _snoc->smmu_iova_start, ar_snoc->smmu_iova_len);
+
+   ret = ath10k_smmu_attach(ar);
+   if (ret < 0) {
+   ath10k_err(ar, "SMMU init failed, err = %d, start: 
%pad, len: %zx\n",
+  ret, _snoc->smmu_iova_start,
+  ar_snoc->smmu_iova_len);
+   }
+   }
+
+   return ret;
+}
+
 static const struct of_device_id ath10k_snoc_dt_match[] = {
{ .compatible = "qcom,wcn3990-wifi",
 .data = _priv,
@@ -1339,16 +1425,22 @@ static int ath10k_snoc_probe(struct platform_device 
*pdev)
ar_snoc->ce.bus_ops = _snoc_bus_ops;
ar->ce_priv = _snoc->ce;
 
+   ret = ath10k_smmu_init(ar);
+   if (ret) {
+   ath10k_warn(ar, "failed to int SMMU: %d\n", ret);
+   goto err_core_destroy;
+   }
+
ath10k_snoc_resource_init(ar);
if (ret) {
ath10k_warn(ar, "failed to initialize resource: %d\n", ret);
-   goto err_core_destroy;
+   goto err_smmu_deinit;
}
 
ath10k_snoc_setup_resource(ar);
if (ret) {
ath10k_warn(ar, "failed to setup resource: %d\n", ret);
-   goto err_core_destroy;
+   goto err_smmu_deinit;
}
ret = ath10k_snoc_request_irq(ar);
if (ret) {
@@ -1396,6 +1488,9 @@ static int ath10k_snoc_probe(struct platform_device *pdev)
 err_release_resource:
ath10k_snoc_release_resource(ar);
 
+err_smmu_deinit:
+   ath10k_smmu_deinit(ar);
+
 err_core_destroy:
ath10k_core_destroy(ar);
 
@@ -1409,6 +15

[PATCH 11/13] ath10k: Check all CE for data if irq summary is not retained

2018-02-15 Thread Govind Singh
From: Rakesh Pillai <pill...@codeaurora.org>

WCN3990 has interrupts per CE and the interrupt summary
is not retained after the interrupt handler has finished
execution. We need to check if we received any
ce in rx and tx completion path.

Generate a interrupt summary with all CE interrupts if
the target does not retain interrupt summary after the
execution of interrupt handler.

Signed-off-by: Rakesh Pillai <pill...@codeaurora.org>
Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/ce.h   | 10 +++---
 drivers/net/wireless/ath/ath10k/core.c | 13 +
 drivers/net/wireless/ath/ath10k/hw.h   |  3 +++
 3 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/ce.h 
b/drivers/net/wireless/ath/ath10k/ce.h
index 06ac2eb..0e70a07 100644
--- a/drivers/net/wireless/ath/ath10k/ce.h
+++ b/drivers/net/wireless/ath/ath10k/ce.h
@@ -354,14 +354,18 @@ static inline u32 ath10k_ce_base_address(struct ath10k 
*ar, unsigned int ce_id)
(((x) & CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK) >> \
CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB)
 #define CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS   0x
+#define CE_INTERRUPT_SUMMARY   (GENMASK(CE_COUNT_MAX - 1, 0))
 
 static inline u32 ath10k_ce_interrupt_summary(struct ath10k *ar)
 {
struct ath10k_ce *ce = ath10k_ce_priv(ar);
 
-   return CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET(
-   ce->bus_ops->read32((ar), CE_WRAPPER_BASE_ADDRESS +
-   CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS));
+   if (!ar->hw_params.per_ce_irq)
+   return CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET(
+   ce->bus_ops->read32((ar), CE_WRAPPER_BASE_ADDRESS +
+   CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS));
+   else
+   return CE_INTERRUPT_SUMMARY;
 }
 
 #endif /* _CE_H_ */
diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index bcce875..8716ea4 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -89,6 +89,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
+   .per_ce_irq = false,
},
{
.id = QCA9887_HW_1_0_VERSION,
@@ -118,6 +119,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
+   .per_ce_irq = false,
},
{
.id = QCA6174_HW_2_1_VERSION,
@@ -146,6 +148,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
+   .per_ce_irq = false,
},
{
.id = QCA6174_HW_2_1_VERSION,
@@ -174,6 +177,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
+   .per_ce_irq = false,
},
{
.id = QCA6174_HW_3_0_VERSION,
@@ -202,6 +206,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
+   .per_ce_irq = false,
},
{
.id = QCA6174_HW_3_2_VERSION,
@@ -233,6 +238,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
+   .per_ce_irq = false,
},
{
.id = QCA99X0_HW_2_0_DEV_VERSION,
@@ -267,6 +273,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
+   .per_ce_irq = false,
},
{
.id = QCA9984_HW_1_0_DEV_VERSION,
@@ -306,6 +313,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
+   .per_ce_irq = false,
},
{
.id = QCA9888_HW_2_0_DEV_VERSION,
@@ -344,6 +352,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
+   .per_ce_irq = false,
},
{
.id = QCA9377_HW_1_0_DEV_VERSION,
@@ -372,6 +381,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
+   .per_ce_irq = false,
},
{
.id = QCA9377_HW_1_1_DEV_VERSION,
@@ -402,6 +412,7 @@
.num_wds_entries = 0x20,
.target_64bit = false,
.

[PATCH 12/13] ath10k: Vote for hardware resources for WCN3990

2018-02-15 Thread Govind Singh
Add clock and regulator votes for WCN3990 WLAN
chipset.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/snoc.c | 352 -
 drivers/net/wireless/ath/ath10k/snoc.h |  19 ++
 2 files changed, 370 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/snoc.c 
b/drivers/net/wireless/ath/ath10k/snoc.c
index 1ef0d3b..cd21b25 100644
--- a/drivers/net/wireless/ath/ath10k/snoc.c
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -24,9 +24,12 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #define  WCN3990_CE_ATTR_FLAGS 0
 #define ATH10K_SNOC_RX_POST_RETRY_MS 50
 #define CE_POLL_PIPE 4
+#define ATH10K_MAX_PROP_SIZE 32
 
 static char *const ce_name[] = {
"WLAN_CE_0",
@@ -43,6 +46,17 @@
"WLAN_CE_11",
 };
 
+static struct ath10k_wcn3990_vreg_info vreg_cfg[] = {
+   {NULL, "vdd-0.8-cx-mx", 80, 80, 0, 0, false},
+   {NULL, "vdd-1.8-xo", 180, 180, 0, 0, false},
+   {NULL, "vdd-1.3-rfa", 1304000, 1304000, 0, 0, false},
+   {NULL, "vdd-3.3-ch0", 3312000, 3312000, 0, 0, false},
+};
+
+static struct ath10k_wcn3990_clk_info clk_cfg[] = {
+   {NULL, "cxo_ref_clk_pin", 0, false},
+};
+
 static void ath10k_snoc_htc_tx_cb(struct ath10k_ce_pipe *ce_state);
 static void ath10k_snoc_htt_tx_cb(struct ath10k_ce_pipe *ce_state);
 static void ath10k_snoc_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
@@ -969,6 +983,315 @@ static void ath10k_snoc_release_resource(struct ath10k 
*ar)
ath10k_ce_free_pipe(ar, i);
 }
 
+static int ath10k_get_vreg_info(struct ath10k *ar, struct device *dev,
+   struct ath10k_wcn3990_vreg_info *vreg_info)
+{
+   char prop_name[ATH10K_MAX_PROP_SIZE];
+   struct regulator *reg;
+   const __be32 *prop;
+   int ret = 0;
+   int len;
+   int i;
+
+   reg = devm_regulator_get_optional(dev, vreg_info->name);
+
+   if (IS_ERR(reg)) {
+   ret = PTR_ERR(reg);
+
+   if (ret  == -EPROBE_DEFER) {
+   ath10k_err(ar, "EPROBE_DEFER for regulator: %s\n",
+  vreg_info->name);
+   return ret;
+   }
+   if (vreg_info->required) {
+   ath10k_err(ar, "Regulator %s doesn't exist: %d\n",
+  vreg_info->name, ret);
+   return ret;
+   }
+   ath10k_dbg(ar, ATH10K_DBG_SNOC,
+  "Optional regulator %s doesn't exist: %d\n",
+  vreg_info->name, ret);
+   goto done;
+   }
+
+   vreg_info->reg = reg;
+
+   snprintf(prop_name, ATH10K_MAX_PROP_SIZE,
+"qcom,%s-config", vreg_info->name);
+
+   prop = of_get_property(dev->of_node, prop_name, );
+
+   ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc got regulator config property %s 
len %d\n",
+  prop_name, len);
+
+   if (!prop || len < (2 * sizeof(__be32))) {
+   ath10k_warn(ar, "snoc regulator prop %s doesn't exist\n", 
prop_name);
+   goto done;
+   }
+
+   for (i = 0; (i * sizeof(__be32)) < len; i++) {
+   switch (i) {
+   case 0:
+   vreg_info->min_v = be32_to_cpup([0]);
+   break;
+   case 1:
+   vreg_info->max_v = be32_to_cpup([1]);
+   break;
+   case 2:
+   vreg_info->load_ua = be32_to_cpup([2]);
+   break;
+   case 3:
+   vreg_info->settle_delay = be32_to_cpup([3]);
+   break;
+   default:
+   ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc ignoring 
regulator property %s value %d\n",
+  prop_name, i);
+   break;
+   }
+   }
+
+done:
+   ath10k_dbg(ar, ATH10K_DBG_SNOC,
+  "snog vreg %s min_v %u max_v %u load_ua %u settle_delay 
%lu\n",
+  vreg_info->name, vreg_info->min_v, vreg_info->max_v,
+  vreg_info->load_ua, vreg_info->settle_delay);
+
+   return 0;
+}
+
+static int ath10k_get_clk_info(struct ath10k *ar, struct device *dev,
+  struct ath10k_wcn3990_clk_info *clk_info)
+{
+   struct clk *handle;
+   int ret = 0;
+
+   handle = devm_clk_get(dev, clk_info->name);
+   if (IS_ERR(handle)) {
+   ret = PTR_ERR(handle);
+   if (clk_info->required) {
+   ath10k_err(ar, "snoc clock %s isn't available: %d\n",
+  

[PATCH 10/13] ath10k: Add support to get target info from hif ops

2018-02-15 Thread Govind Singh
From: Rakesh Pillai <pill...@codeaurora.org>

wcn3990 does not use bmi.
Add support to get target info from hif ops.

Signed-off-by: Rakesh Pillai <pill...@codeaurora.org>
Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/core.c |  8 
 drivers/net/wireless/ath/ath10k/hif.h  | 13 +
 drivers/net/wireless/ath/ath10k/snoc.c | 10 ++
 3 files changed, 31 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index 51444d3..bcce875 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -2437,6 +2437,14 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
ar->hw->wiphy->hw_version = target_info.version;
break;
case ATH10K_BUS_SNOC:
+   memset(_info, 0, sizeof(target_info));
+   ret = ath10k_hif_get_target_info(ar, _info);
+   if (ret) {
+   ath10k_err(ar, "could not get target info (%d)\n", ret);
+   goto err_power_down;
+   }
+   ar->target_version = target_info.version;
+   ar->hw->wiphy->hw_version = target_info.version;
break;
default:
ath10k_err(ar, "incorrect hif bus type: %d\n", ar->hif.bus);
diff --git a/drivers/net/wireless/ath/ath10k/hif.h 
b/drivers/net/wireless/ath/ath10k/hif.h
index 7abb13c..1a59ea0 100644
--- a/drivers/net/wireless/ath/ath10k/hif.h
+++ b/drivers/net/wireless/ath/ath10k/hif.h
@@ -20,6 +20,7 @@
 
 #include 
 #include "core.h"
+#include "bmi.h"
 #include "debug.h"
 
 struct ath10k_hif_sg_item {
@@ -93,6 +94,9 @@ struct ath10k_hif_ops {
/* fetch calibration data from target eeprom */
int (*fetch_cal_eeprom)(struct ath10k *ar, void **data,
size_t *data_len);
+
+   int (*get_target_info)(struct ath10k *ar,
+  struct bmi_target_info *target_info);
 };
 
 static inline int ath10k_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
@@ -218,4 +222,13 @@ static inline int ath10k_hif_fetch_cal_eeprom(struct 
ath10k *ar,
return ar->hif.ops->fetch_cal_eeprom(ar, data, data_len);
 }
 
+static inline int ath10k_hif_get_target_info(struct ath10k *ar,
+struct bmi_target_info *tgt_info)
+{
+   if (!ar->hif.ops->get_target_info)
+   return -EOPNOTSUPP;
+
+   return ar->hif.ops->get_target_info(ar, tgt_info);
+}
+
 #endif /* _HIF_H_ */
diff --git a/drivers/net/wireless/ath/ath10k/snoc.c 
b/drivers/net/wireless/ath/ath10k/snoc.c
index 6d9ccce..1ef0d3b 100644
--- a/drivers/net/wireless/ath/ath10k/snoc.c
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -528,6 +528,15 @@ static int ath10k_snoc_hif_tx_sg(struct ath10k *ar, u8 
pipe_id,
return err;
 }
 
+static int ath10k_snoc_hif_get_target_info(struct ath10k *ar,
+  struct bmi_target_info *target_info)
+{
+   target_info->version = ATH10K_HW_WCN3990;
+   target_info->type = ATH10K_HW_WCN3990;
+
+   return 0;
+}
+
 static u16 ath10k_snoc_hif_get_free_queue_number(struct ath10k *ar, u8 pipe)
 {
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
@@ -787,6 +796,7 @@ static int ath10k_snoc_hif_power_up(struct ath10k *ar)
.tx_sg  = ath10k_snoc_hif_tx_sg,
.send_complete_check= ath10k_snoc_hif_send_complete_check,
.get_free_queue_number  = ath10k_snoc_hif_get_free_queue_number,
+   .get_target_info= ath10k_snoc_hif_get_target_info,
 };
 
 static const struct ath10k_bus_ops ath10k_snoc_bus_ops = {
-- 
1.9.1



[PATCH 09/13] ath10k: Modify hif tx paddr to dma_addr_t type

2018-02-15 Thread Govind Singh
Change type of hif sg tx paddr to dma_addr_t for
supporting target having addressing mode greater than
32 bit.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/hif.h | 2 +-
 drivers/net/wireless/ath/ath10k/pci.c | 8 
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/hif.h 
b/drivers/net/wireless/ath/ath10k/hif.h
index 6da4e33..7abb13c 100644
--- a/drivers/net/wireless/ath/ath10k/hif.h
+++ b/drivers/net/wireless/ath/ath10k/hif.h
@@ -26,7 +26,7 @@ struct ath10k_hif_sg_item {
u16 transfer_id;
void *transfer_context; /* NULL = tx completion callback not called */
void *vaddr; /* for debugging mostly */
-   u32 paddr;
+   dma_addr_t paddr;
u16 len;
 };
 
diff --git a/drivers/net/wireless/ath/ath10k/pci.c 
b/drivers/net/wireless/ath/ath10k/pci.c
index 8abaccc..cda8689 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -1375,8 +1375,8 @@ int ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
 
for (i = 0; i < n_items - 1; i++) {
ath10k_dbg(ar, ATH10K_DBG_PCI,
-  "pci tx item %d paddr 0x%08x len %d n_items %d\n",
-  i, items[i].paddr, items[i].len, n_items);
+  "pci tx item %d paddr %pad len %d n_items %d\n",
+  i, [i].paddr, items[i].len, n_items);
ath10k_dbg_dump(ar, ATH10K_DBG_PCI_DUMP, NULL, "pci tx data: ",
items[i].vaddr, items[i].len);
 
@@ -1393,8 +1393,8 @@ int ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
/* `i` is equal to `n_items -1` after for() */
 
ath10k_dbg(ar, ATH10K_DBG_PCI,
-  "pci tx item %d paddr 0x%08x len %d n_items %d\n",
-  i, items[i].paddr, items[i].len, n_items);
+  "pci tx item %d paddr %pad len %d n_items %d\n",
+  i, [i].paddr, items[i].len, n_items);
ath10k_dbg_dump(ar, ATH10K_DBG_PCI_DUMP, NULL, "pci tx data: ",
items[i].vaddr, items[i].len);
 
-- 
1.9.1



[PATCH 07/13] ath10k: Add hif tx methods for wcn3990

2018-02-15 Thread Govind Singh
Add hif tx/tx-complete methods for wcn3990
target.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/snoc.c | 123 -
 1 file changed, 120 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/snoc.c 
b/drivers/net/wireless/ath/ath10k/snoc.c
index 9d402e4..899f0a3 100644
--- a/drivers/net/wireless/ath/ath10k/snoc.c
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -42,6 +42,9 @@
"WLAN_CE_11",
 };
 
+static void ath10k_snoc_htc_tx_cb(struct ath10k_ce_pipe *ce_state);
+static void ath10k_snoc_htt_tx_cb(struct ath10k_ce_pipe *ce_state);
+
 static const struct ath10k_snoc_drv_priv drv_priv = {
.hw_rev = ATH10K_HW_WCN3990,
.dma_mask = DMA_BIT_MASK(37),
@@ -54,7 +57,7 @@
.src_nentries = 16,
.src_sz_max = 2048,
.dest_nentries = 0,
-   .send_cb = NULL,
+   .send_cb = ath10k_snoc_htc_tx_cb,
},
 
/* CE1: target->host HTT + HTC control */
@@ -81,7 +84,7 @@
.src_nentries = 32,
.src_sz_max = 2048,
.dest_nentries = 0,
-   .send_cb = NULL,
+   .send_cb = ath10k_snoc_htc_tx_cb,
},
 
/* CE4: host->target HTT */
@@ -90,7 +93,7 @@
.src_nentries = 256,
.src_sz_max = 256,
.dest_nentries = 0,
-   .send_cb = NULL,
+   .send_cb = ath10k_snoc_htt_tx_cb,
},
 
/* CE5: target->host HTT (ipa_uc->target ) */
@@ -359,6 +362,117 @@ static void ath10k_snoc_rx_post(struct ath10k *ar)
ath10k_snoc_rx_post_pipe(_snoc->pipe_info[i]);
 }
 
+static void ath10k_snoc_htc_tx_cb(struct ath10k_ce_pipe *ce_state)
+{
+   struct ath10k *ar = ce_state->ar;
+   struct sk_buff_head list;
+   struct sk_buff *skb;
+
+   __skb_queue_head_init();
+   while (ath10k_ce_completed_send_next(ce_state, (void **)) == 0) {
+   if (!skb)
+   continue;
+
+   __skb_queue_tail(, skb);
+   }
+
+   while ((skb = __skb_dequeue()))
+   ath10k_htc_tx_completion_handler(ar, skb);
+}
+
+static void ath10k_snoc_htt_tx_cb(struct ath10k_ce_pipe *ce_state)
+{
+   struct ath10k *ar = ce_state->ar;
+   struct sk_buff *skb;
+
+   while (ath10k_ce_completed_send_next(ce_state, (void **)) == 0) {
+   if (!skb)
+   continue;
+
+   dma_unmap_single(ar->dev, ATH10K_SKB_CB(skb)->paddr,
+skb->len, DMA_TO_DEVICE);
+   ath10k_htt_hif_tx_complete(ar, skb);
+   }
+}
+
+static int ath10k_snoc_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
+struct ath10k_hif_sg_item *items, int n_items)
+{
+   struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+   struct ath10k_ce *ce = ath10k_ce_priv(ar);
+   struct ath10k_snoc_pipe *snoc_pipe;
+   struct ath10k_ce_pipe *ce_pipe;
+   int err, i = 0;
+
+   snoc_pipe = _snoc->pipe_info[pipe_id];
+   ce_pipe = snoc_pipe->ce_hdl;
+   spin_lock_bh(>ce_lock);
+
+   for (i = 0; i < n_items - 1; i++) {
+   ath10k_dbg(ar, ATH10K_DBG_SNOC,
+  "snoc tx item %d paddr %pad len %d n_items %d\n",
+  i, [i].paddr, items[i].len, n_items);
+
+   err = ath10k_ce_send_nolock(ce_pipe,
+   items[i].transfer_context,
+   items[i].paddr,
+   items[i].len,
+   items[i].transfer_id,
+   CE_SEND_FLAG_GATHER);
+   if (err)
+   goto err;
+   }
+
+   ath10k_dbg(ar, ATH10K_DBG_SNOC,
+  "snoc tx item %d paddr %pad len %d n_items %d\n",
+  i, [i].paddr, items[i].len, n_items);
+
+   err = ath10k_ce_send_nolock(ce_pipe,
+   items[i].transfer_context,
+   items[i].paddr,
+   items[i].len,
+   items[i].transfer_id,
+   0);
+   if (err)
+   goto err;
+
+   spin_unlock_bh(>ce_lock);
+
+   return 0;
+
+err:
+   for (; i > 0; i--)
+   __ath10k_ce_send_revert(ce_pipe);
+
+   spin_unlock_bh(>ce_lock);
+   return err;
+}
+
+static u16 ath10k_snoc_hif_get_free_queue_number(struct ath10k *ar, u8 pipe)
+{
+   struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+
+   ath10k_dbg(ar, ATH10K_DBG_SNOC, "hif get free queue number\n");
+
+   return ath10k_ce_num_free_src_entries(ar_snoc->pipe_

[PATCH 08/13] ath10k: Add hif rx methods for wcn3990

2018-02-15 Thread Govind Singh
Add hif rx methods in rx path for wcn3990
target.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/snoc.c | 171 +
 1 file changed, 153 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/snoc.c 
b/drivers/net/wireless/ath/ath10k/snoc.c
index 899f0a3..6d9ccce 100644
--- a/drivers/net/wireless/ath/ath10k/snoc.c
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -26,6 +26,7 @@
 #include 
 #define  WCN3990_CE_ATTR_FLAGS 0
 #define ATH10K_SNOC_RX_POST_RETRY_MS 50
+#define CE_POLL_PIPE 4
 
 static char *const ce_name[] = {
"WLAN_CE_0",
@@ -44,6 +45,9 @@
 
 static void ath10k_snoc_htc_tx_cb(struct ath10k_ce_pipe *ce_state);
 static void ath10k_snoc_htt_tx_cb(struct ath10k_ce_pipe *ce_state);
+static void ath10k_snoc_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
+static void ath10k_snoc_htt_rx_cb(struct ath10k_ce_pipe *ce_state);
+static void ath10k_snoc_htt_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
 
 static const struct ath10k_snoc_drv_priv drv_priv = {
.hw_rev = ATH10K_HW_WCN3990,
@@ -53,7 +57,7 @@
 static struct ce_attr host_ce_config_wlan[] = {
/* CE0: host->target HTC control streams */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 16,
.src_sz_max = 2048,
.dest_nentries = 0,
@@ -62,25 +66,25 @@
 
/* CE1: target->host HTT + HTC control */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
.dest_nentries = 512,
-   .recv_cb = NULL,
+   .recv_cb = ath10k_snoc_htt_htc_rx_cb,
},
 
/* CE2: target->host WMI */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
.dest_nentries = 64,
-   .recv_cb = NULL,
+   .recv_cb = ath10k_snoc_htc_rx_cb,
},
 
/* CE3: host->target WMI */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 32,
.src_sz_max = 2048,
.dest_nentries = 0,
@@ -89,7 +93,7 @@
 
/* CE4: host->target HTT */
{
-   .flags = WCN3990_CE_ATTR_FLAGS | CE_ATTR_DIS_INTR,
+   .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR,
.src_nentries = 256,
.src_sz_max = 256,
.dest_nentries = 0,
@@ -98,16 +102,16 @@
 
/* CE5: target->host HTT (ipa_uc->target ) */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 512,
.dest_nentries = 512,
-   .recv_cb = NULL,
+   .recv_cb = ath10k_snoc_htt_rx_cb,
},
 
/* CE6: target autonomous hif_memcpy */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 0,
.dest_nentries = 0,
@@ -115,7 +119,7 @@
 
/* CE7: ce_diag, the Diagnostic Window */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 2,
.src_sz_max = 2048,
.dest_nentries = 2,
@@ -123,7 +127,7 @@
 
/* CE8: Target to uMC */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
.dest_nentries = 128,
@@ -131,29 +135,29 @@
 
/* CE9 target->host HTT */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
.dest_nentries = 512,
-   .recv_cb = NULL,
+   .recv_cb = ath10k_snoc_htt_htc_rx_cb,
},
 
/* CE10: target->host HTT */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
.dest_nentries = 512,
-   .recv_cb = NULL,
+   .recv_cb = ath10k_snoc_htt_htc_rx_cb,
},
 
/* CE11: target -> host PKTLOG */
{
-   .flags = WCN3990_CE_ATTR_FLAGS,
+   .flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
.dest_nentries = 512,
-   .recv_cb = NULL,
+   .recv_cb = ath10k_snoc_htt_htc_rx_cb,
},
 };
 
@@ -362,6 +366,82 @@ sta

[PATCH 06/13] ath10k: Add hif power-up/power-down methods

2018-02-15 Thread Govind Singh
Add hif power-up/power-down methods for wcn3990
target.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/snoc.c | 61 ++
 1 file changed, 61 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/snoc.c 
b/drivers/net/wireless/ath/ath10k/snoc.c
index a39eee7..9d402e4 100644
--- a/drivers/net/wireless/ath/ath10k/snoc.c
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -519,6 +519,65 @@ static int ath10k_snoc_hif_start(struct ath10k *ar)
return 0;
 }
 
+static int ath10k_snoc_init_pipes(struct ath10k *ar)
+{
+   int i, ret;
+
+   for (i = 0; i < CE_COUNT; i++) {
+   ret = ath10k_ce_init_pipe(ar, i, _ce_config_wlan[i]);
+   if (ret) {
+   ath10k_err(ar, "failed to initialize copy engine pipe 
%d: %d\n",
+  i, ret);
+   return ret;
+   }
+   }
+
+   return 0;
+}
+
+static int ath10k_snoc_wlan_enable(struct ath10k *ar)
+{
+   return 0;
+}
+
+static void ath10k_snoc_wlan_disable(struct ath10k *ar)
+{
+}
+
+static void ath10k_snoc_hif_power_down(struct ath10k *ar)
+{
+   ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power down\n");
+
+   ath10k_snoc_wlan_disable(ar);
+}
+
+static int ath10k_snoc_hif_power_up(struct ath10k *ar)
+{
+   int ret;
+
+   ath10k_dbg(ar, ATH10K_DBG_SNOC, "%s:WCN3990 driver state = %d\n",
+  __func__, ar->state);
+
+   ret = ath10k_snoc_wlan_enable(ar);
+   if (ret) {
+   ath10k_err(ar, "failed to enable wcn3990: %d\n", ret);
+   return ret;
+   }
+
+   ret = ath10k_snoc_init_pipes(ar);
+   if (ret) {
+   ath10k_err(ar, "failed to initialize CE: %d\n", ret);
+   goto err_wlan_enable;
+   }
+
+   return 0;
+
+err_wlan_enable:
+   ath10k_snoc_wlan_disable(ar);
+
+   return ret;
+}
+
 static const struct ath10k_hif_ops ath10k_snoc_hif_ops = {
.read32 = ath10k_snoc_read32,
.write32= ath10k_snoc_write32,
@@ -526,6 +585,8 @@ static int ath10k_snoc_hif_start(struct ath10k *ar)
.stop   = ath10k_snoc_hif_stop,
.map_service_to_pipe= ath10k_snoc_hif_map_service_to_pipe,
.get_default_pipe   = ath10k_snoc_hif_get_default_pipe,
+   .power_up   = ath10k_snoc_hif_power_up,
+   .power_down = ath10k_snoc_hif_power_down,
 };
 
 static const struct ath10k_bus_ops ath10k_snoc_bus_ops = {
-- 
1.9.1



[PATCH 04/13] ath10k: Add HTC services for WCN3990

2018-02-15 Thread Govind Singh
WCN3990 target uses 3 Copy engine(CE1/CE9/CE10) in RX path
and CE 11 for pktlog.
Add data path HTC ep services and PKTLOG services for WCN3990.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/htc.c | 6 ++
 drivers/net/wireless/ath/ath10k/htc.h | 4 
 2 files changed, 10 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/htc.c 
b/drivers/net/wireless/ath/ath10k/htc.c
index 492dc5b..8902720 100644
--- a/drivers/net/wireless/ath/ath10k/htc.c
+++ b/drivers/net/wireless/ath/ath10k/htc.c
@@ -542,8 +542,14 @@ static const char *htc_service_name(enum ath10k_htc_svc_id 
id)
return "NMI Data";
case ATH10K_HTC_SVC_ID_HTT_DATA_MSG:
return "HTT Data";
+   case ATH10K_HTC_SVC_ID_HTT_DATA2_MSG:
+   return "HTT Data";
+   case ATH10K_HTC_SVC_ID_HTT_DATA3_MSG:
+   return "HTT Data";
case ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS:
return "RAW";
+   case ATH10K_HTC_SVC_ID_HTT_LOG_MSG:
+   return "PKTLOG";
}
 
return "Unknown";
diff --git a/drivers/net/wireless/ath/ath10k/htc.h 
b/drivers/net/wireless/ath/ath10k/htc.h
index a2f8814..3487759 100644
--- a/drivers/net/wireless/ath/ath10k/htc.h
+++ b/drivers/net/wireless/ath/ath10k/htc.h
@@ -248,6 +248,7 @@ enum ath10k_htc_svc_gid {
ATH10K_HTC_SVC_GRP_WMI = 1,
ATH10K_HTC_SVC_GRP_NMI = 2,
ATH10K_HTC_SVC_GRP_HTT = 3,
+   ATH10K_LOG_SERVICE_GROUP = 6,
 
ATH10K_HTC_SVC_GRP_TEST = 254,
ATH10K_HTC_SVC_GRP_LAST = 255,
@@ -273,6 +274,9 @@ enum ath10k_htc_svc_id {
 
ATH10K_HTC_SVC_ID_HTT_DATA_MSG  = SVC(ATH10K_HTC_SVC_GRP_HTT, 0),
 
+   ATH10K_HTC_SVC_ID_HTT_DATA2_MSG = SVC(ATH10K_HTC_SVC_GRP_HTT, 1),
+   ATH10K_HTC_SVC_ID_HTT_DATA3_MSG = SVC(ATH10K_HTC_SVC_GRP_HTT, 2),
+   ATH10K_HTC_SVC_ID_HTT_LOG_MSG = SVC(ATH10K_LOG_SERVICE_GROUP, 0),
/* raw stream service (i.e. flash, tcmd, calibration apps) */
ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS = SVC(ATH10K_HTC_SVC_GRP_TEST, 0),
 };
-- 
1.9.1



[PATCH 05/13] ath10k: Map HTC services to tx/rx pipes for wcn3990

2018-02-15 Thread Govind Singh
Add mapping of HTC endpoint services supported
by wcn3990 target to tx/rx pipe.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/snoc.c | 168 +
 1 file changed, 168 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/snoc.c 
b/drivers/net/wireless/ath/ath10k/snoc.c
index dcd8bb7..a39eee7 100644
--- a/drivers/net/wireless/ath/ath10k/snoc.c
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -154,6 +154,116 @@
},
 };
 
+static struct service_to_pipe target_service_to_ce_map_wlan[] = {
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO),
+   __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
+   __cpu_to_le32(3),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(2),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BK),
+   __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
+   __cpu_to_le32(3),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BK),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(2),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BE),
+   __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
+   __cpu_to_le32(3),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BE),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(2),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VI),
+   __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
+   __cpu_to_le32(3),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VI),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(2),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_CONTROL),
+   __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
+   __cpu_to_le32(3),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_CONTROL),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(2),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_RSVD_CTRL),
+   __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
+   __cpu_to_le32(0),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_RSVD_CTRL),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(2),
+   },
+   { /* not used */
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS),
+   __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
+   __cpu_to_le32(0),
+   },
+   { /* not used */
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(2),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA_MSG),
+   __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
+   __cpu_to_le32(4),
+   },
+   {
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA_MSG),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(1),
+   },
+   { /* not used */
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS),
+   __cpu_to_le32(PIPEDIR_OUT),
+   __cpu_to_le32(5),
+   },
+   { /* in = DL = target -> host */
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA2_MSG),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(9),
+   },
+   { /* in = DL = target -> host */
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA3_MSG),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(10),
+   },
+   { /* in = DL = target -> host pktlog */
+   __cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_LOG_MSG),
+   __cpu_to_le32(PIPEDIR_IN),  /* in = DL = target -> host */
+   __cpu_to_le32(11),
+   },
+   /* (Additions here) */
+
+   { /* must be last */
+   __cpu_to_le32(0),
+   __cpu_to_le32(0),
+   __cpu_to_le32(0),
+   },
+};
+
 void ath10k_snoc_write32(struct ath10k *ar, u32 offset, u32 value)
 {
struct ath10k_snoc *ar_snoc = at

[PATCH 02/13] ath10k: add resource init and deinit for WCN3990

2018-02-15 Thread Govind Singh
Add methods for resource(memory, irq, HOST CE config)
initialization and de-initialization for WCN3990 target.

WCN3990 target uses 12 copy engine and following CE config.

[CE0] :host->target control and raw streams
[CE1] :target->host HTT
[CE2] :target->host WMI
[CE3] :host->target WMI
[CE4] :host->target HTT
[CE5] :reserved
[CE6] :Target autonomous HIF_memcpy
[CE7] :reserved
[CE8] :reserved
[CE9] :target->host HTT
[CE10] :target->host HTT
[CE11] :target -> host PKTLOG

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/snoc.c | 271 +
 1 file changed, 271 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/snoc.c 
b/drivers/net/wireless/ath/ath10k/snoc.c
index 30354a6..575355c 100644
--- a/drivers/net/wireless/ath/ath10k/snoc.c
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -24,12 +24,135 @@
 #include 
 #include 
 #include 
+#define  WCN3990_CE_ATTR_FLAGS 0
+
+static char *const ce_name[] = {
+   "WLAN_CE_0",
+   "WLAN_CE_1",
+   "WLAN_CE_2",
+   "WLAN_CE_3",
+   "WLAN_CE_4",
+   "WLAN_CE_5",
+   "WLAN_CE_6",
+   "WLAN_CE_7",
+   "WLAN_CE_8",
+   "WLAN_CE_9",
+   "WLAN_CE_10",
+   "WLAN_CE_11",
+};
 
 static const struct ath10k_snoc_drv_priv drv_priv = {
.hw_rev = ATH10K_HW_WCN3990,
.dma_mask = DMA_BIT_MASK(37),
 };
 
+static struct ce_attr host_ce_config_wlan[] = {
+   /* CE0: host->target HTC control streams */
+   {
+   .flags = WCN3990_CE_ATTR_FLAGS,
+   .src_nentries = 16,
+   .src_sz_max = 2048,
+   .dest_nentries = 0,
+   .send_cb = NULL,
+   },
+
+   /* CE1: target->host HTT + HTC control */
+   {
+   .flags = WCN3990_CE_ATTR_FLAGS,
+   .src_nentries = 0,
+   .src_sz_max = 2048,
+   .dest_nentries = 512,
+   .recv_cb = NULL,
+   },
+
+   /* CE2: target->host WMI */
+   {
+   .flags = WCN3990_CE_ATTR_FLAGS,
+   .src_nentries = 0,
+   .src_sz_max = 2048,
+   .dest_nentries = 64,
+   .recv_cb = NULL,
+   },
+
+   /* CE3: host->target WMI */
+   {
+   .flags = WCN3990_CE_ATTR_FLAGS,
+   .src_nentries = 32,
+   .src_sz_max = 2048,
+   .dest_nentries = 0,
+   .send_cb = NULL,
+   },
+
+   /* CE4: host->target HTT */
+   {
+   .flags = WCN3990_CE_ATTR_FLAGS | CE_ATTR_DIS_INTR,
+   .src_nentries = 256,
+   .src_sz_max = 256,
+   .dest_nentries = 0,
+   .send_cb = NULL,
+   },
+
+   /* CE5: target->host HTT (ipa_uc->target ) */
+   {
+   .flags = WCN3990_CE_ATTR_FLAGS,
+   .src_nentries = 0,
+   .src_sz_max = 512,
+   .dest_nentries = 512,
+   .recv_cb = NULL,
+   },
+
+   /* CE6: target autonomous hif_memcpy */
+   {
+   .flags = WCN3990_CE_ATTR_FLAGS,
+   .src_nentries = 0,
+   .src_sz_max = 0,
+   .dest_nentries = 0,
+   },
+
+   /* CE7: ce_diag, the Diagnostic Window */
+   {
+   .flags = WCN3990_CE_ATTR_FLAGS,
+   .src_nentries = 2,
+   .src_sz_max = 2048,
+   .dest_nentries = 2,
+   },
+
+   /* CE8: Target to uMC */
+   {
+   .flags = WCN3990_CE_ATTR_FLAGS,
+   .src_nentries = 0,
+   .src_sz_max = 2048,
+   .dest_nentries = 128,
+   },
+
+   /* CE9 target->host HTT */
+   {
+   .flags = WCN3990_CE_ATTR_FLAGS,
+   .src_nentries = 0,
+   .src_sz_max = 2048,
+   .dest_nentries = 512,
+   .recv_cb = NULL,
+   },
+
+   /* CE10: target->host HTT */
+   {
+   .flags = WCN3990_CE_ATTR_FLAGS,
+   .src_nentries = 0,
+   .src_sz_max = 2048,
+   .dest_nentries = 512,
+   .recv_cb = NULL,
+   },
+
+   /* CE11: target -> host PKTLOG */
+   {
+   .flags = WCN3990_CE_ATTR_FLAGS,
+   .src_nentries = 0,
+   .src_sz_max = 2048,
+   .dest_nentries = 512,
+   .recv_cb = NULL,
+   },
+};
+
 void ath10k_snoc_write32(struct ath10k *ar, u32 offset, u32 value)
 {
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
@@ -57,6 +180,119 @@ u32 ath10k_snoc_read32(struct ath10k *ar, u32 offset)
.write32= ath10k_snoc_write32,
 };
 
+static irqreturn_t ath10k_snoc_per_engine_handler(int irq, void *arg)
+{
+   return IRQ_HANDLED;
+}
+
+static int ath10k_snoc_requ

[PATCH 03/13] ath10k: Add hif start/stop methods for wcn3990 snoc layer

2018-02-15 Thread Govind Singh
Add hif start/stop callback for allocating/freeing buffers
on tx/rx pipe and enabling/disabling the tx/rx pipe
interrupts.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/snoc.c | 189 -
 1 file changed, 187 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/snoc.c 
b/drivers/net/wireless/ath/ath10k/snoc.c
index 575355c..dcd8bb7 100644
--- a/drivers/net/wireless/ath/ath10k/snoc.c
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #define  WCN3990_CE_ATTR_FLAGS 0
+#define ATH10K_SNOC_RX_POST_RETRY_MS 50
 
 static char *const ce_name[] = {
"WLAN_CE_0",
@@ -170,9 +171,193 @@ u32 ath10k_snoc_read32(struct ath10k *ar, u32 offset)
return val;
 }
 
+static int __ath10k_snoc_rx_post_buf(struct ath10k_snoc_pipe *pipe)
+{
+   struct ath10k_ce_pipe *ce_pipe = pipe->ce_hdl;
+   struct ath10k *ar = pipe->hif_ce_state;
+   struct ath10k_ce *ce = ath10k_ce_priv(ar);
+   struct sk_buff *skb;
+   dma_addr_t paddr;
+   int ret;
+
+   skb = dev_alloc_skb(pipe->buf_sz);
+   if (!skb)
+   return -ENOMEM;
+
+   WARN_ONCE((unsigned long)skb->data & 3, "unaligned skb");
+
+   paddr = dma_map_single(ar->dev, skb->data,
+  skb->len + skb_tailroom(skb),
+  DMA_FROM_DEVICE);
+   if (unlikely(dma_mapping_error(ar->dev, paddr))) {
+   ath10k_warn(ar, "failed to dma map snoc rx buf\n");
+   dev_kfree_skb_any(skb);
+   return -EIO;
+   }
+
+   ATH10K_SKB_RXCB(skb)->paddr = paddr;
+
+   spin_lock_bh(>ce_lock);
+   ret = ce_pipe->ops->ce_rx_post_buf(ce_pipe, skb, paddr);
+   spin_unlock_bh(>ce_lock);
+   if (ret) {
+   dma_unmap_single(ar->dev, paddr, skb->len + skb_tailroom(skb),
+DMA_FROM_DEVICE);
+   dev_kfree_skb_any(skb);
+   return ret;
+   }
+
+   return 0;
+}
+
+static void ath10k_snoc_rx_post_pipe(struct ath10k_snoc_pipe *pipe)
+{
+   struct ath10k *ar = pipe->hif_ce_state;
+   struct ath10k_ce *ce = ath10k_ce_priv(ar);
+   struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+   struct ath10k_ce_pipe *ce_pipe = pipe->ce_hdl;
+   int ret, num;
+
+   if (pipe->buf_sz == 0)
+   return;
+
+   if (!ce_pipe->dest_ring)
+   return;
+
+   spin_lock_bh(>ce_lock);
+   num = __ath10k_ce_rx_num_free_bufs(ce_pipe);
+   spin_unlock_bh(>ce_lock);
+   while (num--) {
+   ret = __ath10k_snoc_rx_post_buf(pipe);
+   if (ret) {
+   if (ret == -ENOSPC)
+   break;
+   ath10k_warn(ar, "failed to post rx buf: %d\n", ret);
+   mod_timer(_snoc->rx_post_retry, jiffies +
+ ATH10K_SNOC_RX_POST_RETRY_MS);
+   break;
+   }
+   }
+}
+
+static void ath10k_snoc_rx_post(struct ath10k *ar)
+{
+   struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+   int i;
+
+   for (i = 0; i < CE_COUNT; i++)
+   ath10k_snoc_rx_post_pipe(_snoc->pipe_info[i]);
+}
+
+static inline void ath10k_snoc_irq_disable(struct ath10k *ar)
+{
+   ath10k_ce_disable_interrupts(ar);
+}
+
+static inline void ath10k_snoc_irq_enable(struct ath10k *ar)
+{
+   ath10k_ce_enable_interrupts(ar);
+}
+
+static void ath10k_snoc_rx_pipe_cleanup(struct ath10k_snoc_pipe *snoc_pipe)
+{
+   struct ath10k_ce_pipe *ce_pipe;
+   struct ath10k_ce_ring *ce_ring;
+   struct sk_buff *skb;
+   struct ath10k *ar;
+   int i;
+
+   ar = snoc_pipe->hif_ce_state;
+   ce_pipe = snoc_pipe->ce_hdl;
+   ce_ring = ce_pipe->dest_ring;
+
+   if (!ce_ring)
+   return;
+
+   if (!snoc_pipe->buf_sz)
+   return;
+
+   for (i = 0; i < ce_ring->nentries; i++) {
+   skb = ce_ring->per_transfer_context[i];
+   if (!skb)
+   continue;
+
+   ce_ring->per_transfer_context[i] = NULL;
+
+   dma_unmap_single(ar->dev, ATH10K_SKB_RXCB(skb)->paddr,
+skb->len + skb_tailroom(skb),
+DMA_FROM_DEVICE);
+   dev_kfree_skb_any(skb);
+   }
+}
+
+static void ath10k_snoc_tx_pipe_cleanup(struct ath10k_snoc_pipe *snoc_pipe)
+{
+   struct ath10k_ce_pipe *ce_pipe;
+   struct ath10k_ce_ring *ce_ring;
+   struct ath10k_snoc *ar_snoc;
+   struct sk_buff *skb;
+   struct ath10k *ar;
+   int i;
+
+   ar = snoc_pipe->hif_ce_state;
+   ar_snoc = ath10k_snoc_priv(ar);
+   ce_pipe = snoc_pipe->ce_hdl

[PATCH 00/13] ***Set4: Add support of WCN3990 bus layer support ***

2018-02-15 Thread Govind Singh
This change adds support for integrated wcn3990 chipset on
MSM platforms. WCN3990 is 2x2 802.11ac chipset where wlan
subsystem is interfaced over system interconnect.
Wlan fw runs in Q6 DSP. WCN3990 chipset uses 12 copy engine
for host to target and target to host communication. It has
extra 2 copy engine in rx data path and packet log capability
is exposed via new HTC service over dedicated copy engine.
Each CE has dedicated interrupt of rx path and tx completion.

[CE0] :host->target control and raw streams
[CE1] :target->host HTT
[CE2] :target->host WMI
[CE3] :host->target WMI
[CE4] :host->target HTT
[CE5] :reserved
[CE6] :Target autonomous HIF_memcpy
[CE7] :reserved
[CE8] :reserved
[CE9] :target->host HTT
[CE10] :target->host HTT
[CE11] :target -> host PKTLOG



Govind Singh (11):
  ath10k: platform driver for WCN3990 SNOC WLAN module
  ath10k: add resource init and deinit for WCN3990
  ath10k: Add hif start/stop methods for wcn3990 snoc layer
  ath10k: Add HTC services for WCN3990
  ath10k: Map HTC services to tx/rx pipes for wcn3990
  ath10k: Add hif power-up/power-down methods
  ath10k: Add hif tx methods for wcn3990
  ath10k: Add hif rx methods for wcn3990
  ath10k: Modify hif tx paddr to dma_addr_t type
  ath10k: Vote for hardware resources for WCN3990
  dt: bindings: add bindings for wcn3990 wifi block

Rakesh Pillai (2):
  ath10k: Add support to get target info from hif ops
  ath10k: Check all CE for data if irq summary is not retained

 .../bindings/net/wireless/qcom,ath10k.txt  |   35 +
 drivers/net/wireless/ath/ath10k/Kconfig|8 +
 drivers/net/wireless/ath/ath10k/Makefile   |4 +
 drivers/net/wireless/ath/ath10k/ce.h   |   10 +-
 drivers/net/wireless/ath/ath10k/core.c |   21 +
 drivers/net/wireless/ath/ath10k/hif.h  |   15 +-
 drivers/net/wireless/ath/ath10k/htc.c  |6 +
 drivers/net/wireless/ath/ath10k/htc.h  |4 +
 drivers/net/wireless/ath/ath10k/hw.h   |3 +
 drivers/net/wireless/ath/ath10k/pci.c  |8 +-
 drivers/net/wireless/ath/ath10k/snoc.c | 1450 
 drivers/net/wireless/ath/ath10k/snoc.h |   95 ++
 12 files changed, 1651 insertions(+), 8 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath10k/snoc.c
 create mode 100644 drivers/net/wireless/ath/ath10k/snoc.h

-- 
1.9.1



[PATCH 01/13] ath10k: platform driver for WCN3990 SNOC WLAN module

2018-02-15 Thread Govind Singh
WCN3990 is integrated 802.11ac chipset with SNOC
bus interface. Add snoc layer driver registration
and associated ops.

WCN3990 support is not yet complete as cold-boot
handshake is done using qmi(Qualcomm-MSM-Interface)
and qmi client support will be added once qmi framework
is available.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/Kconfig  |   8 ++
 drivers/net/wireless/ath/ath10k/Makefile |   4 +
 drivers/net/wireless/ath/ath10k/snoc.c   | 153 +++
 drivers/net/wireless/ath/ath10k/snoc.h   |  76 +++
 4 files changed, 241 insertions(+)
 create mode 100644 drivers/net/wireless/ath/ath10k/snoc.c
 create mode 100644 drivers/net/wireless/ath/ath10k/snoc.h

diff --git a/drivers/net/wireless/ath/ath10k/Kconfig 
b/drivers/net/wireless/ath/ath10k/Kconfig
index deb5ae2..1b317eb 100644
--- a/drivers/net/wireless/ath/ath10k/Kconfig
+++ b/drivers/net/wireless/ath/ath10k/Kconfig
@@ -36,6 +36,14 @@ config ATH10K_USB
  This module adds experimental support for USB bus. Currently
  work in progress and will not fully work.
 
+config ATH10K_SNOC
+tristate "Qualcomm ath10k SNOC support (EXPERIMENTAL)"
+depends on ATH10K && ARCH_QCOM
+---help---
+  This module adds support for integrated WCN3990 chip connected
+  to system NOC(SNOC). Currently work in progress and will not
+  fully work.
+
 config ATH10K_DEBUG
bool "Atheros ath10k debugging"
depends on ATH10K
diff --git a/drivers/net/wireless/ath/ath10k/Makefile 
b/drivers/net/wireless/ath/ath10k/Makefile
index 6739ac2..390fde0 100644
--- a/drivers/net/wireless/ath/ath10k/Makefile
+++ b/drivers/net/wireless/ath/ath10k/Makefile
@@ -35,5 +35,9 @@ ath10k_sdio-y += sdio.o
 obj-$(CONFIG_ATH10K_USB) += ath10k_usb.o
 ath10k_usb-y += usb.o
 
+obj-$(CONFIG_ATH10K_SNOC) += ath10k_snoc.o
+ath10k_snoc-y += snoc.o \
+ce.o
+
 # for tracing framework to find trace.h
 CFLAGS_trace.o := -I$(src)
diff --git a/drivers/net/wireless/ath/ath10k/snoc.c 
b/drivers/net/wireless/ath/ath10k/snoc.c
new file mode 100644
index 000..30354a6
--- /dev/null
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include 
+#include 
+#include "debug.h"
+#include "hif.h"
+#include "htc.h"
+#include "ce.h"
+#include "snoc.h"
+#include 
+#include 
+#include 
+
+static const struct ath10k_snoc_drv_priv drv_priv = {
+   .hw_rev = ATH10K_HW_WCN3990,
+   .dma_mask = DMA_BIT_MASK(37),
+};
+
+void ath10k_snoc_write32(struct ath10k *ar, u32 offset, u32 value)
+{
+   struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+
+   iowrite32(value, ar_snoc->mem + offset);
+}
+
+u32 ath10k_snoc_read32(struct ath10k *ar, u32 offset)
+{
+   struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+   u32 val;
+
+   val = ioread32(ar_snoc->mem + offset);
+
+   return val;
+}
+
+static const struct ath10k_hif_ops ath10k_snoc_hif_ops = {
+   .read32 = ath10k_snoc_read32,
+   .write32= ath10k_snoc_write32,
+};
+
+static const struct ath10k_bus_ops ath10k_snoc_bus_ops = {
+   .read32 = ath10k_snoc_read32,
+   .write32= ath10k_snoc_write32,
+};
+
+static const struct of_device_id ath10k_snoc_dt_match[] = {
+   { .compatible = "qcom,wcn3990-wifi",
+.data = _priv,
+   },
+   { }
+};
+MODULE_DEVICE_TABLE(of, ath10k_snoc_dt_match);
+
+static int ath10k_snoc_probe(struct platform_device *pdev)
+{
+   const struct ath10k_snoc_drv_priv *drv_data;
+   const struct of_device_id *of_id;
+   struct ath10k_snoc *ar_snoc;
+   struct device *dev;
+   struct ath10k *ar;
+   int ret;
+
+   of_id = of_match_device(ath10k_snoc_dt_match, >dev);
+   if (!of_id) {
+   dev_err(>dev, "failed to find matching device tree id\n");
+   return -EINVAL;
+   }
+
+   drv_data = of_id->data;
+   dev = >dev;
+
+   ret = dma_set_mask_and_coherent(dev,

[PATCH] ath10k: Fix log message for hif power on failure

2018-02-04 Thread Govind Singh
HIF power-on failure is applicable to each underlying
bus type. Fix log message for hif power on failure.

Signed-off-by: Govind Singh <govi...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index 8716ea4..52a19c1 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2005-2011 Atheros Communications Inc.
  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -2423,7 +2424,7 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
 
ret = ath10k_hif_power_up(ar);
if (ret) {
-   ath10k_err(ar, "could not start pci hif (%d)\n", ret);
+   ath10k_err(ar, "could not power on hif bus (%d)\n", ret);
return ret;
}
 
-- 
1.9.1



RE: [RFC v3 03/11] ath10k: per target configurablity of various items

2018-01-08 Thread Govind Singh
>> A good point, I didn't thought of that during review. No time to investigate 
>> this right now, but maybe Rakesh and Govind (CCed) can comment?
Yes, ar->max_num_peers needs to be assigned with ar->hw_param->num_peers. This 
can create mismatch for wcn3990 target if we 
create multiple peers( TARGET_HL_10_TLV_NUM_PEERS vs TARGET_TLV_NUM_PEERS). We 
will fix this and raise this as separate change.

>>> Btw, what the heck is SNOC anyway?
SNOC is system NOC(network on chip). WCN3990 is integrated chipset connected 
over SNOC and only RF part is discrete to the SoC.

BR,
Govind

-Original Message-
From: Kalle Valo [mailto:kv...@codeaurora.org] 
Sent: Monday, January 8, 2018 7:12 PM
To: Erik Stromdahl <erik.stromd...@gmail.com>
Cc: linux-wireless@vger.kernel.org; ath...@lists.infradead.org; Rakesh Pillai 
<pill...@qti.qualcomm.com>; Govind Singh <govi...@qti.qualcomm.com>
Subject: Re: [RFC v3 03/11] ath10k: per target configurablity of various items

Erik Stromdahl <erik.stromd...@gmail.com> writes:

> On 2017-12-22 16:19, Kalle Valo wrote:
>
>> I was a bit torn about this, I definitely see the need for this but 
>> on the other hand it creates duplicate data (for example two entries 
>> for
>> QCA9377 chip). I guess this is the right approach, at least I cannot 
>> come up anything better.
>>
>> But this patch should be split into two:
>>
>> 1) add bus field to struct ath10k_hw_params
>>
>> 2) add max_num_peers field to struct ath10k_hw_params
>>
>> And it seems 2) is already implemented in commit 9f2992fea580 ("ath10k:
>> wmi: get wmi init parameter values from hw params"), so hopefully we 
>> only need 1) anymore.
>>
>
> Before commit 9f2992fea580a48135591873e5e3ac7e01444207,
> TARGET_TLV_NUM_PEERS was used both in the WMI TLV init command and as 
> the value of *max_num_peers* in *struct ath10k* (ar->max_num_peers).
>
> commit 9f2992fea580a48135591873e5e3ac7e01444207 does not set
> *ar->max_num_peers* to the value of *ar->hw_param->num_peers*.
>
> Is this correct?
>
> As I see it, there is a possible mismatch between what is written to 
> the device in the WMI init message and the value of *ar->max_num_peers*.
>
> Do we still need *max_num_peers* in *struct ath10k* now that we have 
> the
> *num_peers* member in *struct ath10k_hw_params*?

A good point, I didn't thought of that during review. No time to investigate 
this right now, but maybe Rakesh and Govind (CCed) can comment?

> I am currently rewriting my HL patches and I was thinking about adding 
> a separate patch related to this.

Yeah, a separate patch to sort that out is a good idea.

>>> --- a/drivers/net/wireless/ath/ath10k/core.c
>>> +++ b/drivers/net/wireless/ath/ath10k/core.c
>>> @@ -1663,9 +1663,19 @@ static int ath10k_init_hw_params(struct ath10k *ar)
>>> for (i = 0; i < ARRAY_SIZE(ath10k_hw_params_list); i++) {
>>> hw_params = _hw_params_list[i];
>>>   - if (hw_params->id == ar->target_version &&
>>> -   hw_params->dev_id == ar->dev_id)
>>> -   break;
>>> +   if (ar->is_high_latency) {
>>> +   /* High latency devices will use different fw depending
>>> +* on if it is a USB or SDIO device.
>>> +*/
>>> +   if (hw_params->bus == ar->hif.bus &&
>>> +   hw_params->id == ar->target_version &&
>>> +   hw_params->dev_id == ar->dev_id)
>>> +   break;
>>> +   } else {
>>> +   if (hw_params->id == ar->target_version &&
>>> +   hw_params->dev_id == ar->dev_id)
>>> +   break;
>>> +   }
>>
>> I don't like the is_high_latency test here at all. The bus field 
>> should be checked with all entries, not just high latency ones. And 
>> because of this even most of the hw_param bus field entries were not 
>> initialised.
>>
>> So only thing to do is to initialise the bus field for all the 
>> entries and the ugly test here can be removed. Just remember that 
>> QCA4019 uses AHB, I think all the rest is PCI. Or do we have AHB devices 
>> supported?
>
> I noticed that there has been introduced a new bus type (SNOC).
> Do you know which devices are SNOC devices?

SNOC is for wcn3990.

> Btw, what the heck is SNOC anyway?

I have forgetten already what the acronym meant but it's basically some sort of 
shared memory communication method with the firmware.

--
Kalle Valo


[PATCH 04/10] ath10k: Add support for 64 bit htt rx ring cfg

2017-12-21 Thread Govind Singh
WCN3900 target uses 64bit rx_ring_base_paddr and
fw_idx_shadow_reg_paddr fields in HTT rx ring cfg message.
These address points to the memory region where remote
ring empty buffers are allocated.
In order to add 64 bit htt rx ring cfg, define separate
64 bit htt rx ring cfg message and attach it in runtime
based on target_64bit hw param flag.

Signed-off-by: Govind Singh <govi...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/htt.c|   4 +-
 drivers/net/wireless/ath/ath10k/htt.h|  42 +++--
 drivers/net/wireless/ath/ath10k/htt_tx.c | 145 +++
 3 files changed, 168 insertions(+), 23 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt.c 
b/drivers/net/wireless/ath/ath10k/htt.c
index cd160b1..7176b0a 100644
--- a/drivers/net/wireless/ath/ath10k/htt.c
+++ b/drivers/net/wireless/ath/ath10k/htt.c
@@ -207,6 +207,8 @@ int ath10k_htt_init(struct ath10k *ar)
WARN_ON(1);
return -EINVAL;
}
+   ath10k_htt_set_tx_ops(htt);
+
return 0;
 }
 
@@ -258,7 +260,7 @@ int ath10k_htt_setup(struct ath10k_htt *htt)
if (status)
return status;
 
-   status = ath10k_htt_send_rx_ring_cfg_ll(htt);
+   status = htt->tx_ops->htt_send_rx_ring_cfg(htt);
if (status) {
ath10k_warn(ar, "failed to setup rx ring: %d\n",
status);
diff --git a/drivers/net/wireless/ath/ath10k/htt.h 
b/drivers/net/wireless/ath/ath10k/htt.h
index f3d5883..6aaf1d4 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -201,7 +201,7 @@ enum htt_rx_ring_flags {
 #define HTT_RX_RING_SIZE_MIN 128
 #define HTT_RX_RING_SIZE_MAX 2048
 
-struct htt_rx_ring_setup_ring {
+struct htt_rx_ring_setup_ring32 {
__le32 fw_idx_shadow_reg_paddr;
__le32 rx_ring_base_paddr;
__le16 rx_ring_len; /* in 4-byte words */
@@ -222,14 +222,40 @@ struct htt_rx_ring_setup_ring {
__le16 frag_info_offset;
 } __packed;
 
+struct htt_rx_ring_setup_ring64 {
+   __le64 fw_idx_shadow_reg_paddr;
+   __le64 rx_ring_base_paddr;
+   __le16 rx_ring_len; /* in 4-byte words */
+   __le16 rx_ring_bufsize; /* rx skb size - in bytes */
+   __le16 flags; /* %HTT_RX_RING_FLAGS_ */
+   __le16 fw_idx_init_val;
+
+   /* the following offsets are in 4-byte units */
+   __le16 mac80211_hdr_offset;
+   __le16 msdu_payload_offset;
+   __le16 ppdu_start_offset;
+   __le16 ppdu_end_offset;
+   __le16 mpdu_start_offset;
+   __le16 mpdu_end_offset;
+   __le16 msdu_start_offset;
+   __le16 msdu_end_offset;
+   __le16 rx_attention_offset;
+   __le16 frag_info_offset;
+} __packed;
+
 struct htt_rx_ring_setup_hdr {
u8 num_rings; /* supported values: 1, 2 */
__le16 rsvd0;
 } __packed;
 
-struct htt_rx_ring_setup {
+struct htt_rx_ring_setup_32 {
struct htt_rx_ring_setup_hdr hdr;
-   struct htt_rx_ring_setup_ring rings[0];
+   struct htt_rx_ring_setup_ring32 rings[0];
+} __packed;
+
+struct htt_rx_ring_setup_64 {
+   struct htt_rx_ring_setup_hdr hdr;
+   struct htt_rx_ring_setup_ring64 rings[0];
 } __packed;
 
 /*
@@ -1524,7 +1550,8 @@ struct htt_cmd {
struct htt_ver_req ver_req;
struct htt_mgmt_tx_desc mgmt_tx;
struct htt_data_tx_desc data_tx;
-   struct htt_rx_ring_setup rx_setup;
+   struct htt_rx_ring_setup_32 rx_setup_32;
+   struct htt_rx_ring_setup_64 rx_setup_64;
struct htt_stats_req stats_req;
struct htt_oob_sync_req oob_sync_req;
struct htt_aggr_conf aggr_conf;
@@ -1734,6 +1761,11 @@ struct ath10k_htt {
} tx_q_state;
 
bool tx_mem_allocated;
+   const struct ath10k_htt_tx_ops *tx_ops;
+};
+
+struct ath10k_htt_tx_ops {
+   int (*htt_send_rx_ring_cfg)(struct ath10k_htt *htt);
 };
 
 #define RX_HTT_HDR_STATUS_LEN 64
@@ -1845,5 +1877,5 @@ int ath10k_htt_tx(struct ath10k_htt *htt,
 void ath10k_htt_rx_pktlog_completion_handler(struct ath10k *ar,
 struct sk_buff *skb);
 int ath10k_htt_txrx_compl_task(struct ath10k *ar, int budget);
-
+void ath10k_htt_set_tx_ops(struct ath10k_htt *htt);
 #endif
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c 
b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 685faac..fad1664 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -607,12 +607,50 @@ int ath10k_htt_send_frag_desc_bank_cfg(struct ath10k_htt 
*htt)
return 0;
 }
 
-int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt)
+static void ath10k_htt_fill_rx_desc_offset_32(void *rx_ring)
+{
+   struct htt_rx_ring_setup_ring32 *ring =
+   (struct htt_rx_ring_setup_ring32 *)rx_ring;
+
+#define desc_offset(x) (offsetof(struct htt_rx_desc, x) / 4)
+   ring->mac80211_h

[PATCH 05/10] ath10k: Add support for 64 bit HTT frag descriptor

2017-12-21 Thread Govind Singh
WCN3990 target uses 64 bit frag descriptor and more
fields in TSO flag.
Add support for 64 bit HTT frag descriptor.

Signed-off-by: Govind Singh <govi...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/htt.c|   2 +-
 drivers/net/wireless/ath/ath10k/htt.h|  32 ++-
 drivers/net/wireless/ath/ath10k/htt_tx.c | 159 +++
 3 files changed, 167 insertions(+), 26 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt.c 
b/drivers/net/wireless/ath/ath10k/htt.c
index 7176b0a..8dc96a1 100644
--- a/drivers/net/wireless/ath/ath10k/htt.c
+++ b/drivers/net/wireless/ath/ath10k/htt.c
@@ -256,7 +256,7 @@ int ath10k_htt_setup(struct ath10k_htt *htt)
return status;
}
 
-   status = ath10k_htt_send_frag_desc_bank_cfg(htt);
+   status = htt->tx_ops->htt_send_frag_desc_bank_cfg(htt);
if (status)
return status;
 
diff --git a/drivers/net/wireless/ath/ath10k/htt.h 
b/drivers/net/wireless/ath/ath10k/htt.h
index 6aaf1d4..881af77 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -107,6 +107,14 @@ struct htt_msdu_ext_desc {
struct htt_data_tx_desc_frag frags[6];
 };
 
+struct htt_msdu_ext_desc_64 {
+   __le32 tso_flag[5];
+   __le16 ip_identification;
+   u8 flags;
+   u8 reserved;
+   struct htt_data_tx_desc_frag frags[6];
+};
+
 #defineHTT_MSDU_EXT_DESC_FLAG_IPV4_CSUM_ENABLE BIT(0)
 #defineHTT_MSDU_EXT_DESC_FLAG_UDP_IPV4_CSUM_ENABLE BIT(1)
 #defineHTT_MSDU_EXT_DESC_FLAG_UDP_IPV6_CSUM_ENABLE BIT(2)
@@ -1387,7 +1395,7 @@ struct htt_q_state_conf {
u8 pad[2];
 } __packed;
 
-struct htt_frag_desc_bank_cfg {
+struct htt_frag_desc_bank_cfg32 {
u8 info; /* HTT_FRAG_DESC_BANK_CFG_INFO_ */
u8 num_banks;
u8 desc_size;
@@ -1396,6 +1404,15 @@ struct htt_frag_desc_bank_cfg {
struct htt_q_state_conf q_state;
 } __packed;
 
+struct htt_frag_desc_bank_cfg64 {
+   u8 info; /* HTT_FRAG_DESC_BANK_CFG_INFO_ */
+   u8 num_banks;
+   u8 desc_size;
+   __le64 bank_base_addrs[HTT_FRAG_DESC_BANK_MAX];
+   struct htt_frag_desc_bank_id bank_id[HTT_FRAG_DESC_BANK_MAX];
+   struct htt_q_state_conf q_state;
+} __packed;
+
 #define HTT_TX_Q_STATE_ENTRY_COEFFICIENT   128
 #define HTT_TX_Q_STATE_ENTRY_FACTOR_MASK   0x3f
 #define HTT_TX_Q_STATE_ENTRY_FACTOR_LSB0
@@ -1555,7 +1572,8 @@ struct htt_cmd {
struct htt_stats_req stats_req;
struct htt_oob_sync_req oob_sync_req;
struct htt_aggr_conf aggr_conf;
-   struct htt_frag_desc_bank_cfg frag_desc_bank_cfg;
+   struct htt_frag_desc_bank_cfg32 frag_desc_bank_cfg32;
+   struct htt_frag_desc_bank_cfg64 frag_desc_bank_cfg64;
struct htt_tx_fetch_resp tx_fetch_resp;
};
 } __packed;
@@ -1741,7 +1759,11 @@ struct ath10k_htt {
 
struct {
dma_addr_t paddr;
-   struct htt_msdu_ext_desc *vaddr;
+   union {
+   struct htt_msdu_ext_desc *vaddr_desc_32;
+   struct htt_msdu_ext_desc_64 *vaddr_desc_64;
+   };
+   size_t size;
} frag_desc;
 
struct {
@@ -1766,6 +1788,9 @@ struct ath10k_htt {
 
 struct ath10k_htt_tx_ops {
int (*htt_send_rx_ring_cfg)(struct ath10k_htt *htt);
+   int (*htt_send_frag_desc_bank_cfg)(struct ath10k_htt *htt);
+   int (*htt_alloc_frag_desc)(struct ath10k_htt *htt);
+   void (*htt_free_frag_desc)(struct ath10k_htt *htt);
 };
 
 #define RX_HTT_HDR_STATUS_LEN 64
@@ -1845,7 +1870,6 @@ struct htt_rx_desc {
 bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb);
 int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt);
 int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie);
-int ath10k_htt_send_frag_desc_bank_cfg(struct ath10k_htt *htt);
 int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt);
 int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
u8 max_subfrms_ampdu,
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c 
b/drivers/net/wireless/ath/ath10k/htt_tx.c
index fad1664..5989489 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -256,23 +256,65 @@ static int ath10k_htt_tx_alloc_cont_txbuf(struct 
ath10k_htt *htt)
return 0;
 }
 
-static void ath10k_htt_tx_free_cont_frag_desc(struct ath10k_htt *htt)
+static void ath10k_htt_tx_free_cont_frag_desc_32(struct ath10k_htt *htt)
 {
size_t size;
 
-   if (!htt->frag_desc.vaddr)
+   if (!htt->frag_desc.vaddr_desc_32)
return;
 
-   size = htt->max_num_pending_tx * sizeof(struct htt_msdu_ext_desc);
+   size = htt->max_num_pending_tx *
+   sizeof(struct htt_msdu_ext_desc);
 
dma_fr

[PATCH 08/10] ath10k: Add paddrs_ring_64 support for 64bit target

2017-12-21 Thread Govind Singh
paddrs_ring_64 holds the physical device address of the
rx buffers that host SW provides for the MAC HW to fill.
Since this field is used in rx ring setup and rx ring
replenish in rx data path. Define separate methods
for handling 64 bit ring paddr and attach them dynamically
based on target_64bit hw param flag. Use u64 type
while popping paddr from the rx hash table for 64bit target.

Signed-off-by: Govind Singh <govi...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/htt.c|   1 +
 drivers/net/wireless/ath/ath10k/htt.h|  15 -
 drivers/net/wireless/ath/ath10k/htt_rx.c | 110 ++-
 3 files changed, 109 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt.c 
b/drivers/net/wireless/ath/ath10k/htt.c
index 8dc96a1..764fb26 100644
--- a/drivers/net/wireless/ath/ath10k/htt.c
+++ b/drivers/net/wireless/ath/ath10k/htt.c
@@ -208,6 +208,7 @@ int ath10k_htt_init(struct ath10k *ar)
return -EINVAL;
}
ath10k_htt_set_tx_ops(htt);
+   ath10k_htt_set_rx_ops(htt);
 
return 0;
 }
diff --git a/drivers/net/wireless/ath/ath10k/htt.h 
b/drivers/net/wireless/ath/ath10k/htt.h
index 3a43a48..805ff89 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -1708,7 +1708,10 @@ struct ath10k_htt {
 * rx buffers the host SW provides for the MAC HW to
 * fill.
 */
-   __le32 *paddrs_ring;
+   union {
+   __le64 *paddrs_ring_64;
+   __le32 *paddrs_ring_32;
+   };
 
/*
 * Base address of ring, as a "physical" device address
@@ -1814,6 +1817,7 @@ struct ath10k_htt {
 
bool tx_mem_allocated;
const struct ath10k_htt_tx_ops *tx_ops;
+   const struct ath10k_htt_rx_ops *rx_ops;
 };
 
 struct ath10k_htt_tx_ops {
@@ -1827,6 +1831,14 @@ struct ath10k_htt_tx_ops {
void (*htt_free_txbuff)(struct ath10k_htt *htt);
 };
 
+struct ath10k_htt_rx_ops {
+   size_t (*htt_get_rx_ring_size)(struct ath10k_htt *htt);
+   void (*htt_config_paddrs_ring)(struct ath10k_htt *htt, void *vaddr);
+   void (*htt_set_paddrs_ring)(struct ath10k_htt *htt, dma_addr_t paddr,
+   int idx);
+   void* (*htt_get_vaddr_ring)(struct ath10k_htt *htt);
+   void (*htt_reset_paddrs_ring)(struct ath10k_htt *htt, int idx);
+};
 #define RX_HTT_HDR_STATUS_LEN 64
 
 /* This structure layout is programmed via rx ring setup
@@ -1933,4 +1945,5 @@ void ath10k_htt_rx_pktlog_completion_handler(struct 
ath10k *ar,
 struct sk_buff *skb);
 int ath10k_htt_txrx_compl_task(struct ath10k *ar, int budget);
 void ath10k_htt_set_tx_ops(struct ath10k_htt *htt);
+void ath10k_htt_set_rx_ops(struct ath10k_htt *htt);
 #endif
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c 
b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 6fb6751..a53e3b6 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -33,7 +33,7 @@
 static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb);
 
 static struct sk_buff *
-ath10k_htt_rx_find_skb_paddr(struct ath10k *ar, u32 paddr)
+ath10k_htt_rx_find_skb_paddr(struct ath10k *ar, u64 paddr)
 {
struct ath10k_skb_rxcb *rxcb;
 
@@ -81,6 +81,60 @@ static void ath10k_htt_rx_ring_free(struct ath10k_htt *htt)
   htt->rx_ring.size * sizeof(htt->rx_ring.netbufs_ring[0]));
 }
 
+static size_t ath10k_htt_get_rx_ring_size_32(struct ath10k_htt *htt)
+{
+   return htt->rx_ring.size * sizeof(htt->rx_ring.paddrs_ring_32);
+}
+
+static size_t ath10k_htt_get_rx_ring_size_64(struct ath10k_htt *htt)
+{
+   return htt->rx_ring.size * sizeof(htt->rx_ring.paddrs_ring_64);
+}
+
+static void ath10k_htt_config_paddrs_ring_32(struct ath10k_htt *htt,
+void *vaddr)
+{
+   htt->rx_ring.paddrs_ring_32 = vaddr;
+}
+
+static void ath10k_htt_config_paddrs_ring_64(struct ath10k_htt *htt,
+void *vaddr)
+{
+   htt->rx_ring.paddrs_ring_64 = vaddr;
+}
+
+static void ath10k_htt_set_paddrs_ring_32(struct ath10k_htt *htt,
+ dma_addr_t paddr, int idx)
+{
+   htt->rx_ring.paddrs_ring_32[idx] = __cpu_to_le32(paddr);
+}
+
+static void ath10k_htt_set_paddrs_ring_64(struct ath10k_htt *htt,
+ dma_addr_t paddr, int idx)
+{
+   htt->rx_ring.paddrs_ring_64[idx] = __cpu_to_le64(paddr);
+}
+
+static void ath10k_htt_reset_paddrs_ring_32(struct ath10k_htt *htt, int idx)
+{
+   htt->rx_ring.paddrs_ring_32[idx] = 0;
+}
+
+static void ath10k_htt_reset_paddrs_ring_64(struct ath10k_htt *htt, int idx)
+{
+   htt->rx_ring.paddrs_ring_64[idx] = 0;
+}
+
+static void *ath10k_htt_get_vaddr_ring_32(s

[PATCH 01/10] ath10k: Add hw param for 64-bit address support

2017-12-21 Thread Govind Singh
From: Rakesh Pillai <pill...@qti.qualcomm.com>

WCN3990 target supports 37-bit addressing mode. In order
to accommodate extended address support, add hw param to
indicate if the target supports addressing above 32-bits.

Signed-off-by: Rakesh Pillai <pill...@qti.qualcomm.com>
Signed-off-by: Govind Singh <govi...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/core.c | 13 +
 drivers/net/wireless/ath/ath10k/hw.h   |  3 +++
 2 files changed, 16 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index ad61e64..031fe00 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -78,6 +78,7 @@
.num_peers = TARGET_TLV_NUM_PEERS,
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
+   .target_64bit = false,
},
{
.id = QCA9887_HW_1_0_VERSION,
@@ -105,6 +106,7 @@
.num_peers = TARGET_TLV_NUM_PEERS,
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
+   .target_64bit = false,
},
{
.id = QCA6174_HW_2_1_VERSION,
@@ -131,6 +133,7 @@
.num_peers = TARGET_TLV_NUM_PEERS,
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
+   .target_64bit = false,
},
{
.id = QCA6174_HW_2_1_VERSION,
@@ -157,6 +160,7 @@
.num_peers = TARGET_TLV_NUM_PEERS,
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
+   .target_64bit = false,
},
{
.id = QCA6174_HW_3_0_VERSION,
@@ -183,6 +187,7 @@
.num_peers = TARGET_TLV_NUM_PEERS,
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
+   .target_64bit = false,
},
{
.id = QCA6174_HW_3_2_VERSION,
@@ -212,6 +217,7 @@
.num_peers = TARGET_TLV_NUM_PEERS,
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
+   .target_64bit = false,
},
{
.id = QCA99X0_HW_2_0_DEV_VERSION,
@@ -244,6 +250,7 @@
.num_peers = TARGET_TLV_NUM_PEERS,
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
+   .target_64bit = false,
},
{
.id = QCA9984_HW_1_0_DEV_VERSION,
@@ -281,6 +288,7 @@
.num_peers = TARGET_TLV_NUM_PEERS,
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
+   .target_64bit = false,
},
{
.id = QCA9888_HW_2_0_DEV_VERSION,
@@ -317,6 +325,7 @@
.num_peers = TARGET_TLV_NUM_PEERS,
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
+   .target_64bit = false,
},
{
.id = QCA9377_HW_1_0_DEV_VERSION,
@@ -343,6 +352,7 @@
.num_peers = TARGET_TLV_NUM_PEERS,
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
+   .target_64bit = false,
},
{
.id = QCA9377_HW_1_1_DEV_VERSION,
@@ -371,6 +381,7 @@
.num_peers = TARGET_TLV_NUM_PEERS,
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
+   .target_64bit = false,
},
{
.id = QCA4019_HW_1_0_DEV_VERSION,
@@ -404,6 +415,7 @@
.num_peers = TARGET_TLV_NUM_PEERS,
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
+   .target_64bit = false,
},
{
.id = WCN3990_HW_1_0_DEV_VERSION,
@@ -422,6 +434,7 @@
.num_peers = TARGET_HL_10_TLV_NUM_PEERS,
.ast_skid_limit = TARGET_HL_10_TLV_AST_SKID_LIMIT,
.num_wds_entries = TARGET_HL_10_TLV_NUM_WDS_ENTRIES,
+   .target_64bit = true,
},
 };
 
diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net/wireless/ath/ath10k/hw.h
index 90ad39b..5d243f3 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -561,6 +561,9 @@ struct ath10k_hw_params {
u32 num_peers;
u32 ast_skid_limit;
u32 num_wds_entries;
+
+   /* Targets supporting physical addressing capability above 32-bits */
+   bool target_64bit;
 };
 
 struct htt_rx_desc;
-- 
1.9.1



[PATCH 03/10] ath10k: Add support for 64 bit HTT in-order indication msg

2017-12-21 Thread Govind Singh
WCN3990 target use 64bit msdu address in htt in-order
indication message. Add support for 64 bit msdu address in
HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND message.

Signed-off-by: Govind Singh <govi...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/htt.h| 12 +-
 drivers/net/wireless/ath/ath10k/htt_rx.c | 67 +---
 2 files changed, 72 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt.h 
b/drivers/net/wireless/ath/ath10k/htt.h
index 6305308..f3d5883 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -855,13 +855,23 @@ struct htt_rx_in_ord_msdu_desc {
u8 reserved;
 } __packed;
 
+struct htt_rx_in_ord_msdu_desc_ext {
+   __le64 msdu_paddr;
+   __le16 msdu_len;
+   u8 fw_desc;
+   u8 reserved;
+} __packed;
+
 struct htt_rx_in_ord_ind {
u8 info;
__le16 peer_id;
u8 vdev_id;
u8 reserved;
__le16 msdu_count;
-   struct htt_rx_in_ord_msdu_desc msdu_descs[0];
+   union {
+   struct htt_rx_in_ord_msdu_desc msdu_descs32[0];
+   struct htt_rx_in_ord_msdu_desc_ext msdu_descs64[0];
+   } __packed;
 } __packed;
 
 #define HTT_RX_IN_ORD_IND_INFO_TID_MASK0x001f
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c 
b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 7d295ee..6402189 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -408,12 +408,12 @@ static struct sk_buff *ath10k_htt_rx_pop_paddr(struct 
ath10k_htt *htt,
return msdu;
 }
 
-static int ath10k_htt_rx_pop_paddr_list(struct ath10k_htt *htt,
-   struct htt_rx_in_ord_ind *ev,
-   struct sk_buff_head *list)
+static int ath10k_htt_rx_pop_paddr32_list(struct ath10k_htt *htt,
+ struct htt_rx_in_ord_ind *ev,
+ struct sk_buff_head *list)
 {
struct ath10k *ar = htt->ar;
-   struct htt_rx_in_ord_msdu_desc *msdu_desc = ev->msdu_descs;
+   struct htt_rx_in_ord_msdu_desc *msdu_desc = ev->msdu_descs32;
struct htt_rx_desc *rxd;
struct sk_buff *msdu;
int msdu_count;
@@ -458,6 +458,55 @@ static int ath10k_htt_rx_pop_paddr_list(struct ath10k_htt 
*htt,
return 0;
 }
 
+static int ath10k_htt_rx_pop_paddr64_list(struct ath10k_htt *htt,
+ struct htt_rx_in_ord_ind *ev,
+ struct sk_buff_head *list)
+{
+   struct ath10k *ar = htt->ar;
+   struct htt_rx_in_ord_msdu_desc_ext *msdu_desc = ev->msdu_descs64;
+   struct htt_rx_desc *rxd;
+   struct sk_buff *msdu;
+   int msdu_count;
+   bool is_offload;
+   u64 paddr;
+
+   lockdep_assert_held(>rx_ring.lock);
+
+   msdu_count = __le16_to_cpu(ev->msdu_count);
+   is_offload = !!(ev->info & HTT_RX_IN_ORD_IND_INFO_OFFLOAD_MASK);
+
+   while (msdu_count--) {
+   paddr = __le64_to_cpu(msdu_desc->msdu_paddr);
+   msdu = ath10k_htt_rx_pop_paddr(htt, paddr);
+   if (!msdu) {
+   __skb_queue_purge(list);
+   return -ENOENT;
+   }
+
+   __skb_queue_tail(list, msdu);
+
+   if (!is_offload) {
+   rxd = (void *)msdu->data;
+
+   trace_ath10k_htt_rx_desc(ar, rxd, sizeof(*rxd));
+
+   skb_put(msdu, sizeof(*rxd));
+   skb_pull(msdu, sizeof(*rxd));
+   skb_put(msdu, __le16_to_cpu(msdu_desc->msdu_len));
+
+   if (!(__le32_to_cpu(rxd->attention.flags) &
+ RX_ATTENTION_FLAGS_MSDU_DONE)) {
+   ath10k_warn(htt->ar, "tried to pop an 
incomplete frame, oops!\n");
+   return -EIO;
+   }
+   }
+
+   msdu_desc++;
+   }
+
+   return 0;
+}
+
 int ath10k_htt_rx_alloc(struct ath10k_htt *htt)
 {
struct ath10k *ar = htt->ar;
@@ -1981,7 +2030,7 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, 
struct sk_buff *skb)
   "htt rx in ord vdev %i peer %i tid %i offload %i frag %i 
msdu count %i\n",
   vdev_id, peer_id, tid, offload, frag, msdu_count);
 
-   if (skb->len < msdu_count * sizeof(*resp->rx_in_ord_ind.msdu_descs)) {
+   if (skb->len < msdu_count * sizeof(*resp->rx_in_ord_ind.msdu_descs32)) {
ath10k_warn(ar, "dropping invalid in order rx indication\n");
return -EINVAL;
}
@@ -1990,7 +2039,13 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, 
struct sk_buff *skb)
 * extracted and processed.
   

[PATCH 10/10] ath10k: Add support for 64 bit ce descriptor

2017-12-21 Thread Govind Singh
WCN3990 CE descriptor uses 64bit address for
src/dst ring buffer. It has extended field for toeplitz
hash result, which is being used for HW assisted
hash results.

To accommodate WCN3990 descriptor, define new CE
descriptor for extended addressing mode and related
methods to handle the descriptor data.

Signed-off-by: Govind Singh <govi...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/ce.c  | 630 +-
 drivers/net/wireless/ath/ath10k/ce.h  |  48 ++-
 drivers/net/wireless/ath/ath10k/pci.c |   6 +-
 3 files changed, 587 insertions(+), 97 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/ce.c 
b/drivers/net/wireless/ath/ath10k/ce.c
index 9aa214b..48314b8 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -327,12 +327,12 @@ static inline void 
ath10k_ce_engine_int_status_clear(struct ath10k *ar,
  * Guts of ath10k_ce_send.
  * The caller takes responsibility for any needed locking.
  */
-int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
- void *per_transfer_context,
- dma_addr_t buffer,
- unsigned int nbytes,
- unsigned int transfer_id,
- unsigned int flags)
+static int _ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
+ void *per_transfer_context,
+ dma_addr_t buffer,
+ unsigned int nbytes,
+ unsigned int transfer_id,
+ unsigned int flags)
 {
struct ath10k *ar = ce_state->ar;
struct ath10k_ce_ring *src_ring = ce_state->src_ring;
@@ -384,6 +384,87 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
return ret;
 }
 
+static int _ath10k_ce_send_nolock_64(struct ath10k_ce_pipe *ce_state,
+void *per_transfer_context,
+dma_addr_t buffer,
+unsigned int nbytes,
+unsigned int transfer_id,
+unsigned int flags)
+{
+   struct ath10k *ar = ce_state->ar;
+   struct ath10k_ce_ring *src_ring = ce_state->src_ring;
+   struct ce_desc_64 *desc, sdesc;
+   unsigned int nentries_mask = src_ring->nentries_mask;
+   unsigned int sw_index = src_ring->sw_index;
+   unsigned int write_index = src_ring->write_index;
+   u32 ctrl_addr = ce_state->ctrl_addr;
+   __le32 *addr;
+   u32 desc_flags = 0;
+   int ret = 0;
+
+   if (test_bit(ATH10K_FLAG_CRASH_FLUSH, >dev_flags))
+   return -ESHUTDOWN;
+
+   if (nbytes > ce_state->src_sz_max)
+   ath10k_warn(ar, "%s: send more we can (nbytes: %d, max: %d)\n",
+   __func__, nbytes, ce_state->src_sz_max);
+
+   if (unlikely(CE_RING_DELTA(nentries_mask,
+  write_index, sw_index - 1) <= 0)) {
+   ret = -ENOSR;
+   goto exit;
+   }
+
+   desc = CE_SRC_RING_TO_DESC_64(src_ring->base_addr_owner_space,
+ write_index);
+
+   desc_flags |= SM(transfer_id, CE_DESC_FLAGS_META_DATA);
+
+   if (flags & CE_SEND_FLAG_GATHER)
+   desc_flags |= CE_DESC_FLAGS_GATHER;
+
+   if (flags & CE_SEND_FLAG_BYTE_SWAP)
+   desc_flags |= CE_DESC_FLAGS_BYTE_SWAP;
+
+   addr = (__le32 *)
+
+   flags |= upper_32_bits(buffer) & CE_DESC_FLAGS_GET_MASK;
+   addr[0] = __cpu_to_le32(buffer);
+   addr[1] = __cpu_to_le32(flags);
+   if (flags & CE_SEND_FLAG_GATHER)
+   addr[1] |= __cpu_to_le32(CE_WCN3990_DESC_FLAGS_GATHER);
+   else
+   addr[1] &= ~(__cpu_to_le32(CE_WCN3990_DESC_FLAGS_GATHER));
+
+   sdesc.nbytes = __cpu_to_le16(nbytes);
+   sdesc.flags  = __cpu_to_le16(desc_flags);
+
+   *desc = sdesc;
+
+   src_ring->per_transfer_context[write_index] = per_transfer_context;
+
+   /* Update Source Ring Write Index */
+   write_index = CE_RING_IDX_INCR(nentries_mask, write_index);
+
+   if (!(flags & CE_SEND_FLAG_GATHER))
+   ath10k_ce_src_ring_write_index_set(ar, ctrl_addr, write_index);
+
+   src_ring->write_index = write_index;
+exit:
+   return ret;
+}
+
+int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
+ void *per_transfer_context,
+ dma_addr_t buffer,
+ unsigned int nbytes,
+ unsigned int transfer_id,
+ unsigned int flags)
+{
+   return ce_state->ops->ce_send_nolock(ce_state, per_transfer_context,
+   buffer, nbytes, transfer_id, flags);
+}
+
 voi

[PATCH 07/10] ath10k: Add hw param for rx ring size support

2017-12-21 Thread Govind Singh
WCN3990 uses larger ring size in comparison to existing
ring size value.
Add rx ring size hw param for supporting different rx ring
size across multiple target.

Signed-off-by: Govind Singh <govi...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/core.c   | 13 +
 drivers/net/wireless/ath/ath10k/htt.h|  3 +++
 drivers/net/wireless/ath/ath10k/htt_rx.c |  5 +
 drivers/net/wireless/ath/ath10k/hw.h |  3 +++
 4 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index 031fe00..8374b05 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -79,6 +79,7 @@
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
.target_64bit = false,
+   .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
},
{
.id = QCA9887_HW_1_0_VERSION,
@@ -107,6 +108,7 @@
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
.target_64bit = false,
+   .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
},
{
.id = QCA6174_HW_2_1_VERSION,
@@ -134,6 +136,7 @@
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
.target_64bit = false,
+   .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
},
{
.id = QCA6174_HW_2_1_VERSION,
@@ -161,6 +164,7 @@
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
.target_64bit = false,
+   .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
},
{
.id = QCA6174_HW_3_0_VERSION,
@@ -188,6 +192,7 @@
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
.target_64bit = false,
+   .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
},
{
.id = QCA6174_HW_3_2_VERSION,
@@ -218,6 +223,7 @@
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
.target_64bit = false,
+   .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
},
{
.id = QCA99X0_HW_2_0_DEV_VERSION,
@@ -251,6 +257,7 @@
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
.target_64bit = false,
+   .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
},
{
.id = QCA9984_HW_1_0_DEV_VERSION,
@@ -289,6 +296,7 @@
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
.target_64bit = false,
+   .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
},
{
.id = QCA9888_HW_2_0_DEV_VERSION,
@@ -326,6 +334,7 @@
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
.target_64bit = false,
+   .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
},
{
.id = QCA9377_HW_1_0_DEV_VERSION,
@@ -353,6 +362,7 @@
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
.target_64bit = false,
+   .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
},
{
.id = QCA9377_HW_1_1_DEV_VERSION,
@@ -382,6 +392,7 @@
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
.target_64bit = false,
+   .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
},
{
.id = QCA4019_HW_1_0_DEV_VERSION,
@@ -416,6 +427,7 @@
.ast_skid_limit = 0x10,
.num_wds_entries = 0x20,
.target_64bit = false,
+   .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
},
{
.id = WCN3990_HW_1_0_DEV_VERSION,
@@ -435,6 +447,7 @@
.ast_skid_limit = TARGET_HL_10_TLV_AST_SKID_LIMIT,
.num_wds_entries = TARGET_HL_10_TLV_NUM_WDS_ENTRIES,
.target_64bit = true,
+   .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL_DUAL_MAC,
},
 };
 
diff --git a/drivers/net/wireless/ath/ath10k/htt.h 
b/drivers/net/wireless/ath/ath10k/htt.h
index ac5d720..3a43a48 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -224,6 +224,9 @@ enum htt_rx_ring_flags {
 
 #define HTT_RX_RING_SIZE_MIN 128
 #define HTT_RX_RING_SIZE_MAX 2048
+#define HTT_RX_RING_SIZE HTT_RX_RING_SIZE_MAX
+#define HTT_RX_RING_FILL_LEVEL (((HTT_RX_RING_SIZE) / 2) - 1)
+#define HTT_RX_RING_FILL_LEVEL_DUAL_MAC (HTT_RX_RING_SIZE - 1)
 
 struct htt_rx_ring_setup_ring32 {
__le32 fw_idx_shadow_reg_paddr;
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c 
b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 6402189..6fb6751 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c

[PATCH 02/10] ath10k: Update rx descriptor for WCN3990 target

2017-12-21 Thread Govind Singh
WCN3990 rx descriptor uses different offset of msdu start, msdu end,
ppdu end, rx pkt end and rx frag info.
To accommodate different offsets, define respective fields in
rx descriptor of WCN3990 target.

Signed-off-by: Govind Singh <govi...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/rx_desc.h | 50 +++
 1 file changed, 50 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/rx_desc.h 
b/drivers/net/wireless/ath/ath10k/rx_desc.h
index 28da143..210e4b16 100644
--- a/drivers/net/wireless/ath/ath10k/rx_desc.h
+++ b/drivers/net/wireless/ath/ath10k/rx_desc.h
@@ -210,6 +210,10 @@ struct rx_frag_info {
u8 ring1_more_count;
u8 ring2_more_count;
u8 ring3_more_count;
+   u8 ring4_more_count;
+   u8 ring5_more_count;
+   u8 ring6_more_count;
+   u8 ring7_more_count;
 } __packed;
 
 /*
@@ -471,10 +475,16 @@ struct rx_msdu_start_qca99x0 {
__le32 info2; /* %RX_MSDU_START_INFO2_ */
 } __packed;
 
+struct rx_msdu_start_wcn3990 {
+   __le32 info2; /* %RX_MSDU_START_INFO2_ */
+   __le32 info3; /* %RX_MSDU_START_INFO3_ */
+} __packed;
+
 struct rx_msdu_start {
struct rx_msdu_start_common common;
union {
struct rx_msdu_start_qca99x0 qca99x0;
+   struct rx_msdu_start_wcn3990 wcn3990;
} __packed;
 } __packed;
 
@@ -595,10 +605,23 @@ struct rx_msdu_end_qca99x0 {
__le32 info2;
 } __packed;
 
+struct rx_msdu_end_wcn3990 {
+   __le32 ipv6_crc;
+   __le32 tcp_seq_no;
+   __le32 tcp_ack_no;
+   __le32 info1;
+   __le32 info2;
+   __le32 rule_indication_0;
+   __le32 rule_indication_1;
+   __le32 rule_indication_2;
+   __le32 rule_indication_3;
+} __packed;
+
 struct rx_msdu_end {
struct rx_msdu_end_common common;
union {
struct rx_msdu_end_qca99x0 qca99x0;
+   struct rx_msdu_end_wcn3990 wcn3990;
} __packed;
 } __packed;
 
@@ -963,6 +986,12 @@ struct rx_pkt_end {
__le32 phy_timestamp_2;
 } __packed;
 
+struct rx_pkt_end_wcn3990 {
+   __le32 info0; /* %RX_PKT_END_INFO0_ */
+   __le64 phy_timestamp_1;
+   __le64 phy_timestamp_2;
+} __packed;
+
 #define RX_LOCATION_INFO0_RTT_FAC_LEGACY_MASK  0x3fff
 #define RX_LOCATION_INFO0_RTT_FAC_LEGACY_LSB   0
 #define RX_LOCATION_INFO0_RTT_FAC_VHT_MASK 0x1fff8000
@@ -998,6 +1027,12 @@ struct rx_location_info {
__le32 rx_location_info1; /* %RX_LOCATION_INFO1_ */
 } __packed;
 
+struct rx_location_info_wcn3990 {
+   __le32 rx_location_info0; /* %RX_LOCATION_INFO0_ */
+   __le32 rx_location_info1; /* %RX_LOCATION_INFO1_ */
+   __le32 rx_location_info2; /* %RX_LOCATION_INFO2_ */
+} __packed;
+
 enum rx_phy_ppdu_end_info0 {
RX_PHY_PPDU_END_INFO0_ERR_RADAR   = BIT(2),
RX_PHY_PPDU_END_INFO0_ERR_RX_ABORT= BIT(3),
@@ -1086,6 +1121,20 @@ struct rx_ppdu_end_qca9984 {
__le16 info1; /* %RX_PPDU_END_INFO1_ */
 } __packed;
 
+struct rx_ppdu_end_wcn3990 {
+   struct rx_pkt_end_wcn3990 rx_pkt_end;
+   struct rx_location_info_wcn3990 rx_location_info;
+   struct rx_phy_ppdu_end rx_phy_ppdu_end;
+   __le32 rx_timing_offset;
+   __le32 reserved_info_0;
+   __le32 reserved_info_1;
+   __le32 rx_antenna_info;
+   __le32 rx_coex_info;
+   __le32 rx_mpdu_cnt_info;
+   __le64 phy_timestamp_tx;
+   __le32 rx_bb_length;
+} __packed;
+
 struct rx_ppdu_end {
struct rx_ppdu_end_common common;
union {
@@ -1093,6 +1142,7 @@ struct rx_ppdu_end {
struct rx_ppdu_end_qca6174 qca6174;
struct rx_ppdu_end_qca99x0 qca99x0;
struct rx_ppdu_end_qca9984 qca9984;
+   struct rx_ppdu_end_wcn3990 wcn3990;
} __packed;
 } __packed;
 
-- 
1.9.1



[PATCH 09/10] ath10k: Use dma_addr_t for ce buffers to support 64bit target

2017-12-21 Thread Govind Singh
CE send and receive API's are using u32 ring address, which
truncates the address for target with 64bit addressing range.
Use dma_addr_t for ce buffers to support target with extended
addressing range.

Signed-off-by: Govind Singh <govi...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/ce.c  | 14 --
 drivers/net/wireless/ath/ath10k/ce.h  | 14 --
 drivers/net/wireless/ath/ath10k/pci.c |  4 ++--
 3 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/ce.c 
b/drivers/net/wireless/ath/ath10k/ce.c
index a8afd69..9aa214b 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -329,7 +329,7 @@ static inline void ath10k_ce_engine_int_status_clear(struct 
ath10k *ar,
  */
 int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
  void *per_transfer_context,
- u32 buffer,
+ dma_addr_t buffer,
  unsigned int nbytes,
  unsigned int transfer_id,
  unsigned int flags)
@@ -413,7 +413,7 @@ void __ath10k_ce_send_revert(struct ath10k_ce_pipe *pipe)
 
 int ath10k_ce_send(struct ath10k_ce_pipe *ce_state,
   void *per_transfer_context,
-  u32 buffer,
+   dma_addr_t buffer,
   unsigned int nbytes,
   unsigned int transfer_id,
   unsigned int flags)
@@ -459,7 +459,8 @@ int __ath10k_ce_rx_num_free_bufs(struct ath10k_ce_pipe 
*pipe)
return CE_RING_DELTA(nentries_mask, write_index, sw_index - 1);
 }
 
-int __ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr)
+int __ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx,
+   dma_addr_t paddr)
 {
struct ath10k *ar = pipe->ar;
struct ath10k_ce *ce = ath10k_ce_priv(ar);
@@ -508,7 +509,8 @@ void ath10k_ce_rx_update_write_idx(struct ath10k_ce_pipe 
*pipe, u32 nentries)
dest_ring->write_index = write_index;
 }
 
-int ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr)
+int ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx,
+ dma_addr_t paddr)
 {
struct ath10k *ar = pipe->ar;
struct ath10k_ce *ce = ath10k_ce_priv(ar);
@@ -593,7 +595,7 @@ int ath10k_ce_completed_recv_next(struct ath10k_ce_pipe 
*ce_state,
 
 int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state,
   void **per_transfer_contextp,
-  u32 *bufferp)
+  dma_addr_t *bufferp)
 {
struct ath10k_ce_ring *dest_ring;
unsigned int nentries_mask;
@@ -701,7 +703,7 @@ int ath10k_ce_completed_send_next_nolock(struct 
ath10k_ce_pipe *ce_state,
 /* NB: Modeled after ath10k_ce_completed_send_next */
 int ath10k_ce_cancel_send_next(struct ath10k_ce_pipe *ce_state,
   void **per_transfer_contextp,
-  u32 *bufferp,
+  dma_addr_t *bufferp,
   unsigned int *nbytesp,
   unsigned int *transfer_idp)
 {
diff --git a/drivers/net/wireless/ath/ath10k/ce.h 
b/drivers/net/wireless/ath/ath10k/ce.h
index bdec794..f36ad51 100644
--- a/drivers/net/wireless/ath/ath10k/ce.h
+++ b/drivers/net/wireless/ath/ath10k/ce.h
@@ -160,7 +160,7 @@ struct ath10k_ce {
  */
 int ath10k_ce_send(struct ath10k_ce_pipe *ce_state,
   void *per_transfer_send_context,
-  u32 buffer,
+  dma_addr_t buffer,
   unsigned int nbytes,
   /* 14 bits */
   unsigned int transfer_id,
@@ -168,7 +168,7 @@ int ath10k_ce_send(struct ath10k_ce_pipe *ce_state,
 
 int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
  void *per_transfer_context,
- u32 buffer,
+ dma_addr_t buffer,
  unsigned int nbytes,
  unsigned int transfer_id,
  unsigned int flags);
@@ -180,8 +180,10 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
 /*==Recv===*/
 
 int __ath10k_ce_rx_num_free_bufs(struct ath10k_ce_pipe *pipe);
-int __ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr);
-int ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr);
+int __ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx,
+   dma_addr_t paddr);
+int ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx,
+ dma_addr_t paddr);
 void ath10k_ce_rx_update_write_idx(struct ath10k_ce_pipe *pipe, u32 nentries);
 
 /* recv flags */
@@ -222,7 +224,7 @@ int ath10k_ce_alloc_pipe(struct ath10k *ar, int c

[PATCH 00/10] *** HTT/CE changes for WCN3990 ***

2017-12-21 Thread Govind Singh
This change adds HTT/CE layer support for WCN3990 target.
WCN3990 is the integrated chipset using System NOC
interconnect. This chipset uses 37 bit addressing mode,
due to this 64bit rx ring desc, tx desc and ce desc
support is added to enable extended addressing range.

These changes are validated on QCA6174 and WCN3990 target.

Govind Singh (9):
  ath10k: Update rx descriptor for WCN3990 target
  ath10k: Add support for 64 bit HTT in-order indication msg
  ath10k: Add support for 64 bit htt rx ring cfg
  ath10k: Add support for 64 bit HTT frag descriptor
  ath10k: Add support for htt_data_tx_desc_64 descriptor
  ath10k: Add hw param for rx ring size support
  ath10k: Add paddrs_ring_64 support for 64bit target
  ath10k: Use dma_addr_t for ce buffers to support 64bit target
  ath10k: Add support for 64 bit ce descriptor

Rakesh Pillai (1):
  ath10k: Add hw param for 64-bit address support

 drivers/net/wireless/ath/ath10k/ce.c  | 634 +-
 drivers/net/wireless/ath/ath10k/ce.h  |  58 ++-
 drivers/net/wireless/ath/ath10k/core.c|  26 ++
 drivers/net/wireless/ath/ath10k/htt.c |   7 +-
 drivers/net/wireless/ath/ath10k/htt.h | 142 ++-
 drivers/net/wireless/ath/ath10k/htt_rx.c  | 182 +++--
 drivers/net/wireless/ath/ath10k/htt_tx.c  | 598 +---
 drivers/net/wireless/ath/ath10k/hw.h  |   6 +
 drivers/net/wireless/ath/ath10k/mac.c |   2 +-
 drivers/net/wireless/ath/ath10k/pci.c |  10 +-
 drivers/net/wireless/ath/ath10k/rx_desc.h |  50 +++
 11 files changed, 1507 insertions(+), 208 deletions(-)

-- 
1.9.1



[PATCH 2/2] ath10k: Populate RSC counter to firmware

2017-12-08 Thread Govind Singh
Access Point (AP) re-transmits message 3 of 4 way handshake if
AP does not receive an appropriate response as acknowledgment.
As a result, the client may receive message 3 multiple times.
Each time it receives this message, it reinstalls the same
encryption key, and thereby reset the incremental transmit packet
number (nonce) and receive replay counter used by the encryption
protocol. By forcing nonce reuse in this manner, the encryption
protocol can be attacked, e.g., packets can be replayed, decrypted,
and/or forged.

Send RSC counter to FW in set key WMI command, so that FW can drop the
packet in PN check if received packet sequence no is less than current
RSC counter during group keys(GTK) exchange.

Tested on QCA6174 HW3.0 with firmware version RM.4.4.1.c1-00035-QCARMSWP-1.

Signed-off-by: Govind Singh <govi...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/mac.c | 1 +
 drivers/net/wireless/ath/ath10k/wmi-tlv.c | 3 +++
 drivers/net/wireless/ath/ath10k/wmi.h | 4 +++-
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c 
b/drivers/net/wireless/ath/ath10k/mac.c
index 06383e7..43f78e3 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -226,6 +226,7 @@ static int ath10k_send_key(struct ath10k_vif *arvif,
.macaddr = macaddr,
};
 
+   memcpy(arg.key_rsc_counter, key->rx_pn, IEEE80211_MAX_PN_LEN);
lockdep_assert_held(>ar->conf_mutex);
 
switch (key->cipher) {
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c 
b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 7616c1c..e7148f0 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -1849,6 +1849,9 @@ static struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct 
ath10k *ar)
if (arg->macaddr)
ether_addr_copy(cmd->peer_macaddr.addr, arg->macaddr);
 
+   memcpy(>key_rsc_counter, >key_rsc_counter,
+  WMI_MAX_RSC_LEN);
+
ptr += sizeof(*tlv);
ptr += sizeof(*cmd);
 
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h 
b/drivers/net/wireless/ath/ath10k/wmi.h
index c02b21c..4849787 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -4752,6 +4752,7 @@ struct wmi_key_seq_counter {
 #define WMI_CIPHER_CKIP 0x6
 #define WMI_CIPHER_AES_CMAC 0x7
 #define WMI_CIPHER_AES_GCM  0x8
+#define WMI_MAX_RSC_LEN 0x8
 
 struct wmi_vdev_install_key_cmd {
__le32 vdev_id;
@@ -4759,7 +4760,7 @@ struct wmi_vdev_install_key_cmd {
__le32 key_idx;
__le32 key_flags;
__le32 key_cipher; /* %WMI_CIPHER_ */
-   struct wmi_key_seq_counter key_rsc_counter;
+   u8 key_rsc_counter[WMI_MAX_RSC_LEN];
struct wmi_key_seq_counter key_global_rsc_counter;
struct wmi_key_seq_counter key_tsc_counter;
u8 wpi_key_rsc_counter[16];
@@ -4782,6 +4783,7 @@ struct wmi_vdev_install_key_arg {
u32 key_txmic_len;
u32 key_rxmic_len;
const void *key_data;
+   u8 key_rsc_counter[IEEE80211_MAX_PN_LEN];
 };
 
 /*
-- 
1.9.1



[PATCH 1/2] mac80211: Populate RSC counter in set_key method

2017-12-08 Thread Govind Singh
Send RSC counter to driver in set_key method, so that FW/driver
can drop the packet in PN check if received packet sequence
no is less than current RSC counter during group keys(GTK)
exchange.

Signed-off-by: Govind Singh <govi...@qti.qualcomm.com>
---
 include/net/mac80211.h | 6 --
 net/mac80211/key.c | 6 ++
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 2ee4af2..2f0c91d 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1564,6 +1564,8 @@ enum ieee80211_key_flags {
IEEE80211_KEY_FLAG_RESERVE_TAILROOM = BIT(7),
 };
 
+#define IEEE80211_MAX_PN_LEN   16
+
 /**
  * struct ieee80211_key_conf - key information
  *
@@ -1586,6 +1588,7 @@ enum ieee80211_key_flags {
  * - Temporal Authenticator Rx MIC Key (64 bits)
  * @icv_len: The ICV length for this key type
  * @iv_len: The IV length for this key type
+ * @rx_pn: Last received packet number, must be in little endian.
  */
 struct ieee80211_key_conf {
atomic64_t tx_pn;
@@ -1596,11 +1599,10 @@ struct ieee80211_key_conf {
u8 flags;
s8 keyidx;
u8 keylen;
+   u8 rx_pn[IEEE80211_MAX_PN_LEN];
u8 key[0];
 };
 
-#define IEEE80211_MAX_PN_LEN   16
-
 #define TKIP_PN_TO_IV16(pn) ((u16)(pn & 0x))
 #define TKIP_PN_TO_IV32(pn) ((u32)((pn >> 16) & 0x))
 
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 9380493..15e1822 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -538,6 +538,12 @@ struct ieee80211_key *
}
memcpy(key->conf.key, key_data, key_len);
INIT_LIST_HEAD(>list);
+   /* Assign receive packet sequence no, rx_pn remains in
+* little endian format as seq is guaranteed to be in little
+* endian format.
+*/
+   if (seq)
+   memcpy(>conf.rx_pn, seq, seq_len);
 
return key;
 }
-- 
1.9.1



[PATCH 2/2] ath10k: Add copy engine register MAP for wcn3990 target

2017-06-27 Thread Govind Singh
Copy engine is a host to target communication interface
between wlan firmware and wlan wcn3990 platform driver. Add copy
engine register map for wcn3990 wlan module. This add support
for the copy engine source/destination ring configuration for
wcn3990 chipset.

Signed-off-by: Govind Singh <govi...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/core.c |   5 ++
 drivers/net/wireless/ath/ath10k/hw.c   | 150 +
 drivers/net/wireless/ath/ath10k/hw.h   |   9 ++
 drivers/net/wireless/ath/ath10k/pci.c  |   4 +
 4 files changed, 168 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index 38dbdd5..b55196c 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -2474,6 +2474,11 @@ struct ath10k *ath10k_core_create(size_t priv_size, 
struct device *dev,
ar->hw_ce_regs = _ce_regs;
ar->hw_values = _values;
break;
+   case ATH10K_HW_WCN3990:
+   ar->regs = _regs;
+   ar->hw_ce_regs = _ce_regs;
+   ar->hw_values = _values;
+   break;
default:
ath10k_err(ar, "unsupported core hardware revision %d\n",
   hw_rev);
diff --git a/drivers/net/wireless/ath/ath10k/hw.c 
b/drivers/net/wireless/ath/ath10k/hw.c
index afb0c01..a860691 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -192,6 +192,156 @@
.ce_desc_meta_data_lsb  = 4,
 };
 
+const struct ath10k_hw_regs wcn3990_regs = {
+   .rtc_soc_base_address   = 0x,
+   .rtc_wmac_base_address  = 0x,
+   .soc_core_base_address  = 0x,
+   .ce_wrapper_base_address= 0x0024C000,
+   .ce0_base_address   = 0x0024,
+   .ce1_base_address   = 0x00241000,
+   .ce2_base_address   = 0x00242000,
+   .ce3_base_address   = 0x00243000,
+   .ce4_base_address   = 0x00244000,
+   .ce5_base_address   = 0x00245000,
+   .ce6_base_address   = 0x00246000,
+   .ce7_base_address   = 0x00247000,
+   .ce8_base_address   = 0x00248000,
+   .ce9_base_address   = 0x00249000,
+   .ce10_base_address  = 0x0024A000,
+   .ce11_base_address  = 0x0024B000,
+   .soc_chip_id_address= 0x00f0,
+   .soc_reset_control_si0_rst_mask = 0x0001,
+   .soc_reset_control_ce_rst_mask  = 0x0100,
+   .ce_wrap_intr_sum_host_msi_lsb  = 0x000c,
+   .ce_wrap_intr_sum_host_msi_mask = 0x00fff000,
+   .pcie_intr_fw_mask  = 0x0010,
+};
+
+static struct ath10k_hw_ce_regs_addr_map wcn3990_src_ring = {
+   .msb= 0x0010,
+   .lsb= 0x0010,
+   .mask   = GENMASK(17, 17),
+};
+
+static struct ath10k_hw_ce_regs_addr_map wcn3990_dst_ring = {
+   .msb= 0x0012,
+   .lsb= 0x0012,
+   .mask   = GENMASK(18, 18),
+};
+
+static struct ath10k_hw_ce_regs_addr_map wcn3990_dmax = {
+   .msb= 0x,
+   .lsb= 0x,
+   .mask   = GENMASK(15, 0),
+};
+
+static struct ath10k_hw_ce_ctrl1 wcn3990_ctrl1 = {
+   .addr   = 0x0018,
+   .src_ring   = _src_ring,
+   .dst_ring   = _dst_ring,
+   .dmax   = _dmax,
+};
+
+static struct ath10k_hw_ce_regs_addr_map wcn3990_host_ie_cc = {
+   .mask   = GENMASK(0, 0),
+};
+
+static struct ath10k_hw_ce_host_ie wcn3990_host_ie = {
+   .copy_complete  = _host_ie_cc,
+};
+
+static struct ath10k_hw_ce_host_wm_regs wcn3990_wm_reg = {
+   .dstr_lmask = 0x0010,
+   .dstr_hmask = 0x0008,
+   .srcr_lmask = 0x0004,
+   .srcr_hmask = 0x0002,
+   .cc_mask= 0x0001,
+   .wm_mask= 0x001E,
+   .addr   = 0x0030,
+};
+
+static struct ath10k_hw_ce_misc_regs wcn3990_misc_reg = {
+   .axi_err= 0x0100,
+   .dstr_add_err   = 0x0200,
+   .srcr_len_err   = 0x0100,
+   .dstr_mlen_vio  = 0x0080,
+   .dstr_overflow  = 0x0040,
+   .srcr_overflow  = 0x0020,
+   .err_mask   = 0x03E0,
+   .addr   = 0x0038,
+};
+
+static struct ath10k_hw_ce_regs_addr_map wcn3990_src_wm_low = {
+   .msb= 0x,
+   .lsb= 0x0010,
+   .mask   = GENMASK(31, 16),
+};
+
+static struct ath10k_hw_ce_regs_addr_map wcn3990_src_wm_high = {
+   .msb= 0x000f,
+   .lsb= 0x,
+   .mask   = GENMASK(15, 0),
+};
+
+static struct ath10k_hw_ce_dst_

[PATCH 1/2] ath10k: Make CE layer bus agnostic

2017-06-27 Thread Govind Singh
Remove bus specific dependencies from CE layer
to have common CE layer across multiple targets.
This is required for adding support for WCN3990
chipset support as WCN3990 chipset uses SNOC
bus interface with Copy Engine endpoint.

Signed-off-by: Govind Singh <govi...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/ahb.c  |   3 +-
 drivers/net/wireless/ath/ath10k/ce.c   | 299 ++---
 drivers/net/wireless/ath/ath10k/ce.h   |  30 +++-
 drivers/net/wireless/ath/ath10k/core.h |   2 +
 drivers/net/wireless/ath/ath10k/pci.c  |  51 +++---
 drivers/net/wireless/ath/ath10k/pci.h  |  14 +-
 6 files changed, 224 insertions(+), 175 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/ahb.c 
b/drivers/net/wireless/ath/ath10k/ahb.c
index da770af..b36dd792 100644
--- a/drivers/net/wireless/ath/ath10k/ahb.c
+++ b/drivers/net/wireless/ath/ath10k/ahb.c
@@ -787,8 +787,9 @@ static int ath10k_ahb_probe(struct platform_device *pdev)
ar_pci->mem = ar_ahb->mem;
ar_pci->mem_len = ar_ahb->mem_len;
ar_pci->ar = ar;
-   ar_pci->bus_ops = _ahb_bus_ops;
+   ar_pci->ce.bus_ops = _ahb_bus_ops;
ar_pci->targ_cpu_to_ce_addr = ath10k_ahb_qca4019_targ_cpu_to_ce_addr;
+   ar->ce_priv = _pci->ce;
 
ret = ath10k_pci_setup_resource(ar);
if (ret) {
diff --git a/drivers/net/wireless/ath/ath10k/ce.c 
b/drivers/net/wireless/ath/ath10k/ce.c
index 9e620b4..3b3481c 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -16,7 +16,6 @@
  */
 
 #include "hif.h"
-#include "pci.h"
 #include "ce.h"
 #include "debug.h"
 
@@ -33,7 +32,7 @@
  * Each ring consists of a number of descriptors which specify
  * an address, length, and meta-data.
  *
- * Typically, one side of the PCIe interconnect (Host or Target)
+ * Typically, one side of the PCIe/AHB/SNOC interconnect (Host or Target)
  * controls one ring and the other side controls the other ring.
  * The source side chooses when to initiate a transfer and it
  * chooses what to send (buffer address, length). The destination
@@ -73,57 +72,71 @@
return ((offset & addr_map->mask) >> (addr_map->lsb));
 }
 
+static inline u32 ath10k_ce_read32(struct ath10k *ar, u32 offset)
+{
+   struct ath10k_ce *ce = ath10k_ce_priv(ar);
+
+   return ce->bus_ops->read32(ar, offset);
+}
+
+static inline void ath10k_ce_write32(struct ath10k *ar, u32 offset, u32 value)
+{
+   struct ath10k_ce *ce = ath10k_ce_priv(ar);
+
+   ce->bus_ops->write32(ar, offset, value);
+}
+
 static inline void ath10k_ce_dest_ring_write_index_set(struct ath10k *ar,
   u32 ce_ctrl_addr,
   unsigned int n)
 {
-   ath10k_pci_write32(ar, ce_ctrl_addr +
-   ar->hw_ce_regs->dst_wr_index_addr, n);
+   ath10k_ce_write32(ar, ce_ctrl_addr +
+ ar->hw_ce_regs->dst_wr_index_addr, n);
 }
 
 static inline u32 ath10k_ce_dest_ring_write_index_get(struct ath10k *ar,
  u32 ce_ctrl_addr)
 {
-   return ath10k_pci_read32(ar, ce_ctrl_addr +
-   ar->hw_ce_regs->dst_wr_index_addr);
+   return ath10k_ce_read32(ar, ce_ctrl_addr +
+   ar->hw_ce_regs->dst_wr_index_addr);
 }
 
 static inline void ath10k_ce_src_ring_write_index_set(struct ath10k *ar,
  u32 ce_ctrl_addr,
  unsigned int n)
 {
-   ath10k_pci_write32(ar, ce_ctrl_addr +
-   ar->hw_ce_regs->sr_wr_index_addr, n);
+   ath10k_ce_write32(ar, ce_ctrl_addr +
+ ar->hw_ce_regs->sr_wr_index_addr, n);
 }
 
 static inline u32 ath10k_ce_src_ring_write_index_get(struct ath10k *ar,
 u32 ce_ctrl_addr)
 {
-   return ath10k_pci_read32(ar, ce_ctrl_addr +
-   ar->hw_ce_regs->sr_wr_index_addr);
+   return ath10k_ce_read32(ar, ce_ctrl_addr +
+   ar->hw_ce_regs->sr_wr_index_addr);
 }
 
 static inline u32 ath10k_ce_src_ring_read_index_get(struct ath10k *ar,
u32 ce_ctrl_addr)
 {
-   return ath10k_pci_read32(ar, ce_ctrl_addr +
-   ar->hw_ce_regs->current_srri_addr);
+   return ath10k_ce_read32(ar, ce_ctrl_addr +
+   ar->hw_ce_regs->current_srri_addr);
 }
 
 static inline void ath10k_ce_src_ring_base_addr_set(struct ath10k *ar,
u32 ce_ctrl_addr,
unsigned int addr)
 {
-   ath10k_pci_write32(a