qcacld-3.0: Initial snapshot of ihelium wlan driver

qcacld-3.0: Initial snapshot of ihelium wlan driver
to match code-scanned SU Release 5.0.0.139. This is
open-source version of wlan for next Android release.

Change-Id: Icf598ca97da74f84bea607e4e902d1889806f507
diff --git a/core/dp/ol/inc/ol_htt_tx_api.h b/core/dp/ol/inc/ol_htt_tx_api.h
new file mode 100644
index 0000000..58ebabc
--- /dev/null
+++ b/core/dp/ol/inc/ol_htt_tx_api.h
@@ -0,0 +1,969 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * 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.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/**
+ * @file ol_htt_tx_api.h
+ * @brief Specify the tx HTT API functions called by the host data SW.
+ * @details
+ *  This file declares the HTT API functions that are specifically
+ *  related to transmit processing.
+ *  In particular, the methods of the abstract HTT tx descriptor are
+ *  specified.
+ */
+#ifndef _OL_HTT_TX_API__H_
+#define _OL_HTT_TX_API__H_
+
+/* #include <osapi_linux.h>    / * uint16_t, etc. * / */
+#include <osdep.h>              /* uint16_t, etc. */
+#include <cdf_nbuf.h>           /* cdf_nbuf_t */
+#include <ol_cfg.h>             /* wlan_frm_fmt */
+
+#include <htt.h>                /* needed by inline functions */
+#include <cdf_net_types.h>
+#include <ol_htt_api.h>         /* htt_pdev_handle */
+#include <htt_types.h>
+#include <cdf_trace.h>
+
+/* Remove these macros when they get added to htt.h. */
+#ifndef HTT_TX_DESC_EXTENSION_GET
+#define HTT_TX_DESC_EXTENSION_OFFSET_BYTES 0
+#define HTT_TX_DESC_EXTENSION_OFFSET_DWORD 0
+#define HTT_TX_DESC_EXTENSION_M        0x10000000
+#define HTT_TX_DESC_EXTENSION_S        28
+
+#define HTT_TX_DESC_EXTENSION_GET(_var) \
+	(((_var) & HTT_TX_DESC_EXTENSION_M) >> HTT_TX_DESC_EXTENSION_S)
+#define HTT_TX_DESC_EXTENSION_SET(_var, _val)				\
+	do {								\
+		HTT_CHECK_SET_VAL(HTT_TX_DESC_EXTENSION, _val);		\
+		((_var) |= ((_val) << HTT_TX_DESC_EXTENSION_S));	\
+	} while (0)
+#endif
+
+/*================ meta-info about tx MSDUs =================================*/
+
+/*
+ * For simplicity, use the IEEE 802.11 frame type values.
+ */
+enum htt_frm_type {
+	htt_frm_type_mgmt = 0,
+	htt_frm_type_ctrl = 1,
+	htt_frm_type_data = 2
+};
+
+/*
+ * For simplicity, use the IEEE 802.11 frame sub-type values.
+ */
+enum htt_frm_subtype {
+	htt_frm_subtype_mgmt_assoc_req = 0,
+	htt_frm_subtype_mgmt_assoc_resp = 1,
+	htt_frm_subtype_mgmt_reassoc_req = 2,
+	htt_frm_subtype_mgmt_reassoc_resp = 3,
+	htt_frm_subtype_mgmt_probe_req = 4,
+	htt_frm_subtype_mgmt_probe_resp = 5,
+	htt_frm_subtype_mgmt_timing_adv = 6,
+	htt_frm_subtype_mgmt_beacon = 8,
+	htt_frm_subtype_mgmt_atim = 9,
+	htt_frm_subtype_mgmt_disassoc = 10,
+	htt_frm_subtype_mgmt_auth = 11,
+	htt_frm_subtype_mgmt_deauth = 12,
+	htt_frm_subtype_mgmt_action = 13,
+	htt_frm_subtype_mgmt_action_no_ack = 14,
+
+	htt_frm_subtype_data_data = 0,
+	htt_frm_subtype_data_data_cf_ack = 1,
+	htt_frm_subtype_data_data_cf_poll = 2,
+	htt_frm_subtype_data_data_cf_ack_cf_poll = 3,
+	htt_frm_subtype_data_null = 4,
+	htt_frm_subtype_data_cf_ack = 5,
+	htt_frm_subtype_data_cf_poll = 6,
+	htt_frm_subtype_data_cf_ack_cf_poll = 7,
+	htt_frm_subtype_data_QoS_data = 8,
+	htt_frm_subtype_data_QoS_data_cf_ack = 9,
+	htt_frm_subtype_data_QoS_data_cf_poll = 10,
+	htt_frm_subtype_data_QoS_data_cf_ack_cf_poll = 11,
+	htt_frm_subtype_data_QoS_null = 12,
+	htt_frm_subtype_data_QoS_cf_poll = 14,
+	htt_frm_subtype_data_QoS_cf_ack_cf_poll = 15,
+};
+
+enum htt_ofdm_datarate {		/* Value    MBPS    Modulation  Coding*/
+	htt_ofdm_datarate_6_mbps = 0,	/* 0        6       BPSK        1/2   */
+	htt_ofdm_datarate_9_mbps = 1,	/* 1        9       BPSK        3/4   */
+	htt_ofdm_datarate_12_mbps = 2,	/* 2        12      QPSK        1/2   */
+	htt_ofdm_datarate_18_mbps = 3,	/* 3        18      QPSK        3/4   */
+	htt_ofdm_datarate_24_mbps = 4,	/* 4        24      16-QAM      1/2   */
+	htt_ofdm_datarate_36_mbps = 5,	/* 5        36      16-QAM      3/4   */
+	htt_ofdm_datarate_48_mbps = 6,	/* 6        48      64-QAM      1/2   */
+	htt_ofdm_datarate_54_mbps = 7,	/* 7        54      64-QAM      3/4   */
+	htt_ofdm_datarate_max = 7,
+};
+
+/**
+ * struct ocb_tx_ctrl_hdr_t - TX control header
+ * @version:		must be 1
+ * @length:		length of this structure
+ * @channel_freq:	channel on which to transmit the packet
+ * @valid_pwr:		bit 0: if set, tx pwr spec is valid
+ * @valid_datarate:	bit 1: if set, tx MCS mask spec is valid
+ * @valid_retries:	bit 2: if set, tx retries spec is valid
+ * @valid_chain_mask:	bit 3: if set, chain mask is valid
+ * @valid_expire_tsf:	bit 4: if set, tx expire TSF spec is valid
+ * @valid_tid:		bit 5: if set, TID is valid
+ * @reserved0_15_6:	bits 15:6 - unused, set to 0x0
+ * @all_flags:		union of all the flags
+ * @expire_tsf_lo:	TX expiry time (TSF) LSBs
+ * @expire_tsf_hi:	TX expiry time (TSF) MSBs
+ * @pwr:		Specify what power the tx frame needs to be transmitted
+ *			at. The power a signed (two's complement) value is in
+ *			units of 0.5 dBm. The value needs to be appropriately
+ *			sign-extended when extracting the value from the message
+ *			and storing it in a variable that is larger than A_INT8.
+ *			If the transmission uses multiple tx chains, this power
+ *			spec is the total transmit power, assuming incoherent
+ *			combination of per-chain power to produce the total
+ *			power.
+ * @datarate:		The desired modulation and coding scheme.
+ *			VALUE    DATA RATE   MODULATION  CODING RATE
+ *			@ 20 MHz
+ *			(MBPS)
+ *			0        6           BPSK        1/2
+ *			1        9           BPSK        3/4
+ *			2        12          QPSK        1/2
+ *			3        18          QPSK        3/4
+ *			4        24          16-QAM      1/2
+ *			5        36          16-QAM      3/4
+ *			6        48          64-QAM      1/2
+ *			7        54          64-QAM      3/4
+ * @retry_limit:	Specify the maximum number of transmissions, including
+ *			the initial transmission, to attempt before giving up if
+ *			no ack is received.
+ *			If the tx rate is specified, then all retries shall use
+ *			the same rate as the initial transmission.
+ *			If no tx rate is specified, the target can choose
+ *			whether to retain the original rate during the
+ *			retransmissions, or to fall back to a more robust rate.
+ * @chain_mask:		specify which chains to transmit from
+ * @ext_tid:		Extended Traffic ID (0-15)
+ * @reserved:		Ensure that the size of the structure is a multiple of
+ *			4. Must be 0.
+ *
+ * When sending an OCB packet, the user application has
+ * the option of including the following struct following an ethernet header
+ * with the proto field set to 0x8151. This struct includes various TX
+ * paramaters including the TX power and MCS.
+ */
+PREPACK struct ocb_tx_ctrl_hdr_t {
+	uint16_t version;
+	uint16_t length;
+	uint16_t channel_freq;
+
+	union {
+		struct {
+			uint16_t
+			valid_pwr:1,
+			valid_datarate:1,
+			valid_retries:1,
+			valid_chain_mask:1,
+			valid_expire_tsf:1,
+			valid_tid:1,
+			reserved0_15_6:10;
+		};
+		uint16_t all_flags;
+	};
+
+	uint32_t expire_tsf_lo;
+	uint32_t expire_tsf_hi;
+	int8_t pwr;
+	uint8_t datarate;
+	uint8_t retry_limit;
+	uint8_t chain_mask;
+	uint8_t ext_tid;
+	uint8_t reserved[3];
+} POSTPACK;
+
+/**
+ * @brief tx MSDU meta-data that HTT may use to program the FW/HW tx descriptor
+ */
+struct htt_msdu_info_t {
+	/* the info sub-struct specifies the characteristics of the MSDU */
+	struct {
+		uint16_t ethertype;
+#define HTT_INVALID_PEER_ID 0xffff
+		uint16_t peer_id;
+		uint8_t vdev_id;
+		uint8_t ext_tid;
+		/*
+		 * l2_hdr_type - L2 format (802.3, native WiFi 802.11,
+		 * or raw 802.11)
+		 * Based on attach-time configuration, the tx frames provided
+		 * by the OS to the tx data SW are expected to be either
+		 * 802.3 format or the "native WiFi" variant of 802.11 format.
+		 * Internally, the driver may also inject tx frames into the tx
+		 * datapath, and these frames may be either 802.3 format or
+		 * 802.11 "raw" format, with no further 802.11 encapsulation
+		 * needed.
+		 * The tx frames are tagged with their frame format, so target
+		 * FW/HW will know how to interpret the packet's encapsulation
+		 * headers when doing tx classification, and what form of 802.11
+		 * header encapsulation is needed, if any.
+		 */
+		uint8_t l2_hdr_type;    /* enum htt_pkt_type */
+		/*
+		 * frame_type - is the tx frame management or data?
+		 * Just to avoid confusion, the enum values for this frame type
+		 * field use the 802.11 frame type values, although it is
+		 * unexpected for control frames to be sent through the host
+		 * data path.
+		 */
+		uint8_t frame_type;     /* enum htt_frm_type */
+		/*
+		 * frame subtype - this field specifies the sub-type of
+		 * management frames
+		 * Just to avoid confusion, the enum values for this frame
+		 * subtype field use the 802.11 management frame subtype values.
+		 */
+		uint8_t frame_subtype;  /* enum htt_frm_subtype */
+		uint8_t is_unicast;
+
+		/* dest_addr is not currently used.
+		 * It could be used as an input to a Tx BD (Riva tx descriptor)
+		 * signature computation.
+		   uint8_t *dest_addr;
+		 */
+
+		uint8_t l3_hdr_offset;  /* wrt cdf_nbuf_data(msdu), in bytes */
+
+		/* l4_hdr_offset is not currently used.
+		 * It could be used to specify to a TCP/UDP checksum computation
+		 * engine where the TCP/UDP header starts.
+		 */
+		/* uint8_t l4_hdr_offset; - wrt cdf_nbuf_data(msdu), in bytes */
+	} info;
+	/* the action sub-struct specifies how to process the MSDU */
+	struct {
+		uint8_t use_6mbps;      /* mgmt frames: option to force
+					   6 Mbps rate */
+		uint8_t do_encrypt;
+		uint8_t do_tx_complete;
+		uint8_t tx_comp_req;
+
+		/*
+		 * cksum_offload - Specify whether checksum offload is
+		 * enabled or not
+		 * Target FW uses this flag to turn on HW checksumming
+		 * 0x0 - No checksum offload
+		 * 0x1 - L3 header checksum only
+		 * 0x2 - L4 checksum only
+		 * 0x3 - L3 header checksum + L4 checksum
+		 */
+		cdf_nbuf_tx_cksum_t cksum_offload;
+	} action;
+};
+
+static inline void htt_msdu_info_dump(struct htt_msdu_info_t *msdu_info)
+{
+	CDF_TRACE(CDF_MODULE_ID_TXRX, CDF_TRACE_LEVEL_INFO_LOW,
+		  "HTT MSDU info object (%p)\n", msdu_info);
+	CDF_TRACE(CDF_MODULE_ID_TXRX, CDF_TRACE_LEVEL_INFO_LOW,
+		  "  ethertype: %#x\n", msdu_info->info.ethertype);
+	CDF_TRACE(CDF_MODULE_ID_TXRX, CDF_TRACE_LEVEL_INFO_LOW,
+		  "  peer_id: %d\n", msdu_info->info.peer_id);
+	CDF_TRACE(CDF_MODULE_ID_TXRX, CDF_TRACE_LEVEL_INFO_LOW,
+		  "  vdev_id: %d\n", msdu_info->info.vdev_id);
+	CDF_TRACE(CDF_MODULE_ID_TXRX, CDF_TRACE_LEVEL_INFO_LOW,
+		  "  ext_tid: %d\n", msdu_info->info.ext_tid);
+	CDF_TRACE(CDF_MODULE_ID_TXRX, CDF_TRACE_LEVEL_INFO_LOW,
+		  "  l2_hdr_type: %d\n", msdu_info->info.l2_hdr_type);
+	CDF_TRACE(CDF_MODULE_ID_TXRX, CDF_TRACE_LEVEL_INFO_LOW,
+		  "  frame_type: %d\n", msdu_info->info.frame_type);
+	CDF_TRACE(CDF_MODULE_ID_TXRX, CDF_TRACE_LEVEL_INFO_LOW,
+		  "  frame_subtype: %d\n", msdu_info->info.frame_subtype);
+	CDF_TRACE(CDF_MODULE_ID_TXRX, CDF_TRACE_LEVEL_INFO_LOW,
+		  "  is_unicast: %u\n", msdu_info->info.is_unicast);
+	CDF_TRACE(CDF_MODULE_ID_TXRX, CDF_TRACE_LEVEL_INFO_LOW,
+		  "  l3_hdr_offset: %u\n", msdu_info->info.l3_hdr_offset);
+	CDF_TRACE(CDF_MODULE_ID_TXRX, CDF_TRACE_LEVEL_INFO_LOW,
+		  "  use 6 Mbps: %d\n", msdu_info->action.use_6mbps);
+	CDF_TRACE(CDF_MODULE_ID_TXRX, CDF_TRACE_LEVEL_INFO_LOW,
+		  "  do_encrypt: %d\n", msdu_info->action.do_encrypt);
+	CDF_TRACE(CDF_MODULE_ID_TXRX, CDF_TRACE_LEVEL_INFO_LOW,
+		  "  do_tx_complete: %d\n", msdu_info->action.do_tx_complete);
+	CDF_TRACE(CDF_MODULE_ID_TXRX, CDF_TRACE_LEVEL_INFO_LOW,
+		  "  is_unicast: %u\n", msdu_info->info.is_unicast);
+	CDF_TRACE(CDF_MODULE_ID_TXRX, CDF_TRACE_LEVEL_INFO_LOW,
+		  "  is_unicast: %u\n", msdu_info->info.is_unicast);
+}
+
+/*================ tx completion message field access methods ===============*/
+
+/**
+ * @brief Look up the descriptor ID of the nth MSDU from a tx completion msg.
+ * @details
+ *  A tx completion message tells the host that the target is done
+ *  transmitting a series of MSDUs.  The message uses a descriptor ID
+ *  to identify each such MSDU.  This function/macro is used to
+ *  find the ID of one such MSDU referenced by the tx completion message.
+ *
+ * @param iterator - tx completion message context provided by HTT to the
+ *      tx completion message handler.  This abstract reference to the
+ *      HTT tx completion message's payload allows the data SW's tx
+ *      completion handler to not care about the format of the HTT
+ *      tx completion message.
+ * @param num - (zero-based) index to specify a single MSDU within the
+ *      series of MSDUs referenced by the tx completion message
+ * @return descriptor ID for the specified MSDU
+ */
+uint16_t htt_tx_compl_desc_id(void *iterator, int num);
+
+/*========================= tx descriptor operations ========================*/
+
+/**
+ * @brief Allocate a HTT abstract tx descriptor.
+ * @details
+ *  Allocate a HTT abstract tx descriptor from a pool within "consistent"
+ *  memory, which is accessible by HIF and/or MAC DMA as well as by the
+ *  host CPU.
+ *  It is expected that the tx datapath will allocate HTT tx descriptors
+ *  and link them with datapath SW tx descriptors up front as the driver
+ *  is loaded.  Thereafter, the link from datapath SW tx descriptor to
+ *  HTT tx descriptor will be maintained until the driver is unloaded.
+ *
+ * @param htt_pdev - handle to the HTT instance making the allocation
+ * @param[OUT] paddr_lo - physical address of the HTT descriptor
+ * @return success -> descriptor handle, -OR- failure -> NULL
+ */
+void *htt_tx_desc_alloc(htt_pdev_handle htt_pdev, uint32_t *paddr_lo);
+
+/**
+ * @brief Free a HTT abstract tx descriptor.
+ *
+ * @param htt_pdev - handle to the HTT instance that made the allocation
+ * @param htt_tx_desc - the descriptor to free
+ */
+void htt_tx_desc_free(htt_pdev_handle htt_pdev, void *htt_tx_desc);
+
+#if defined(HELIUMPLUS_PADDR64)
+/* TODO: oka: use kernel-doc format */
+/**
+ * @brief Free a HTT abstract tx descriptor.
+ *
+ * @param htt_pdev - handle to the HTT instance that made the allocation
+ * @param htt_tx_desc - the descriptor to free
+ */
+void *
+htt_tx_frag_alloc(htt_pdev_handle pdev,
+		  u_int16_t index,
+		  u_int32_t *frag_paddr_lo);
+#endif /* defined(HELIUMPLUS_PADDR64) */
+/**
+ * @brief Discard all tx frames in the process of being downloaded.
+ * @details
+ * This function dicards any tx frames queued in HTT or the layers
+ * under HTT.
+ * The download completion callback is invoked on these frames.
+ *
+ * @param htt_pdev - handle to the HTT instance
+ * @param[OUT] frag_paddr_lo - physical address of the fragment descriptor
+ *                             (MSDU Link Extension Descriptor)
+ */
+void htt_tx_pending_discard(htt_pdev_handle pdev);
+
+/**
+ * @brief Download a MSDU descriptor and (a portion of) the MSDU payload.
+ * @details
+ *  This function is used within LL systems to download a tx descriptor and
+ *  the initial portion of the tx MSDU payload, and within HL systems to
+ *  download the tx descriptor and the entire tx MSDU payload.
+ *  The HTT layer determines internally how much of the tx descriptor
+ *  actually needs to be downloaded. In particular, the HTT layer does not
+ *  download the fragmentation descriptor, and only for the LL case downloads
+ *  the physical address of the fragmentation descriptor.
+ *  In HL systems, the tx descriptor and the entire frame are downloaded.
+ *  In LL systems, only the tx descriptor and the header of the frame are
+ *  downloaded.  To determine how much of the tx frame to download, this
+ *  function assumes the tx frame is the default frame type, as specified
+ *  by ol_cfg_frame_type.  "Raw" frames need to be transmitted through the
+ *  alternate htt_tx_send_nonstd function.
+ *  The tx descriptor has already been attached to the cdf_nbuf object during
+ *  a preceding call to htt_tx_desc_init.
+ *
+ * @param htt_pdev - the handle of the physical device sending the tx data
+ * @param msdu - the frame being transmitted
+ * @param msdu_id - unique ID for the frame being transmitted
+ * @return 0 -> success, -OR- 1 -> failure
+ */
+int
+htt_tx_send_std(htt_pdev_handle htt_pdev, cdf_nbuf_t msdu, uint16_t msdu_id);
+
+/**
+ * @brief Download a Batch Of Tx MSDUs
+ * @details
+ *     Each MSDU already has the MSDU ID stored in the headroom of the
+ *     netbuf data buffer, and has the HTT tx descriptor already attached
+ *     as a prefix fragment to the netbuf.
+ *
+ * @param htt_pdev - the handle of the physical device sending the tx data
+ * @param head_msdu - the MSDU Head for Tx batch being transmitted
+ * @param num_msdus - The total Number of MSDU's provided for batch tx
+ * @return null-terminated linked-list of unaccepted frames
+ */
+cdf_nbuf_t
+htt_tx_send_batch(htt_pdev_handle htt_pdev,
+		  cdf_nbuf_t head_msdu, int num_msdus);
+
+/* The htt scheduler for queued packets in htt
+ * htt when unable to send to HTC because of lack of resource
+ * forms a nbuf queue which is flushed when tx completion event from
+ * target is recieved
+ */
+
+void htt_tx_sched(htt_pdev_handle pdev);
+
+/**
+ * @brief Same as htt_tx_send_std, but can handle raw frames.
+ */
+int
+htt_tx_send_nonstd(htt_pdev_handle htt_pdev,
+		   cdf_nbuf_t msdu,
+		   uint16_t msdu_id, enum htt_pkt_type pkt_type);
+
+/**
+ * htt_pkt_dl_len_get() Gets the HTT PKT download length.
+ * @pdev: pointer to struct htt_pdev_t
+ *
+ * Return: size of HTT packet download length.
+ */
+int
+htt_pkt_dl_len_get(struct htt_pdev_t *pdev);
+
+#define HTT_TX_CLASSIFY_BIT_S	4  /* Used to set
+				    * classify bit in HTT desc.*/
+
+/**
+ * enum htt_ce_tx_pkt_type - enum of packet types to be set in CE
+ *			     descriptor
+ * @tx_pkt_type_raw: Value set for RAW frames
+ * @tx_pkt_type_native_wifi: Value set for NATIVE WIFI frames
+ * @tx_pkt_type_eth2: Value set for Ethernet II frames (mostly default)
+ * @tx_pkt_type_802_3: Value set for 802.3 / original ethernet frames
+ * @tx_pkt_type_mgmt: Value set for MGMT frames over HTT
+ *
+ */
+enum htt_ce_tx_pkt_type {
+	tx_pkt_type_raw = 0,
+	tx_pkt_type_native_wifi = 1,
+	tx_pkt_type_eth2 = 2,
+	tx_pkt_type_802_3 = 3,
+	tx_pkt_type_mgmt = 4
+};
+
+
+extern const uint32_t htt_to_ce_pkt_type[];
+
+/**
+ * Provide a constant to specify the offset of the HTT portion of the
+ * HTT tx descriptor, to avoid having to export the descriptor defintion.
+ * The htt module checks internally that this exported offset is consistent
+ * with the private tx descriptor definition.
+ *
+ * Similarly, export a definition of the HTT tx descriptor size, and then
+ * check internally that this exported constant matches the private tx
+ * descriptor definition.
+ */
+#define HTT_TX_DESC_VADDR_OFFSET 8
+
+/**
+ * htt_tx_desc_init() - Initialize the per packet HTT Tx descriptor
+ * @pdev:		  The handle of the physical device sending the
+ *			  tx data
+ * @htt_tx_desc:	  Abstract handle to the tx descriptor
+ * @htt_tx_desc_paddr_lo: Physical address of the HTT tx descriptor
+ * @msdu_id:		  ID to tag the descriptor with.
+ *			  The FW sends this ID back to host as a cookie
+ *			  during Tx completion, which the host uses to
+ *			  identify the MSDU.
+ *			  This ID is an index into the OL Tx desc. array.
+ * @msdu:		  The MSDU that is being prepared for transmission
+ * @msdu_info:		  Tx MSDU meta-data
+ * @tso_info:		  Storage for TSO meta-data
+ *
+ * This function initializes the HTT tx descriptor.
+ * HTT Tx descriptor is a host-f/w interface structure, and meta-data
+ * accompanying every packet downloaded to f/w via the HTT interface.
+ */
+static inline
+void
+htt_tx_desc_init(htt_pdev_handle pdev,
+		 void *htt_tx_desc,
+		 uint32_t htt_tx_desc_paddr_lo,
+		 uint16_t msdu_id,
+		 cdf_nbuf_t msdu, struct htt_msdu_info_t *msdu_info,
+		 struct cdf_tso_info_t *tso_info,
+		 struct ocb_tx_ctrl_hdr_t *tx_ctrl,
+		 uint8_t is_dsrc)
+{
+	uint8_t  pkt_type, pkt_subtype = 0, ce_pkt_type = 0;
+	uint32_t hw_classify = 0, data_attr = 0;
+	uint32_t *word0, *word1, local_word3;
+#if HTT_PADDR64
+	uint32_t *word4;
+#else /* ! HTT_PADDR64 */
+	uint32_t *word3;
+#endif /* HTT_PADDR64 */
+	uint32_t local_word0, local_word1;
+	struct htt_host_tx_desc_t *htt_host_tx_desc =
+		(struct htt_host_tx_desc_t *)
+		(((char *)htt_tx_desc) - HTT_TX_DESC_VADDR_OFFSET);
+	bool desc_ext_required = (tx_ctrl && tx_ctrl->all_flags != 0);
+
+	word0 = (uint32_t *) htt_tx_desc;
+	word1 = word0 + 1;
+	/*
+	 * word2 is frag desc pointer
+	 * word3 or 4 is peer_id
+	 */
+#if HTT_PADDR64
+	word4 = word0 + 4;      /* Dword 3 */
+#else /* ! HTT_PADDR64  */
+	word3 = word0 + 3;      /* Dword 3 */
+#endif /* HTT_PADDR64 */
+
+	pkt_type = msdu_info->info.l2_hdr_type;
+
+	if (cdf_likely(pdev->cfg.ce_classify_enabled)) {
+		if (cdf_likely(pkt_type == htt_pkt_type_eth2 ||
+			pkt_type == htt_pkt_type_ethernet))
+			cdf_nbuf_tx_info_get(msdu, pkt_type, pkt_subtype,
+				     hw_classify);
+
+		ce_pkt_type = htt_to_ce_pkt_type[pkt_type];
+		if (0xffffffff == ce_pkt_type) {
+			CDF_TRACE(CDF_MODULE_ID_TXRX, CDF_TRACE_LEVEL_DEBUG,
+			"Invalid HTT pkt type %d\n", pkt_type);
+			return;
+		}
+	}
+
+	/*
+	 * HTT Tx Desc is in uncached memory. Used cached writes per word, to
+	 * reduce unnecessary memory access.
+	 */
+
+	local_word0 = 0;
+	if (msdu_info) {
+		HTT_H2T_MSG_TYPE_SET(local_word0, HTT_H2T_MSG_TYPE_TX_FRM);
+		HTT_TX_DESC_PKT_TYPE_SET(local_word0, pkt_type);
+		HTT_TX_DESC_PKT_SUBTYPE_SET(local_word0, pkt_subtype);
+		HTT_TX_DESC_VDEV_ID_SET(local_word0, msdu_info->info.vdev_id);
+		if (tx_ctrl && tx_ctrl->valid_tid)
+			HTT_TX_DESC_EXT_TID_SET(local_word0, tx_ctrl->ext_tid);
+		else
+			HTT_TX_DESC_EXT_TID_SET(local_word0,
+				msdu_info->info.ext_tid);
+		HTT_TX_DESC_EXTENSION_SET(local_word0, desc_ext_required);
+		HTT_TX_DESC_EXT_TID_SET(local_word0, msdu_info->info.ext_tid);
+		HTT_TX_DESC_CKSUM_OFFLOAD_SET(local_word0,
+					      msdu_info->action.cksum_offload);
+		HTT_TX_DESC_NO_ENCRYPT_SET(local_word0,
+					   msdu_info->action.do_encrypt ?
+					   0 : 1);
+	}
+
+	*word0 = local_word0;
+
+	local_word1 = 0;
+
+#if defined(FEATURE_TSO)
+	if (tso_info->is_tso)
+		HTT_TX_DESC_FRM_LEN_SET(local_word1, tso_info->total_len);
+	else
+#endif
+		HTT_TX_DESC_FRM_LEN_SET(local_word1, cdf_nbuf_len(msdu));
+
+	HTT_TX_DESC_FRM_ID_SET(local_word1, msdu_id);
+	*word1 = local_word1;
+
+	/* Initialize peer_id to INVALID_PEER because
+	   this is NOT Reinjection path */
+	local_word3 = HTT_INVALID_PEER;
+	if (tx_ctrl && tx_ctrl->channel_freq)
+		HTT_TX_DESC_CHAN_FREQ_SET(local_word3, tx_ctrl->channel_freq);
+#if HTT_PADDR64
+	*word4 = local_word3;
+#else /* ! HTT_PADDR64 */
+	*word3 = local_word3;
+#endif /* HTT_PADDR64 */
+
+	/*
+	 *  If any of the tx control flags are set, then we need the extended
+	 *  HTT header.
+	 */
+	if (desc_ext_required) {
+		struct htt_tx_msdu_desc_ext_t local_desc_ext = {0};
+
+		/*
+		 * Copy the info that was read from TX control header from the
+		 * user application to the extended HTT header.
+		 * First copy everything
+		 * to a local temp structure, and then copy everything to the
+		 * actual uncached structure in one go to save memory writes.
+		 */
+		local_desc_ext.valid_pwr = tx_ctrl->valid_pwr;
+		local_desc_ext.valid_mcs_mask = tx_ctrl->valid_datarate;
+		local_desc_ext.valid_retries = tx_ctrl->valid_retries;
+		local_desc_ext.valid_expire_tsf = tx_ctrl->valid_expire_tsf;
+		local_desc_ext.valid_chainmask = tx_ctrl->valid_chain_mask;
+
+		local_desc_ext.pwr = tx_ctrl->pwr;
+		if (tx_ctrl->valid_datarate &&
+				tx_ctrl->datarate <= htt_ofdm_datarate_max)
+			local_desc_ext.mcs_mask =
+				(1 << (tx_ctrl->datarate + 4));
+		local_desc_ext.retry_limit = tx_ctrl->retry_limit;
+		local_desc_ext.expire_tsf_lo = tx_ctrl->expire_tsf_lo;
+		local_desc_ext.expire_tsf_hi = tx_ctrl->expire_tsf_hi;
+		local_desc_ext.chain_mask = tx_ctrl->chain_mask;
+
+		local_desc_ext.is_dsrc = (is_dsrc != 0);
+
+		cdf_nbuf_push_head(msdu, sizeof(local_desc_ext));
+		cdf_mem_copy(cdf_nbuf_data(msdu), &local_desc_ext,
+				sizeof(local_desc_ext));
+	}
+
+	/*
+	 * Specify that the data provided by the OS is a bytestream,
+	 * and thus should not be byte-swapped during the HIF download
+	 * even if the host is big-endian.
+	 * There could be extra fragments added before the OS's fragments,
+	 * e.g. for TSO, so it's incorrect to clear the frag 0 wordstream flag.
+	 * Instead, clear the wordstream flag for the final fragment, which
+	 * is certain to be (one of the) fragment(s) provided by the OS.
+	 * Setting the flag for this final fragment suffices for specifying
+	 * all fragments provided by the OS rather than added by the driver.
+	 */
+	cdf_nbuf_set_frag_is_wordstream(msdu, cdf_nbuf_get_num_frags(msdu) - 1,
+					0);
+
+	/* store a link to the HTT tx descriptor within the netbuf */
+	cdf_nbuf_frag_push_head(msdu, sizeof(struct htt_host_tx_desc_t),
+				(char *)htt_host_tx_desc, /* virtual addr */
+				htt_tx_desc_paddr_lo,
+				0 /* phys addr MSBs - n/a */);
+
+	/*
+	 * Indicate that the HTT header (and HTC header) is a meta-data
+	 * "wordstream", i.e. series of uint32_t, rather than a data
+	 * bytestream.
+	 * This allows the HIF download to byteswap the HTT + HTC headers if
+	 * the host is big-endian, to convert to the target's little-endian
+	 * format.
+	 */
+	cdf_nbuf_set_frag_is_wordstream(msdu, 0, 1);
+
+	if (cdf_likely(pdev->cfg.ce_classify_enabled &&
+		(msdu_info->info.l2_hdr_type != htt_pkt_type_mgmt))) {
+		uint32_t pkt_offset = cdf_nbuf_get_frag_len(msdu, 0);
+		data_attr = hw_classify << CDF_CE_TX_CLASSIFY_BIT_S;
+		data_attr |= ce_pkt_type << CDF_CE_TX_PKT_TYPE_BIT_S;
+		data_attr |= pkt_offset  << CDF_CE_TX_PKT_OFFSET_BIT_S;
+	}
+
+	cdf_nbuf_data_attr_set(msdu, data_attr);
+}
+
+/**
+ * @brief Set a flag to indicate that the MSDU in question was postponed.
+ * @details
+ *  In systems in which the host retains its tx frame until the target sends
+ *  a tx completion, the target has the option of discarding it's copy of
+ *  the tx descriptor (and frame, for HL) and sending a "postpone" message
+ *  to the host, to inform the host that it must eventually download the
+ *  tx descriptor (and frame, for HL).
+ *  Before the host downloads the postponed tx desc/frame again, it will use
+ *  this function to set a flag in the HTT tx descriptor indicating that this
+ *  is a re-send of a postponed frame, rather than a new frame.  The target
+ *  uses this flag to keep the correct order between re-sent and new tx frames.
+ *  This function is relevant for LL systems.
+ *
+ * @param pdev - the handle of the physical device sending the tx data
+ * @param desc - abstract handle to the tx descriptor
+ */
+void htt_tx_desc_flag_postponed(htt_pdev_handle pdev, void *desc);
+
+/**
+ * @brief Set a flag to tell the target that more tx downloads are en route.
+ * @details
+ *  At times, particularly in response to a U-APSD trigger in a HL system, the
+ *  host will download multiple tx descriptors (+ frames, in HL) in a batch.
+ *  The host will use this function to set a "more" flag in the initial
+ *  and interior frames of the batch, to tell the target that more tx frame
+ *  downloads within the batch are imminent.
+ *
+ * @param pdev - the handle of the physical device sending the tx data
+ * @param desc - abstract handle to the tx descriptor
+ */
+void htt_tx_desc_flag_batch_more(htt_pdev_handle pdev, void *desc);
+
+/**
+ * @brief Specify the number of fragments in the fragmentation descriptor.
+ * @details
+ *  Specify the number of fragments within the MSDU, i.e. the number of
+ *  elements within the fragmentation descriptor.
+ *  For LL, this is used to terminate the list of fragments used by the
+ *  HW's tx MAC DMA.
+ *  For HL, this is used to terminate the list of fragments provided to
+ *  HTC for download.
+ *
+ * @param pdev - the handle of the physical device sending the tx data
+ * @param desc - abstract handle to the tx descriptor
+ * @param num_frags - the number of fragments comprising the MSDU
+ */
+static inline
+void
+htt_tx_desc_num_frags(htt_pdev_handle pdev, void *desc, uint32_t num_frags)
+{
+	/*
+	 * Set the element after the valid frag elems to 0x0,
+	 * to terminate the list of fragments.
+	 */
+#if defined(HELIUMPLUS_PADDR64)
+	if (HTT_WIFI_IP(pdev, 2, 0)) {
+		/** Skip TSO related 4 dwords WIFI2.0*/
+		desc = (void *)&(((struct msdu_ext_desc_t *)desc)->frag_ptr0);
+		/* Frag ptr is 48 bit wide so clear the next dword as well */
+		*((uint32_t *)(((char *)desc) + (num_frags << 3))) = 0;
+		*((uint32_t *)
+		  (((char *)desc) + (num_frags << 3) + sizeof(uint32_t))) = 0;
+		/* TODO: OKA: remove the magic constants */
+	} else {
+		/* XXXOKA -- Looks like a bug, called with htt_frag_desc */
+		*((u_int32_t *)
+		  (((char *) desc) + HTT_TX_DESC_LEN + num_frags * 8)) = 0;
+	}
+#else /* ! HELIUMPLUS_PADDR64 */
+	*((uint32_t *)
+	  (((char *)desc) + HTT_TX_DESC_LEN + num_frags * 8)) = 0;
+#endif /* HELIUMPLUS_PADDR64 */
+}
+
+/* checksum offload flags for hw */
+#define IPV4_CSUM_EN     0x00010000
+#define UDP_IPV4_CSUM_EN 0x00020000
+#define UDP_IPV6_CSUM_EN 0x00040000
+#define TCP_IPV4_CSUM_EN 0x00080000
+#define TCP_IPV6_CSUM_EN 0x00100000
+#define PARTIAL_CSUM_EN  0x00200000
+
+/**
+ * @brief Specify the location and size of a fragment of a tx MSDU.
+ * @details
+ *  In LL systems, the tx MAC DMA needs to know how the MSDU is constructed
+ *  from fragments.
+ *  In LL and HL systems, the HIF's download DMA to the target (LL: tx desc
+ *  + header of tx payload; HL: tx desc + entire tx payload) needs to know
+ *  where to find the fragments to download.
+ *  The tx data SW uses this function to specify the location and size of
+ *  each of the MSDU's fragments.
+ *
+ * @param pdev - the handle of the physical device sending the tx data
+ * @param desc - abstract handle to the HTT tx descriptor
+ * @param frag_num - which fragment is being specified (zero-based indexing)
+ * @param frag_phys_addr - DMA/physical address of the fragment
+ * @param frag_len - number of bytes within the fragment
+ */
+static inline
+void
+htt_tx_desc_frag(htt_pdev_handle pdev,
+		 void *desc,
+		 int frag_num, uint32_t frag_phys_addr, uint16_t frag_len)
+{
+	u_int32_t *word;
+
+#if defined(HELIUMPLUS_PADDR64)
+	if (HTT_WIFI_IP(pdev, 2, 0)) {
+		word = (u_int32_t *)(desc);
+		/* Initialize top 6 words of TSO flags per packet */
+		*word++ = 0;
+		*word++ = 0;
+		*word++ = 0;
+		if (((struct txrx_pdev_cfg_t *)(pdev->ctrl_pdev))
+		    ->ip_tcp_udp_checksum_offload)
+			*word |= (IPV4_CSUM_EN | TCP_IPV4_CSUM_EN |
+					TCP_IPV6_CSUM_EN | UDP_IPV4_CSUM_EN |
+					UDP_IPV6_CSUM_EN);
+		else
+			*word = 0;
+		word++;
+		*word++ = 0;
+		*word++ = 0;
+
+		cdf_assert_always(word == &(((struct msdu_ext_desc_t *)
+					     desc)->frag_ptr0));
+
+		/* Each fragment consumes 2 DWORDS */
+		word += (frag_num << 1);
+		*word = frag_phys_addr;
+
+		word++;
+		*word = (frag_len<<16);
+
+	} else {
+		/* For Helium+, this block cannot exist */
+		CDF_ASSERT(0);
+	}
+#else /* !defined(HELIUMPLUS_PADDR64) */
+	word = (uint32_t *) (((char *)desc) + HTT_TX_DESC_LEN + frag_num * 8);
+	*word = frag_phys_addr;
+	word++;
+	*word = frag_len;
+#endif /* defined(HELIUMPLUS_PADDR64) */
+}
+
+void htt_tx_desc_frags_table_set(htt_pdev_handle pdev,
+				 void *desc,
+				 uint32_t paddr,
+				 uint32_t frag_desc_paddr_lo,
+				 int reset);
+
+/**
+ * @brief Specify the type and subtype of a tx frame.
+ *
+ * @param pdev - the handle of the physical device sending the tx data
+ * @param type - format of the MSDU (802.3, native WiFi, raw, or mgmt)
+ * @param sub_type - sub_type (relevant for raw frames)
+ */
+static inline
+void
+htt_tx_desc_type(htt_pdev_handle pdev,
+		 void *htt_tx_desc, enum wlan_frm_fmt type, uint8_t sub_type)
+{
+	uint32_t *word0;
+
+	word0 = (uint32_t *) htt_tx_desc;
+	/* clear old values */
+	*word0 &= ~(HTT_TX_DESC_PKT_TYPE_M | HTT_TX_DESC_PKT_SUBTYPE_M);
+	/* write new values */
+	HTT_TX_DESC_PKT_TYPE_SET(*word0, type);
+	HTT_TX_DESC_PKT_SUBTYPE_SET(*word0, sub_type);
+}
+
+/***** TX MGMT DESC management APIs ****/
+
+/* Number of mgmt descriptors in the pool */
+#define HTT_MAX_NUM_MGMT_DESCS 32
+
+/** htt_tx_mgmt_desc_pool_alloc
+ * @description - allocates the memory for mgmt frame descriptors
+ * @param  - htt pdev object
+ * @param  - num of descriptors to be allocated in the pool
+ */
+void htt_tx_mgmt_desc_pool_alloc(struct htt_pdev_t *pdev, A_UINT32 num_elems);
+
+/** htt_tx_mgmt_desc_alloc
+ * @description - reserves a mgmt descriptor from the pool
+ * @param  - htt pdev object
+ * @param  - pointer to variable to hold the allocated desc id
+ * @param  - pointer to the mamangement from UMAC
+ * @return - pointer the allocated mgmt descriptor
+ */
+cdf_nbuf_t
+htt_tx_mgmt_desc_alloc(struct htt_pdev_t *pdev, A_UINT32 *desc_id,
+		       cdf_nbuf_t mgmt_frm);
+
+/** htt_tx_mgmt_desc_free
+ * @description - releases the management descriptor back to the pool
+ * @param  - htt pdev object
+ * @param  - descriptor ID
+ */
+void
+htt_tx_mgmt_desc_free(struct htt_pdev_t *pdev, A_UINT8 desc_id,
+		      A_UINT32 status);
+
+/** htt_tx_mgmt_desc_pool_free
+ * @description - releases all the resources allocated for mgmt desc pool
+ * @param  - htt pdev object
+ */
+void htt_tx_mgmt_desc_pool_free(struct htt_pdev_t *pdev);
+
+/**
+ * @brief Provide a buffer to store a 802.11 header added by SW tx encap
+ *
+ * @param htt_tx_desc - which frame the 802.11 header is being added to
+ * @param new_l2_hdr_size - how large the buffer needs to be
+ */
+#define htt_tx_desc_mpdu_header(htt_tx_desc, new_l2_hdr_size) /*NULL*/
+/**
+ * @brief How many tx credits would be consumed by the specified tx frame.
+ *
+ * @param msdu - the tx frame in question
+ * @return number of credits used for this tx frame
+ */
+#define htt_tx_msdu_credit(msdu) 1      /* 1 credit per buffer */
+#ifdef HTT_DBG
+void htt_tx_desc_display(void *tx_desc);
+#else
+#define htt_tx_desc_display(tx_desc)
+#endif
+
+static inline void htt_tx_desc_set_peer_id(void *htt_tx_desc, uint16_t peer_id)
+{
+	uint16_t *peer_id_field_ptr;
+
+	peer_id_field_ptr = (uint16_t *)
+			    (htt_tx_desc +
+			     HTT_TX_DESC_PEERID_DESC_PADDR_OFFSET_BYTES);
+
+	*peer_id_field_ptr = peer_id;
+}
+
+static inline
+void htt_tx_desc_set_chanfreq(void *htt_tx_desc, uint16_t chanfreq)
+{
+	uint16_t *chanfreq_field_ptr;
+
+	/* The reason we dont use CHAN_FREQ_OFFSET_BYTES is because
+	   it uses DWORD as unit */
+	/* The reason we dont use the SET macro in htt.h is because
+	   htt_tx_desc is incomplete type */
+	chanfreq_field_ptr = (uint16_t *)
+		(htt_tx_desc +
+		 HTT_TX_DESC_PEERID_DESC_PADDR_OFFSET_BYTES
+		 + sizeof(A_UINT16));
+
+	*chanfreq_field_ptr = chanfreq;
+}
+
+#if defined(FEATURE_TSO)
+void
+htt_tx_desc_fill_tso_info(htt_pdev_handle pdev, void *desc,
+	 struct cdf_tso_info_t *tso_info);
+#else
+#define htt_tx_desc_fill_tso_info(pdev, desc, tso_info)
+#endif
+#endif /* _OL_HTT_TX_API__H_ */