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