qcacmn: Datapath changes for WiSA specification

Datapath changes for WiSA specification.
 - Multicast packets with 50000 as destination
   port should go at 6Mbps.
 - Multicast packets with 50001 as destination
   port should go at 24Mbps.

Change-Id: I582b13fd85e2bdc0e49739a1c6f8d8a3b295902f
CRs-Fixed: 1010412
diff --git a/hif/inc/hif.h b/hif/inc/hif.h
index a8dc3f6..2e3c230 100644
--- a/hif/inc/hif.h
+++ b/hif/inc/hif.h
@@ -575,8 +575,6 @@
 int hif_dump_registers(struct hif_opaque_softc *scn);
 int ol_copy_ramdump(struct hif_opaque_softc *scn);
 void hif_crash_shutdown(struct hif_opaque_softc *hif_ctx);
-void hif_bus_pkt_dl_len_set(struct hif_opaque_softc *hif_sc,
-			    unsigned int pkt_download_len);
 void hif_get_hw_info(struct hif_opaque_softc *scn, u32 *version, u32 *revision,
 		     const char **target_name);
 void hif_lro_flush_cb_register(struct hif_opaque_softc *scn,
@@ -598,8 +596,8 @@
 		uint32_t transfer_id, u_int32_t len, uint32_t sendhead);
 int hif_send_single(struct hif_opaque_softc *osc, qdf_nbuf_t msdu, uint32_t
 		transfer_id, u_int32_t len);
-int hif_send_fast(struct hif_opaque_softc *osc, qdf_nbuf_t *nbuf_arr, uint32_t
-		num_msdus, uint32_t transfer_id);
+int hif_send_fast(struct hif_opaque_softc *osc, qdf_nbuf_t nbuf,
+	uint32_t transfer_id, uint32_t download_len);
 void hif_pkt_dl_len_set(void *hif_sc, unsigned int pkt_download_len);
 void hif_ce_war_disable(void);
 void hif_ce_war_enable(void);
diff --git a/hif/src/ce/ce_api.h b/hif/src/ce/ce_api.h
index 7a15365..6098876 100644
--- a/hif/src/ce/ce_api.h
+++ b/hif/src/ce/ce_api.h
@@ -150,11 +150,10 @@
 		unsigned int user_flags);
 
 #ifdef WLAN_FEATURE_FASTPATH
-int ce_send_fast(struct CE_handle *copyeng, qdf_nbuf_t *msdus,
-		 unsigned int num_msdus, unsigned int transfer_id);
+int ce_send_fast(struct CE_handle *copyeng, qdf_nbuf_t msdu,
+	unsigned int transfer_id, uint32_t download_len);
 
 #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,
diff --git a/hif/src/ce/ce_internal.h b/hif/src/ce/ce_internal.h
index 2c445f6..178aa9a 100644
--- a/hif/src/ce/ce_internal.h
+++ b/hif/src/ce/ce_internal.h
@@ -107,7 +107,6 @@
 	enum CE_op_state state;
 
 #ifdef WLAN_FEATURE_FASTPATH
-	u_int32_t download_len; /* pkt download length for source ring */
 	fastpath_msg_handler fastpath_handler;
 	void *context;
 #endif /* WLAN_FEATURE_FASTPATH */
diff --git a/hif/src/ce/ce_service.c b/hif/src/ce/ce_service.c
index 7bbbd6f..951eef4 100644
--- a/hif/src/ce/ce_service.c
+++ b/hif/src/ce/ce_service.c
@@ -539,9 +539,9 @@
 /**
  * ce_send_fast() CE layer Tx buffer posting function
  * @copyeng: copy engine handle
- * @msdus: iarray of msdu to be sent
- * @num_msdus: number of msdus in an array
+ * @msdu: msdu to be sent
  * @transfer_id: transfer_id
+ * @download_len: packet download length
  *
  * Assumption : Called with an array of MSDU's
  * Function:
@@ -552,8 +552,8 @@
  *
  * Return: No. of packets that could be sent
  */
