qcacmn: Introduce APIs needed by WIN

Added new APIs ce_batch_send and ce_send_single
only used by WIN.

Acked-by: Varsha Mishra <varsham@codeaurora.org>
Change-Id: I55d86d692455be118734f6e0a13e0e58c227b1a0
CRs-Fixed: 1009050
diff --git a/hif/src/ce/ce_api.h b/hif/src/ce/ce_api.h
index fd757b2..7a15365 100644
--- a/hif/src/ce/ce_api.h
+++ b/hif/src/ce/ce_api.h
@@ -114,6 +114,7 @@
 #define CE_WM_FLAG_SEND_LOW    2
 #define CE_WM_FLAG_RECV_HIGH   4
 #define CE_WM_FLAG_RECV_LOW    8
+#define CE_HTT_TX_CE           4
 
 /* A list of buffers to be gathered and sent */
 struct ce_sendlist;
@@ -155,6 +156,17 @@
 #endif
 void ce_pkt_dl_len_set(void *hif_sc, unsigned int pkt_download_len);
 
+void ce_update_tx_ring(struct CE_handle *ce_tx_hdl, uint32_t num_htt_cmpls);
+extern qdf_nbuf_t ce_batch_send(struct CE_handle *ce_tx_hdl,
+		qdf_nbuf_t msdu,
+		uint32_t transfer_id,
+		uint32_t len,
+		uint32_t sendhead);
+
+extern int ce_send_single(struct CE_handle *ce_tx_hdl,
+		qdf_nbuf_t msdu,
+		uint32_t transfer_id,
+		uint32_t len);
 /*
  * Register a Send Callback function.
  * This function is called as soon as the contents of a Send
diff --git a/hif/src/ce/ce_internal.h b/hif/src/ce/ce_internal.h
index 1d95984..4df0ec0 100644
--- a/hif/src/ce/ce_internal.h
+++ b/hif/src/ce/ce_internal.h
@@ -250,31 +250,39 @@
 struct CE_src_desc {
 	uint32_t buffer_addr;
 #if _BYTE_ORDER == _BIG_ENDIAN
-	uint32_t  meta_data:14,
-		byte_swap:1,
-		gather:1,
-		nbytes:16;
+	uint32_t  meta_data:12,
+		  target_int_disable:1,
+		  host_int_disable:1,
+		  byte_swap:1,
+		  gather:1,
+		  nbytes:16;
 #else
 
-		uint32_t nbytes:16,
-		gather:1,
-		byte_swap:1,
-		meta_data:14;
+	uint32_t nbytes:16,
+		 gather:1,
+		 byte_swap:1,
+		 host_int_disable:1,
+		 target_int_disable:1,
+		 meta_data:12;
 #endif
 };
 
 struct CE_dest_desc {
 	uint32_t buffer_addr;
 #if _BYTE_ORDER == _BIG_ENDIAN
-	uint32_t  meta_data:14,
-		byte_swap:1,
-		gather:1,
-		nbytes:16;
+	uint32_t  meta_data:12,
+		  target_int_disable:1,
+		  host_int_disable:1,
+		  byte_swap:1,
+		  gather:1,
+		  nbytes:16;
 #else
 	uint32_t nbytes:16,
-		gather:1,
-		byte_swap:1,
-		meta_data:14;
+		 gather:1,
+		 byte_swap:1,
+		 host_int_disable:1,
+		 target_int_disable:1,
+		 meta_data:12;
 #endif
 };
 #endif /* QCA_WIFI_3_0 */
diff --git a/hif/src/ce/ce_main.c b/hif/src/ce/ce_main.c
index 6b1570e..88ef77b 100644
--- a/hif/src/ce/ce_main.c
+++ b/hif/src/ce/ce_main.c
@@ -47,7 +47,9 @@
 #include "ce_assignment.h"
 #include "ce_tasklet.h"
 #include "platform_icnss.h"
+#ifndef CONFIG_WIN
 #include "qwlan_version.h"
+#endif
 
 #define CE_POLL_TIMEOUT 10      /* ms */
 
@@ -1119,7 +1121,7 @@
 			return;
 		}
 	}
-#ifdef ATH_11AC_TXCOMPACT
+#if ATH_11AC_TXCOMPACT
 	ce_per_engine_servicereap(scn, pipe);
 #else
 	ce_per_engine_service(scn, pipe);