-int ce_send_fast(struct CE_handle *copyeng, qdf_nbuf_t *msdus,
-		 unsigned int num_msdus, unsigned int transfer_id)
+int ce_send_fast(struct CE_handle *copyeng, qdf_nbuf_t msdu,
+		 unsigned int transfer_id, uint32_t download_len)
 {
 	struct CE_state *ce_state = (struct CE_state *)copyeng;
 	struct hif_softc *scn = ce_state->scn;
@@ -564,8 +564,6 @@
 	unsigned int write_index;
 	unsigned int sw_index;
 	unsigned int frag_len;
-	qdf_nbuf_t msdu;
-	int i;
 	uint64_t dma_addr;
 	uint32_t user_flags;
 
@@ -581,9 +579,9 @@
 				NULL, NULL, write_index);
 
 	if (qdf_unlikely(CE_RING_DELTA(nentries_mask, write_index, sw_index - 1)
-			 < (SLOTS_PER_DATAPATH_TX * num_msdus))) {
+			 < SLOTS_PER_DATAPATH_TX)) {
 		HIF_ERROR("Source ring full, required %d, available %d",
-		      (SLOTS_PER_DATAPATH_TX * num_msdus),
+		      SLOTS_PER_DATAPATH_TX,
 		      CE_RING_DELTA(nentries_mask, write_index, sw_index - 1));
 		OL_ATH_CE_PKT_ERROR_COUNT_INCR(scn, CE_RING_DELTA_FAIL);
 		Q_TARGET_ACCESS_END(scn);
@@ -591,8 +589,7 @@
 		return 0;
 	}
 
-	/* 2 msdus per packet */
-	for (i = 0; i < num_msdus; i++) {
+	{
 		struct CE_src_desc *src_ring_base =
 			(struct CE_src_desc *)src_ring->base_addr_owner_space;
 		struct CE_src_desc *shadow_base =
@@ -603,7 +600,6 @@
 			CE_SRC_RING_TO_DESC(shadow_base, write_index);
 
 		hif_pm_runtime_get_noresume(hif_hdl);
-		msdu = msdus[i];
 
 		/*
 		 * First fill out the ring descriptor for the HTC HTT frame
@@ -616,10 +612,9 @@
 							  0xFFFFFFFF);
 		user_flags = qdf_nbuf_data_attr_get(msdu) & DESC_DATA_FLAG_MASK;
 		ce_buffer_addr_hi_set(shadow_src_desc, dma_addr, user_flags);
-
-		shadow_src_desc->meta_data = transfer_id;
+			shadow_src_desc->meta_data = transfer_id;
 		shadow_src_desc->nbytes = qdf_nbuf_get_frag_len(msdu, 0);
-
+		download_len -= shadow_src_desc->nbytes;
 		/*
 		 * HTC HTT header is a word stream, so byte swap if CE byte
 		 * swap enabled
@@ -629,13 +624,11 @@
 		/* For the first one, it still does not need to write */
 		shadow_src_desc->gather = 1;
 		*src_desc = *shadow_src_desc;
-
 		/* By default we could initialize the transfer context to this
 		 * value
 		 */
 		src_ring->per_transfer_context[write_index] =
 			CE_SENDLIST_ITEM_CTXT;
-
 		write_index = CE_RING_IDX_INCR(nentries_mask, write_index);
 
 		src_desc = CE_SRC_RING_TO_DESC(src_ring_base, write_index);
@@ -657,8 +650,8 @@
 		/* get actual packet length */
 		frag_len = qdf_nbuf_get_frag_len(msdu, 1);
 
-		/* only read download_len once */
-		shadow_src_desc->nbytes =  ce_state->download_len;
+		/* download remaining bytes of payload */
+		shadow_src_desc->nbytes =  download_len;
 		if (shadow_src_desc->nbytes > frag_len)
 			shadow_src_desc->nbytes = frag_len;
 
@@ -676,34 +669,27 @@
 			sizeof(qdf_nbuf_data(msdu)), QDF_TX));
 	}
 
-	/* Write the final index to h/w one-shot */
-	if (i) {
-		src_ring->write_index = write_index;
+	src_ring->write_index = write_index;
 
-		if (hif_pm_runtime_get(hif_hdl) == 0) {
-			hif_record_ce_desc_event(scn, ce_state->id,
-						 FAST_TX_WRITE_INDEX_UPDATE,
-						 NULL, NULL, write_index);
+	if (hif_pm_runtime_get(hif_hdl) == 0) {
+		hif_record_ce_desc_event(scn, ce_state->id,
+					 FAST_TX_WRITE_INDEX_UPDATE,
+					 NULL, NULL, write_index);
 
-			/* Don't call WAR_XXX from here
-			 * Just call XXX instead, that has the reqd. intel
-			 */
-			war_ce_src_ring_write_idx_set(scn, ctrl_addr,
-					write_index);
-			hif_pm_runtime_put(hif_hdl);
-		}
+		/* Don't call WAR_XXX from here
+		 * Just call XXX instead, that has the reqd. intel
+		 */
+		war_ce_src_ring_write_idx_set(scn, ctrl_addr,
+				write_index);
+		hif_pm_runtime_put(hif_hdl);
 	}
 
+
 	Q_TARGET_ACCESS_END(scn);
 	qdf_spin_unlock_bh(&ce_state->ce_index_lock);
 
-	/*
-	 * If all packets in the array are transmitted,
-	 * i = num_msdus
-	 * Temporarily add an ASSERT
-	 */
-	ASSERT(i == num_msdus);
-	return i;
+	/* sent 1 packet */
+	return 1;
 }
 
 /**
@@ -2216,32 +2202,6 @@
 	}
 }
 
-#ifdef WLAN_FEATURE_FASTPATH
-/**
- * ce_pkt_dl_len_set() set the HTT packet download length
- * @hif_sc: HIF context
- * @pkt_download_len: download length
- *
- * Return: None
- */
-void ce_pkt_dl_len_set(void *hif_sc, u_int32_t pkt_download_len)
-{
-	struct hif_softc *sc = (struct hif_softc *)(hif_sc);
-	struct CE_state *ce_state = sc->ce_id_to_state[CE_HTT_H2T_MSG];
-
-	qdf_assert_always(ce_state);
-
-	ce_state->download_len = pkt_download_len;
-
-	qdf_print("%s CE %d Pkt download length %d", __func__,
-		  ce_state->id, ce_state->download_len);
-}
-#else
-void ce_pkt_dl_len_set(void *hif_sc, u_int32_t pkt_download_len)
-{
-}
-#endif /* WLAN_FEATURE_FASTPATH */
-
 bool ce_get_rx_pending(struct hif_softc *scn)
 {
 	int CE_id;
diff --git a/hif/src/dispatcher/dummy.c b/hif/src/dispatcher/dummy.c
index 1b16f60..7197673 100644
--- a/hif/src/dispatcher/dummy.c
+++ b/hif/src/dispatcher/dummy.c
@@ -183,20 +183,6 @@
 }
 
 /**
- * hif_dummy_bus_pkt_dl_len_set()- dummy call
- * @sc: context
- * @pkt_download_len: download length
- *
- * Return: None
- */
-void hif_dummy_bus_pkt_dl_len_set(void *sc,
-				  u_int32_t pkt_download_len)
-{
-	return;
-}
-
-
-/**
  * hif_dummy_cancel_deferred_target_sleep - dummy call
  * @hif_sc: hif context
  *
diff --git a/hif/src/dispatcher/dummy.h b/hif/src/dispatcher/dummy.h
index d843d72..a4d0141 100644
--- a/hif/src/dispatcher/dummy.h
+++ b/hif/src/dispatcher/dummy.h
@@ -42,8 +42,6 @@
 		     int opcode, void *config, uint32_t config_len);
 void hif_dummy_set_mailbox_swap(struct hif_softc *hif_sc);
 void hif_dummy_claim_device(struct hif_softc *hif_sc);
-void hif_dummy_bus_pkt_dl_len_set(void *sc,
-				  u_int32_t pkt_download_len);
 void hif_dummy_cancel_deferred_target_sleep(struct hif_softc *hif_sc);
 void hif_dummy_irq_enable(struct hif_softc *hif_sc, int irq_id);
 void hif_dummy_irq_disable(struct hif_softc *hif_sc, int irq_id);
diff --git a/hif/src/dispatcher/multibus.c b/hif/src/dispatcher/multibus.c
index 8fe9a39..e084080 100644
--- a/hif/src/dispatcher/multibus.c
+++ b/hif/src/dispatcher/multibus.c
@@ -250,13 +250,6 @@
 	hif_sc->bus_ops.hif_stop(hif_sc);
 }
 
-void hif_bus_pkt_dl_len_set(struct hif_opaque_softc *hif_ctx,
-			    u_int32_t pkt_download_len)
-{
-	struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx);
-	hif_sc->bus_ops.hif_bus_pkt_dl_len_set(hif_sc, pkt_download_len);
-}
-
 void hif_cancel_deferred_target_sleep(struct hif_softc *hif_sc)
 {
 	return hif_sc->bus_ops.hif_cancel_deferred_target_sleep(hif_sc);
diff --git a/hif/src/dispatcher/multibus.h b/hif/src/dispatcher/multibus.h
index 4d5f521..ef3b95d 100644
--- a/hif/src/dispatcher/multibus.h
+++ b/hif/src/dispatcher/multibus.h
@@ -57,8 +57,6 @@
 	void (*hif_claim_device)(struct hif_softc *hif_sc);
 	void (*hif_shutdown_device)(struct hif_softc *hif_sc);
 	void (*hif_stop)(struct hif_softc *hif_sc);
-	void (*hif_bus_pkt_dl_len_set)(void *hif_sc,
-				       u_int32_t pkt_download_len);
 	void (*hif_cancel_deferred_target_sleep)(struct hif_softc *hif_sc);
 	void (*hif_irq_disable)(struct hif_softc *hif_sc, int ce_id);
 	void (*hif_irq_enable)(struct hif_softc *hif_sc, int ce_id);
diff --git a/hif/src/dispatcher/multibus_ahb.c b/hif/src/dispatcher/multibus_ahb.c
index 3019ec2..314d67b 100644
--- a/hif/src/dispatcher/multibus_ahb.c
+++ b/hif/src/dispatcher/multibus_ahb.c
@@ -53,7 +53,6 @@
 	bus_ops->hif_claim_device = &hif_dummy_claim_device;
 	bus_ops->hif_shutdown_device = &hif_ce_stop;
 	bus_ops->hif_stop = &hif_ce_stop;
-	bus_ops->hif_bus_pkt_dl_len_set = &ce_pkt_dl_len_set;
 	bus_ops->hif_cancel_deferred_target_sleep =
 				&hif_dummy_cancel_deferred_target_sleep;
 	bus_ops->hif_irq_disable = &hif_ahb_irq_disable;
diff --git a/hif/src/dispatcher/multibus_pci.c b/hif/src/dispatcher/multibus_pci.c
index f9066a9..a5f8919 100644
--- a/hif/src/dispatcher/multibus_pci.c
+++ b/hif/src/dispatcher/multibus_pci.c
@@ -69,7 +69,6 @@
 	bus_ops->hif_claim_device = &hif_dummy_claim_device;
 	bus_ops->hif_shutdown_device = &hif_ce_stop;
 	bus_ops->hif_stop = &hif_ce_stop;
-	bus_ops->hif_bus_pkt_dl_len_set = &ce_pkt_dl_len_set;
 	bus_ops->hif_cancel_deferred_target_sleep =
 					&hif_pci_cancel_deferred_target_sleep;
 	bus_ops->hif_irq_disable = &hif_pci_irq_disable;
diff --git a/hif/src/dispatcher/multibus_sdio.c b/hif/src/dispatcher/multibus_sdio.c
index 4842148..fc27202 100644
--- a/hif/src/dispatcher/multibus_sdio.c
+++ b/hif/src/dispatcher/multibus_sdio.c
@@ -52,7 +52,6 @@
 	bus_ops->hif_claim_device = &hif_sdio_claim_device;
 	bus_ops->hif_shutdown_device = &hif_sdio_shutdown;
 	bus_ops->hif_stop = &hif_sdio_stop;
-	bus_ops->hif_bus_pkt_dl_len_set = &hif_dummy_bus_pkt_dl_len_set;
 	bus_ops->hif_cancel_deferred_target_sleep =
 				&hif_dummy_cancel_deferred_target_sleep;
 	bus_ops->hif_irq_disable = &hif_dummy_irq_disable;
diff --git a/hif/src/dispatcher/multibus_snoc.c b/hif/src/dispatcher/multibus_snoc.c
index 284901a..f58ef19 100644
--- a/hif/src/dispatcher/multibus_snoc.c
+++ b/hif/src/dispatcher/multibus_snoc.c
@@ -60,7 +60,6 @@
 	bus_ops->hif_claim_device = &hif_dummy_claim_device;
 	bus_ops->hif_shutdown_device = &hif_ce_stop;
 	bus_ops->hif_stop = &hif_ce_stop;
-	bus_ops->hif_bus_pkt_dl_len_set = &ce_pkt_dl_len_set;
 	bus_ops->hif_cancel_deferred_target_sleep =
 				&hif_dummy_cancel_deferred_target_sleep;
 	bus_ops->hif_irq_disable = &hif_snoc_irq_disable;
diff --git a/hif/src/hif_main.c b/hif/src/hif_main.c
index 6bbf06e..fdb1a73 100644
--- a/hif/src/hif_main.c
+++ b/hif/src/hif_main.c
@@ -942,28 +942,16 @@
  * @msdu : array of msdus to be sent
  * @num_msdus : number of msdus in an array
  * @transfer_id: transfer id
+ * @download_len: download length
  *
  * 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)
+int hif_send_fast(struct hif_opaque_softc *osc, qdf_nbuf_t nbuf,
+		uint32_t transfer_id, uint32_t download_len)
 {
 	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);
+	return ce_send_fast((struct CE_handle *)ce_tx_hdl, nbuf,
+			transfer_id, download_len);
 }
 
 /**
diff --git a/hif/src/pcie/if_pci.c b/hif/src/pcie/if_pci.c
index a46d078..0601b75 100644
--- a/hif/src/pcie/if_pci.c
+++ b/hif/src/pcie/if_pci.c
@@ -3996,16 +3996,3 @@
 }
 
 #endif /* FEATURE_RUNTIME_PM */