diff --git a/hif/src/ce/ce_service.c b/hif/src/ce/ce_service.c
index c3fc02f..ae4d643 100644
--- a/hif/src/ce/ce_service.c
+++ b/hif/src/ce/ce_service.c
@@ -309,6 +309,9 @@
 		memcpy(&(((uint32_t *)shadow_src_desc)[1]), &user_flags,
 			   sizeof(uint32_t));
 #endif
+		shadow_src_desc->target_int_disable = 0;
+		shadow_src_desc->host_int_disable = 0;
+
 		shadow_src_desc->meta_data = transfer_id;
 
 		/*
@@ -703,6 +706,201 @@
 }
 #endif /* WLAN_FEATURE_FASTPATH */
 
+#ifndef AH_NEED_TX_DATA_SWAP
+#define AH_NEED_TX_DATA_SWAP 0
+#endif
+
+/**
+ * ce_batch_send() - sends bunch of msdus at once
+ * @ce_tx_hdl : pointer to CE handle
+ * @msdu : list of msdus to be sent
+ * @transfer_id : transfer id
+ * @len : Downloaded length
+ * @sendhead : sendhead
+ *
+ * Assumption : Called with an array of MSDU's
+ * Function:
+ * For each msdu in the array
+ * 1. Send each msdu
+ * 2. Increment write index accordinlgy.
+ *
+ * Return: list of msds not sent
+ */
+qdf_nbuf_t ce_batch_send(struct CE_handle *ce_tx_hdl,  qdf_nbuf_t msdu,
+		uint32_t transfer_id, u_int32_t len, uint32_t sendhead)
+{
+	struct CE_state *ce_state = (struct CE_state *)ce_tx_hdl;
+	struct hif_softc *scn = ce_state->scn;
+	struct CE_ring_state *src_ring = ce_state->src_ring;
+	u_int32_t ctrl_addr = ce_state->ctrl_addr;
+	/*  A_target_id_t targid = TARGID(scn);*/
+
+	uint32_t nentries_mask = src_ring->nentries_mask;
+	uint32_t sw_index, write_index;
+
+	struct CE_src_desc *src_desc_base =
+		(struct CE_src_desc *)src_ring->base_addr_owner_space;
+	uint32_t *src_desc;
+
+	struct CE_src_desc lsrc_desc = {0};
+	int deltacount = 0;
+	qdf_nbuf_t freelist = NULL, hfreelist = NULL, tempnext;
+
+	sw_index = src_ring->sw_index;
+	write_index = src_ring->write_index;
+
+	deltacount = CE_RING_DELTA(nentries_mask, write_index, sw_index-1);
+
+	while (msdu) {
+		tempnext = qdf_nbuf_next(msdu);
+
+		if (deltacount < 2) {
+			if (sendhead)
+				return msdu;
+			qdf_print("Out of descriptor\n");
+			src_ring->write_index = write_index;
+			war_ce_src_ring_write_idx_set(scn, ctrl_addr,
+					write_index);
+
+			sw_index = src_ring->sw_index;
+			write_index = src_ring->write_index;
+
+			deltacount = CE_RING_DELTA(nentries_mask, write_index,
+					sw_index-1);
+			if (freelist == NULL) {
+				freelist = msdu;
+				hfreelist = msdu;
+			} else {
+				qdf_nbuf_set_next(freelist, msdu);
+				freelist = msdu;
+			}
+			qdf_nbuf_set_next(msdu, NULL);
+			msdu = tempnext;
+			continue;
+		}
+
+		src_desc = (uint32_t *)CE_SRC_RING_TO_DESC(src_desc_base,
+				write_index);
+
+		src_desc[0]   = qdf_nbuf_get_frag_paddr(msdu, 0);
+
+		lsrc_desc.meta_data = transfer_id;
+		if (len  > msdu->len)
+			len =  msdu->len;
+		lsrc_desc.nbytes = len;
+		/*  Data packet is a byte stream, so disable byte swap */
+		lsrc_desc.byte_swap = AH_NEED_TX_DATA_SWAP;
+		lsrc_desc.gather    = 0; /*For the last one, gather is not set*/
+
+		src_desc[1] = ((uint32_t *)&lsrc_desc)[1];
+
+
+		src_ring->per_transfer_context[write_index] = msdu;
+		write_index = CE_RING_IDX_INCR(nentries_mask, write_index);
+
+		if (sendhead)
+			break;
+		qdf_nbuf_set_next(msdu, NULL);
+		msdu = tempnext;
+
+	}
+
+
+	src_ring->write_index = write_index;
+	war_ce_src_ring_write_idx_set(scn, ctrl_addr, write_index);
+
+	return hfreelist;
+}
+
+/**
+ * ce_update_tx_ring() - Advance sw index.
+ * @ce_tx_hdl : pointer to CE handle
+ * @num_htt_cmpls : htt completions received.
+ *
+ * Function:
+ * Increment the value of sw index of src ring
+ * according to number of htt completions
+ * received.
+ *
+ * Return: void
+ */
+void ce_update_tx_ring(struct CE_handle *ce_tx_hdl, uint32_t num_htt_cmpls)
+{
+	struct CE_state *ce_state = (struct CE_state *)ce_tx_hdl;
+	struct CE_ring_state *src_ring = ce_state->src_ring;
+	uint32_t nentries_mask = src_ring->nentries_mask;
+	/*
+	 * Advance the s/w index:
+	 * This effectively simulates completing the CE ring descriptors
+	 */
+	src_ring->sw_index =
+		CE_RING_IDX_ADD(nentries_mask, src_ring->sw_index,
+				num_htt_cmpls);
+}
+
+/**
+ * ce_send_single() - sends
+ * @ce_tx_hdl : pointer to CE handle
+ * @msdu : msdu to be sent
+ * @transfer_id : transfer id
+ * @len : Downloaded length
+ *
+ * Function:
+ * 1. Send one msdu
+ * 2. Increment write index of src ring accordinlgy.
+ *
+ * Return: int: CE sent status
+ */
+int ce_send_single(struct CE_handle *ce_tx_hdl, qdf_nbuf_t msdu,
+		uint32_t transfer_id, u_int32_t len)
+{
+	struct CE_state *ce_state = (struct CE_state *)ce_tx_hdl;
+	struct hif_softc *scn = ce_state->scn;
+	struct CE_ring_state *src_ring = ce_state->src_ring;
+	uint32_t ctrl_addr = ce_state->ctrl_addr;
+	/*A_target_id_t targid = TARGID(scn);*/
+
+	uint32_t nentries_mask = src_ring->nentries_mask;
+	uint32_t sw_index, write_index;
+
+	struct CE_src_desc *src_desc_base =
+		(struct CE_src_desc *)src_ring->base_addr_owner_space;
+	uint32_t *src_desc;
+
+	struct CE_src_desc lsrc_desc = {0};
+
+	sw_index = src_ring->sw_index;
+	write_index = src_ring->write_index;
+
+	if (qdf_unlikely(CE_RING_DELTA(nentries_mask, write_index,
+					sw_index-1) < 1)) {
+		/* ol_tx_stats_inc_ring_error(sc->scn->pdev_txrx_handle, 1); */
+		qdf_print("ce send fail %d %d %d\n", nentries_mask,
+				write_index, sw_index);
+		return 1;
+	}
+
+	src_desc = (uint32_t *)CE_SRC_RING_TO_DESC(src_desc_base, write_index);
+
+	src_desc[0] = qdf_nbuf_get_frag_paddr(msdu, 0);
+
+	lsrc_desc.meta_data = transfer_id;
+	lsrc_desc.nbytes = len;
+	/*  Data packet is a byte stream, so disable byte swap */
+	lsrc_desc.byte_swap = AH_NEED_TX_DATA_SWAP;
+	lsrc_desc.gather    = 0; /* For the last one, gather is not set */
+
+	src_desc[1] = ((uint32_t *)&lsrc_desc)[1];
+
+
+	src_ring->per_transfer_context[write_index] = msdu;
+	write_index = CE_RING_IDX_INCR(nentries_mask, write_index);
+
+	src_ring->write_index = write_index;
+	war_ce_src_ring_write_idx_set(scn, ctrl_addr, write_index);
+
+	return QDF_STATUS_SUCCESS;
+}
 /**
  * ce_recv_buf_enqueue() - enqueue a recv buffer into a copy engine
  * @coyeng: copy engine handle
@@ -1373,7 +1571,7 @@
 	dest_ring->write_index = write_index;
 }
 
-#define MSG_FLUSH_NUM 6
+#define MSG_FLUSH_NUM 32
 /**
  * ce_per_engine_service_fast() - CE handler routine to service fastpath messages
  * @scn: hif_context
diff --git a/hif/src/hif_main.c b/hif/src/hif_main.c
index 14a9b12..03c9f76 100644
--- a/hif/src/hif_main.c
+++ b/hif/src/hif_main.c
@@ -983,3 +983,117 @@
 
 	return false;
 }
+
+/**
+ * hif_batch_send() - API to access hif specific function
+ * ce_batch_send.
+ * @osc: HIF Context
+ * @msdu : list of msdus to be sent
+ * @transfer_id : transfer id
+ * @len : donwloaded length
+ *
+ * Return: list of msds not sent
+ */
+qdf_nbuf_t hif_batch_send(struct hif_opaque_softc *osc, qdf_nbuf_t msdu,
+		uint32_t transfer_id, u_int32_t len, uint32_t sendhead)
+{
+	void *ce_tx_hdl = hif_get_ce_handle(osc, CE_HTT_TX_CE);
+	return ce_batch_send((struct CE_handle *)ce_tx_hdl, msdu, transfer_id,
+			len, sendhead);
+}
+
+/**
+ * hif_update_tx_ring() - API to access hif specific function
+ * ce_update_tx_ring.
+ * @osc: HIF Context
+ * @num_htt_cmpls : number of htt compl received.
+ *
+ * Return: void
+ */
+void hif_update_tx_ring(struct hif_opaque_softc *osc, u_int32_t num_htt_cmpls)
+{
+	void *ce_tx_hdl = hif_get_ce_handle(osc, CE_HTT_TX_CE);
+	ce_update_tx_ring(ce_tx_hdl, num_htt_cmpls);
+}
+
+
+/**
+ * hif_send_single() - API to access hif specific function
+ * ce_send_single.
+ * @osc: HIF Context
+ * @msdu : msdu to be sent
+ * @transfer_id: transfer id
+ * @len : downloaded length
+ *
+ * Return: msdu sent status
+ */
+int hif_send_single(struct hif_opaque_softc *osc, qdf_nbuf_t msdu, uint32_t
+		transfer_id, u_int32_t len)
+{
+	void *ce_tx_hdl = hif_get_ce_handle(osc, CE_HTT_TX_CE);
+	return ce_send_single((struct CE_handle *)ce_tx_hdl, msdu, transfer_id,
+			len);
+}
+
+/**
+ * hif_send_fast() - API to access hif specific function
+ * ce_send_fast.
+ * @osc: HIF Context
+ * @msdu : array of msdus to be sent
+ * @num_msdus : number of msdus in an array
+ * @transfer_id: transfer id
+ *
+ * Return: No. of packets that could be sent
+ */
+int hif_send_fast(struct hif_opaque_softc *osc, qdf_nbuf_t *nbuf_arr,
+		uint32_t num_msdus, uint32_t transfer_id)
+{
+	void *ce_tx_hdl = hif_get_ce_handle(osc, CE_HTT_TX_CE);
+	return ce_send_fast((struct CE_handle *)ce_tx_hdl, nbuf_arr, num_msdus,
+			transfer_id);
+}
+
+/**
+ * hif_pkt_dl_len_set() - API to access hif specific function
+ * ce_pkt_dl_len_set.
+ * @osc: HIF Context
+ * @pkt_download_len: download length
+ *
+ * Return: None
+ */
+void hif_pkt_dl_len_set(void *hif_sc, unsigned int pkt_download_len)
+{
+	ce_pkt_dl_len_set(hif_sc, pkt_download_len);
+}
+
+/**
+ * hif_reg_write() - API to access hif specific function
+ * hif_write32_mb.
+ * @hif_ctx : HIF Context
+ * @offset : offset on which value has to be written
+ * @value : value to be written
+ *
+ * Return: None
+ */
+void hif_reg_write(struct hif_opaque_softc *hif_ctx, uint32_t offset,
+		uint32_t value)
+{
+	struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
+	hif_write32_mb(scn->mem + offset, value);
+
+}
+
+/**
+ * hif_reg_read() - API to access hif specific function
+ * hif_read32_mb.
+ * @hif_ctx : HIF Context
+ * @offset : offset from which value has to be read
+ *
+ * Return: Read value
+ */
+uint32_t hif_reg_read(struct hif_opaque_softc *hif_ctx, uint32_t offset)
+{
+
+	struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
+	return hif_read32_mb(scn->mem + offset);
+}
diff --git a/hif/src/pcie/if_pci.c b/hif/src/pcie/if_pci.c
index 47e513c..ec8d72f 100644
--- a/hif/src/pcie/if_pci.c
+++ b/hif/src/pcie/if_pci.c
@@ -3026,7 +3026,7 @@
 	void *addr;
 
 	addr = scn->mem + offset;
-	value = A_PCI_READ32(addr);
+	value = hif_read32_mb(addr);
 
 	{
 		unsigned long irq_flags;