-
-/**
- * hif_pci_bus_pkt_dl_len_set() set the HTT packet download length
- * @sc: context
- * @pkt_download_len: download length
- *
- * Return: void
- */
-void hif_pci_bus_pkt_dl_len_set(struct hif_softc *sc,
-				u_int32_t pkt_download_len)
-{
-	ce_pkt_dl_len_set(sc, pkt_download_len);
-}
diff --git a/qdf/linux/src/i_qdf_nbuf.h b/qdf/linux/src/i_qdf_nbuf.h
index fbf36f7..6fafff7 100644
--- a/qdf/linux/src/i_qdf_nbuf.h
+++ b/qdf/linux/src/i_qdf_nbuf.h
@@ -156,7 +156,8 @@
 							num:1,
 							flag_chfrag_start:1,
 							flag_chfrag_end:1,
-							reserved:3;
+							flag_ext_header:1,
+							reserved:2;
 					} bits;
 					uint8_t u8;
 				} flags;
@@ -252,6 +253,9 @@
 #define QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_CHFRAG_END(skb) \
 		(((struct qdf_nbuf_cb *) \
 		((skb)->cb))->u.tx.extra_frag.flags.bits.flag_chfrag_end)
+#define QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_EXT_HEADER(skb) \
+		(((struct qdf_nbuf_cb *) \
+		((skb)->cb))->u.tx.extra_frag.flags.bits.flag_ext_header)
 #define QDF_NBUF_CB_TX_EXTRA_FRAG_WORDSTR_EFRAG(skb) \
 	(((struct qdf_nbuf_cb *) \
 		((skb)->cb))->u.tx.extra_frag.flags.bits.flag_efrag)