/*
 * Copyright (c) 2012-2017 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.
 */

#include <qdf_nbuf.h>         /* qdf_nbuf_t, etc. */
#include <htt.h>              /* HTT_TX_EXT_TID_MGMT */
#include <ol_htt_tx_api.h>    /* htt_tx_desc_tid */
#include <ol_txrx_api.h>      /* ol_txrx_vdev_handle */
#include <ol_txrx_ctrl_api.h> /* ol_txrx_sync */
#include <ol_txrx.h>
#include <ol_txrx_internal.h> /* TXRX_ASSERT1 */
#include <ol_txrx_types.h>    /* pdev stats */
#include <ol_tx_desc.h>       /* ol_tx_desc */
#include <ol_tx_send.h>       /* ol_tx_send */
#include <ol_txrx_peer_find.h>
#include <ol_tx_classify.h>
#include <ol_tx_queue.h>
#include <ipv4.h>
#include <ipv6_defs.h>
#include <ip_prot.h>
#include <enet.h>             /* ETHERTYPE_VLAN, etc. */
#include <cds_ieee80211_common.h>        /* ieee80211_frame */
#include <cdp_txrx_handle.h>
/*
 * In theory, this tx classify code could be used on the host or in the target.
 * Thus, this code uses generic OS primitives, that can be aliased to either
 * the host's OS primitives or the target's OS primitives.
 * For now, the following #defines set up these host-specific or
 * target-specific aliases.
 */

#if defined(CONFIG_HL_SUPPORT)

#define OL_TX_CLASSIFY_EXTENSION(vdev, tx_desc, netbuf, msdu_info, txq)
#define OL_TX_CLASSIFY_MGMT_EXTENSION(vdev, tx_desc, netbuf, msdu_info, txq)

#ifdef QCA_TX_HTT2_SUPPORT
static void
ol_tx_classify_htt2_frm(
	struct ol_txrx_vdev_t *vdev,
	qdf_nbuf_t tx_nbuf,
	struct ol_txrx_msdu_info_t *tx_msdu_info)
{
	struct htt_msdu_info_t *htt = &tx_msdu_info->htt;
	A_UINT8 candi_frm = 0;

	/*
	 * Offload the frame re-order to L3 protocol and ONLY support
	 * TCP protocol now.
	 */
	if ((htt->info.l2_hdr_type == htt_pkt_type_ethernet) &&
	    (htt->info.frame_type == htt_frm_type_data) &&
	    htt->info.is_unicast &&
	    (htt->info.ethertype == ETHERTYPE_IPV4)) {
		struct ipv4_hdr_t *ipHdr;

		ipHdr = (struct ipv4_hdr_t *)(qdf_nbuf_data(tx_nbuf) +
			htt->info.l3_hdr_offset);
		if (ipHdr->protocol == IP_PROTOCOL_TCP)
			candi_frm = 1;
	}

	qdf_nbuf_set_tx_parallel_dnload_frm(tx_nbuf, candi_frm);
}

#define OL_TX_CLASSIFY_HTT2_EXTENSION(vdev, netbuf, msdu_info)      \
	ol_tx_classify_htt2_frm(vdev, netbuf, msdu_info)
#else
#define OL_TX_CLASSIFY_HTT2_EXTENSION(vdev, netbuf, msdu_info)      /* no-op */
#endif /* QCA_TX_HTT2_SUPPORT */
/* DHCP go with voice priority; WMM_AC_VO_TID1();*/
#define TX_DHCP_TID  6

#if defined(QCA_BAD_PEER_TX_FLOW_CL)
static inline A_BOOL
ol_if_tx_bad_peer_txq_overflow(
	struct ol_txrx_pdev_t *pdev,
	struct ol_txrx_peer_t *peer,
	struct ol_tx_frms_queue_t *txq)
{
	if (peer && pdev && txq && (peer->tx_limit_flag) &&
	    (txq->frms >= pdev->tx_peer_bal.peer_bal_txq_limit))
		return true;
	else
		return false;
}
#else
static inline A_BOOL ol_if_tx_bad_peer_txq_overflow(
	struct ol_txrx_pdev_t *pdev,
	struct ol_txrx_peer_t *peer,
	struct ol_tx_frms_queue_t *txq)
{
	return false;
}
#endif

/* EAPOL go with voice priority: WMM_AC_TO_TID1(WMM_AC_VO);*/
#define TX_EAPOL_TID  6

/* ARP go with voice priority: WMM_AC_TO_TID1(pdev->arp_ac_override)*/
#define TX_ARP_TID  6

/* For non-IP case, use default TID */
#define TX_DEFAULT_TID  0

/*
 * Determine IP TOS priority
 * IP Tos format :
 *        (Refer Pg 57 WMM-test-plan-v1.2)
 * IP-TOS - 8bits
 *            : DSCP(6-bits) ECN(2-bits)
 *            : DSCP - P2 P1 P0 X X X
 *                where (P2 P1 P0) form 802.1D
 */
static inline A_UINT8
ol_tx_tid_by_ipv4(A_UINT8 *pkt)
{
	A_UINT8 ipPri, tid;
	struct ipv4_hdr_t *ipHdr = (struct ipv4_hdr_t *)pkt;

	ipPri = ipHdr->tos >> 5;
	tid = ipPri & 0x7;

	return tid;
}

static inline A_UINT8
ol_tx_tid_by_ipv6(A_UINT8 *pkt)
{
	return (ipv6_traffic_class((struct ipv6_hdr_t *)pkt) >> 5) & 0x7;
}

static inline void
ol_tx_set_ether_type(
	A_UINT8 *datap,
	struct ol_txrx_msdu_info_t *tx_msdu_info)
{
	A_UINT16 typeorlength;
	A_UINT8 *ptr;
	A_UINT8 *l3_data_ptr;

	if (tx_msdu_info->htt.info.l2_hdr_type == htt_pkt_type_raw) {
		/* adjust hdr_ptr to RA */
		struct ieee80211_frame *wh = (struct ieee80211_frame *)datap;

		if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
					IEEE80211_FC0_TYPE_DATA) {
			struct llc_snap_hdr_t *llc;
			/* dot11 encapsulated frame */
			struct ieee80211_qosframe *whqos =
					(struct ieee80211_qosframe *)datap;
			if (whqos->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) {
				tx_msdu_info->htt.info.l3_hdr_offset =
					sizeof(struct ieee80211_qosframe);
			} else {
				tx_msdu_info->htt.info.l3_hdr_offset =
					sizeof(struct ieee80211_frame);
			}
			llc = (struct llc_snap_hdr_t *)
				(datap + tx_msdu_info->htt.info.l3_hdr_offset);
			tx_msdu_info->htt.info.ethertype =
				(llc->ethertype[0] << 8) | llc->ethertype[1];
			/*
			 * l3_hdr_offset refers to the end of the 802.3 or
			 * 802.11 header, which may be a LLC/SNAP header rather
			 * than the IP header.
			 * Thus, don't increment l3_hdr_offset += sizeof(*llc);
			 * rather,leave it as is.
			 */
		} else {
			/*
			 * This function should only be applied to data frames.
			 * For management frames, we already know to use
			 * HTT_TX_EXT_TID_MGMT.
			 */
			TXRX_ASSERT2(0);
		}
	} else if (tx_msdu_info->htt.info.l2_hdr_type ==
					htt_pkt_type_ethernet) {
		ptr = (datap + ETHERNET_ADDR_LEN * 2);
		typeorlength = (ptr[0] << 8) | ptr[1];
		/*ETHERNET_HDR_LEN;*/
		l3_data_ptr = datap + sizeof(struct ethernet_hdr_t);

		if (typeorlength == ETHERTYPE_VLAN) {
			ptr = (datap + ETHERNET_ADDR_LEN * 2
					+ ETHERTYPE_VLAN_LEN);
			typeorlength = (ptr[0] << 8) | ptr[1];
			l3_data_ptr += ETHERTYPE_VLAN_LEN;
		}

		if (!IS_ETHERTYPE(typeorlength)) {
			/* 802.3 header*/
			struct llc_snap_hdr_t *llc_hdr =
				(struct llc_snap_hdr_t *)l3_data_ptr;
			typeorlength = (llc_hdr->ethertype[0] << 8) |
							llc_hdr->ethertype[1];
			l3_data_ptr += sizeof(struct llc_snap_hdr_t);
		}

		tx_msdu_info->htt.info.l3_hdr_offset = (A_UINT8)(l3_data_ptr -
									datap);
		tx_msdu_info->htt.info.ethertype = typeorlength;
	}
}

static inline A_UINT8
ol_tx_tid_by_ether_type(
	A_UINT8 *datap,
	struct ol_txrx_msdu_info_t *tx_msdu_info)
{
	A_UINT8 tid;
	A_UINT8 *l3_data_ptr;
	A_UINT16 typeorlength;

	l3_data_ptr = datap + tx_msdu_info->htt.info.l3_hdr_offset;
	typeorlength = tx_msdu_info->htt.info.ethertype;

	/* IP packet, do packet inspection for TID */
	if (typeorlength == ETHERTYPE_IPV4) {
		tid = ol_tx_tid_by_ipv4(l3_data_ptr);
	} else if (typeorlength == ETHERTYPE_IPV6) {
		tid = ol_tx_tid_by_ipv6(l3_data_ptr);
	} else if (ETHERTYPE_IS_EAPOL_WAPI(typeorlength)) {
		/* EAPOL go with voice priority*/
		tid = TX_EAPOL_TID;
	} else if (typeorlength == ETHERTYPE_ARP) {
		tid = TX_ARP_TID;
	} else {
		/* For non-IP case, use default TID */
		tid = TX_DEFAULT_TID;
	}
	return tid;
}

static inline A_UINT8
ol_tx_tid_by_raw_type(
	A_UINT8 *datap,
	struct ol_txrx_msdu_info_t *tx_msdu_info)
{
	A_UINT8 tid = HTT_TX_EXT_TID_NON_QOS_MCAST_BCAST;

	/* adjust hdr_ptr to RA */
	struct ieee80211_frame *wh = (struct ieee80211_frame *)datap;

	/* FIXME: This code does not handle 4 address formats. The QOS field
	 * is not at usual location.
	 */
	if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
					IEEE80211_FC0_TYPE_DATA) {
		/* dot11 encapsulated frame */
		struct ieee80211_qosframe *whqos =
					(struct ieee80211_qosframe *)datap;
		if (whqos->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS)
			tid = whqos->i_qos[0] & IEEE80211_QOS_TID;
		else
			tid = HTT_NON_QOS_TID;
	} else {
		/*
		 * This function should only be applied to data frames.
		 * For management frames, we already know to use
		 * HTT_TX_EXT_TID_MGMT.
		 */
		qdf_assert(0);
	}
	return tid;
}

static A_UINT8
ol_tx_tid(
	struct ol_txrx_pdev_t *pdev,
	qdf_nbuf_t tx_nbuf,
	struct ol_txrx_msdu_info_t *tx_msdu_info)
{
	A_UINT8 *datap = qdf_nbuf_data(tx_nbuf);
	A_UINT8 tid;

	if (pdev->frame_format == wlan_frm_fmt_raw) {
		tx_msdu_info->htt.info.l2_hdr_type = htt_pkt_type_raw;

		ol_tx_set_ether_type(datap, tx_msdu_info);
		tid = tx_msdu_info->htt.info.ext_tid ==
					QDF_NBUF_TX_EXT_TID_INVALID ?
			ol_tx_tid_by_raw_type(datap, tx_msdu_info) :
			tx_msdu_info->htt.info.ext_tid;
	} else if (pdev->frame_format == wlan_frm_fmt_802_3) {
		tx_msdu_info->htt.info.l2_hdr_type = htt_pkt_type_ethernet;

		ol_tx_set_ether_type(datap, tx_msdu_info);
		tid =
			tx_msdu_info->htt.info.ext_tid ==
					QDF_NBUF_TX_EXT_TID_INVALID ?
				ol_tx_tid_by_ether_type(datap, tx_msdu_info) :
				tx_msdu_info->htt.info.ext_tid;
	} else if (pdev->frame_format == wlan_frm_fmt_native_wifi) {
		struct llc_snap_hdr_t *llc;

		tx_msdu_info->htt.info.l2_hdr_type = htt_pkt_type_native_wifi;
		tx_msdu_info->htt.info.l3_hdr_offset =
						sizeof(struct ieee80211_frame);
		llc = (struct llc_snap_hdr_t *)
			(datap + tx_msdu_info->htt.info.l3_hdr_offset);
		tx_msdu_info->htt.info.ethertype =
			(llc->ethertype[0] << 8) | llc->ethertype[1];
		/*
		 * Native WiFi is a special case of "raw" 802.11 header format.
		 * However, we expect that for all cases that use native WiFi,
		 * the TID will be directly specified out of band.
		 */
		tid = tx_msdu_info->htt.info.ext_tid;
	} else {
		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_FATAL,
			  "Invalid standard frame type: %d\n",
			  pdev->frame_format);
		qdf_assert(0);
		tid = HTT_TX_EXT_TID_INVALID;
	}
	return tid;
}

#if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS)
static inline
struct ol_txrx_peer_t *ol_tx_tdls_peer_find(struct ol_txrx_pdev_t *pdev,
						struct ol_txrx_vdev_t *vdev,
						uint8_t *peer_id)
{
	struct ol_txrx_peer_t *peer = NULL;

	if (vdev->hlTdlsFlag) {
		peer = ol_txrx_find_peer_by_addr((struct cdp_pdev *)pdev,
						vdev->hl_tdls_ap_mac_addr.raw,
						peer_id);
		if (peer &&  (peer->peer_ids[0] == HTT_INVALID_PEER_ID)) {
			peer = NULL;
		} else {
			if (peer)
				OL_TXRX_PEER_INC_REF_CNT(peer);
		}
	}
	if (!peer)
		peer = ol_txrx_assoc_peer_find(vdev);

	return peer;
}

#else
struct ol_txrx_peer_t *ol_tx_tdls_peer_find(struct ol_txrx_pdev_t *pdev,
						struct ol_txrx_vdev_t *vdev,
						uint8_t *peer_id)
{
	struct ol_txrx_peer_t *peer = NULL;

	peer = ol_txrx_assoc_peer_find(vdev);

	return peer;
}


#endif

struct ol_tx_frms_queue_t *
ol_tx_classify(
	struct ol_txrx_vdev_t *vdev,
	struct ol_tx_desc_t *tx_desc,
	qdf_nbuf_t tx_nbuf,
	struct ol_txrx_msdu_info_t *tx_msdu_info)
{
	struct ol_txrx_pdev_t *pdev = vdev->pdev;
	struct ol_txrx_peer_t *peer = NULL;
	struct ol_tx_frms_queue_t *txq = NULL;
	A_UINT8 *dest_addr;
	A_UINT8 tid;
	u_int8_t peer_id;

	TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);
	dest_addr = ol_tx_dest_addr_find(pdev, tx_nbuf);
	if (unlikely(NULL == dest_addr)) {
		QDF_TRACE(QDF_MODULE_ID_TXRX,
				QDF_TRACE_LEVEL_ERROR,
				"Error: dest_addr is NULL.\n");
		return NULL; /*error*/
	}
	if ((IEEE80211_IS_MULTICAST(dest_addr)) ||
	    (vdev->opmode == wlan_op_mode_ocb)) {
		txq = &vdev->txqs[OL_TX_VDEV_MCAST_BCAST];
		tx_msdu_info->htt.info.ext_tid =
					HTT_TX_EXT_TID_NON_QOS_MCAST_BCAST;
		if (vdev->opmode == wlan_op_mode_sta) {
			/*
			 * The STA sends a frame with a broadcast
			 * dest addr (DA) as a
			 * unicast frame to the AP's receive addr (RA).
			 * Find the peer object that represents the AP
			 * that the STA is associated with.
			 */
			peer = ol_txrx_assoc_peer_find(vdev);
			if (!peer) {
				QDF_TRACE(QDF_MODULE_ID_TXRX,
					  QDF_TRACE_LEVEL_ERROR,
					  "Error: STA %p (%02x:%02x:%02x:%02x:%02x:%02x) trying to send bcast DA tx data frame w/o association\n",
					  vdev,
					  vdev->mac_addr.raw[0],
					  vdev->mac_addr.raw[1],
					  vdev->mac_addr.raw[2],
					  vdev->mac_addr.raw[3],
					  vdev->mac_addr.raw[4],
					  vdev->mac_addr.raw[5]);
				return NULL; /* error */
			} else if ((peer->security[
				OL_TXRX_PEER_SECURITY_MULTICAST].sec_type
						!= htt_sec_type_wapi) &&
				   (qdf_nbuf_is_ipv4_pkt(tx_nbuf) == true)) {
				if (QDF_NBUF_CB_PACKET_TYPE_DHCP ==
						QDF_NBUF_CB_GET_PACKET_TYPE(
								tx_nbuf)) {
					/* DHCP frame to go with
					 * voice priority
					 */
					txq = &peer->txqs[TX_DHCP_TID];
					tx_msdu_info->htt.info.ext_tid =
								TX_DHCP_TID;
				}
			}
			/*
			 * The following line assumes each peer object has a
			 * single ID. This is currently true, and is expected
			 * to remain true.
			 */
			tx_msdu_info->htt.info.peer_id = peer->peer_ids[0];
		} else if (vdev->opmode == wlan_op_mode_ocb) {
			tx_msdu_info->htt.info.peer_id = HTT_INVALID_PEER_ID;
			/*
			 * In OCB mode, don't worry about the peer.
			 * We don't need it.
			 */
			peer = NULL;
		} else {
			tx_msdu_info->htt.info.peer_id = HTT_INVALID_PEER_ID;
			/*
			 * Look up the vdev's BSS peer, so that the
			 * classify_extension function can check whether to
			 * encrypt multicast / broadcast frames.
			 */
			peer = ol_txrx_peer_find_hash_find(pdev,
							vdev->mac_addr.raw,
							0, 1);
			if (!peer) {
				QDF_TRACE(QDF_MODULE_ID_TXRX,
					  QDF_TRACE_LEVEL_ERROR,
					  "Error: vdev %p (%02x:%02x:%02x:%02x:%02x:%02x) trying to send bcast/mcast, but no self-peer found\n",
					  vdev,
					  vdev->mac_addr.raw[0],
					  vdev->mac_addr.raw[1],
					  vdev->mac_addr.raw[2],
					  vdev->mac_addr.raw[3],
					  vdev->mac_addr.raw[4],
					  vdev->mac_addr.raw[5]);
				return NULL; /* error */
			}
		}
		tx_msdu_info->htt.info.is_unicast = false;
	} else {
		/* tid would be overwritten for non QoS case*/
		tid = ol_tx_tid(pdev, tx_nbuf, tx_msdu_info);
		if ((HTT_TX_EXT_TID_INVALID == tid) ||
		    (tid >= OL_TX_NUM_TIDS)) {
			QDF_TRACE(QDF_MODULE_ID_TXRX,
				  QDF_TRACE_LEVEL_ERROR,
				  "%s Error: could not classify packet into valid TID(%d).\n",
				  __func__, tid);
			return NULL;
		}
#ifdef ATH_SUPPORT_WAPI
		/* Check to see if a frame is a WAI frame */
		if (tx_msdu_info->htt.info.ethertype == ETHERTYPE_WAI) {
			/* WAI frames should not be encrypted */
			tx_msdu_info->htt.action.do_encrypt = 0;
			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
				  "Tx Frame is a WAI frame\n");
		}
#endif /* ATH_SUPPORT_WAPI */

		/*
		 * Find the peer and increment its reference count.
		 * If this vdev is an AP, use the dest addr (DA) to determine
		 * which peer STA this unicast data frame is for.
		 * If this vdev is a STA, the unicast data frame is for the
		 * AP the STA is associated with.
		 */
		if (vdev->opmode == wlan_op_mode_sta) {
			/*
			 * TO DO:
			 * To support TDLS, first check if there is a TDLS
			 * peer STA,
			 * and if so, check if the DA matches the TDLS peer
			 * STA's MAC address. If there is no peer TDLS STA,
			 * or if the DA is not the TDLS STA's address,
			 * then the frame is either for the AP itself, or is
			 * supposed to be sent to the AP for forwarding.
			 */
			peer = ol_tx_tdls_peer_find(pdev, vdev, &peer_id);
		} else {
			peer = ol_txrx_peer_find_hash_find(pdev, dest_addr,
									0, 1);
		}
		tx_msdu_info->htt.info.is_unicast = true;
		if (!peer) {
			/*
			 * Unicast data xfer can only happen to an
			 * associated peer. It is illegitimate to send unicast
			 * data if there is no peer to send it to.
			 */
			QDF_TRACE(QDF_MODULE_ID_TXRX,
				  QDF_TRACE_LEVEL_ERROR,
				  "Error: vdev %p (%02x:%02x:%02x:%02x:%02x:%02x) trying to send unicast tx data frame to an unknown peer\n",
				  vdev,
				  vdev->mac_addr.raw[0], vdev->mac_addr.raw[1],
				  vdev->mac_addr.raw[2], vdev->mac_addr.raw[3],
				  vdev->mac_addr.raw[4], vdev->mac_addr.raw[5]);
			return NULL; /* error */
		}
		TX_SCHED_DEBUG_PRINT("Peer found\n");
		if (!peer->qos_capable) {
			tid = OL_TX_NON_QOS_TID;
		} else if ((peer->security[
				OL_TXRX_PEER_SECURITY_UNICAST].sec_type
					!= htt_sec_type_wapi) &&
			   (qdf_nbuf_is_ipv4_pkt(tx_nbuf) == true)) {
			if (QDF_NBUF_CB_PACKET_TYPE_DHCP ==
					QDF_NBUF_CB_GET_PACKET_TYPE(tx_nbuf))
				/* DHCP frame to go with voice priority */
				tid = TX_DHCP_TID;
		}

		/* Only allow encryption when in authenticated state */
		if (OL_TXRX_PEER_STATE_AUTH != peer->state)
			tx_msdu_info->htt.action.do_encrypt = 0;

		txq = &peer->txqs[tid];
		tx_msdu_info->htt.info.ext_tid = tid;
		/*
		 * The following line assumes each peer object has a single ID.
		 * This is currently true, and is expected to remain true.
		 */
		tx_msdu_info->htt.info.peer_id = peer->peer_ids[0];
		/*
		 * WORKAROUND - check that the peer ID is valid.
		 * If tx data is provided before ol_rx_peer_map_handler is
		 * called to record the peer ID specified by the target,
		 * then we could end up here with an invalid peer ID.
		 * TO DO: rather than dropping the tx frame, pause the txq it
		 * goes into, then fill in the peer ID for the entries in the
		 * txq when the peer_map event provides the peer ID, and then
		 * unpause the txq.
		 */
		if (tx_msdu_info->htt.info.peer_id == HTT_INVALID_PEER_ID) {
			if (peer) {
				ol_txrx_info(
					   "%s: remove the peer for invalid peer_id %p\n",
					   __func__, peer);
				/* remove the peer reference added above */
				OL_TXRX_PEER_UNREF_DELETE(peer);
				tx_msdu_info->peer = NULL;
			}
			return NULL;
		}
	}
	tx_msdu_info->peer = peer;
	if (ol_if_tx_bad_peer_txq_overflow(pdev, peer, txq))
		return NULL;
	/*
	 * If relevant, do a deeper inspection to determine additional
	 * characteristics of the tx frame.
	 * If the frame is invalid, then the txq will be set to NULL to
	 * indicate an error.
	 */
	OL_TX_CLASSIFY_EXTENSION(vdev, tx_desc, tx_nbuf, tx_msdu_info, txq);
	if (IEEE80211_IS_MULTICAST(dest_addr) && vdev->opmode !=
				wlan_op_mode_sta && tx_msdu_info->peer !=
								NULL) {
		ol_txrx_dbg(
			   "%s: remove the peer reference %p\n",
			   __func__, peer);
		/* remove the peer reference added above */
		OL_TXRX_PEER_UNREF_DELETE(tx_msdu_info->peer);
		/* Making peer NULL in case if multicast non STA mode */
		tx_msdu_info->peer = NULL;
	}

	/* Whether this frame can download though HTT2 data pipe or not. */
	OL_TX_CLASSIFY_HTT2_EXTENSION(vdev, tx_nbuf, tx_msdu_info);

	/* Update Tx Queue info */
	tx_desc->txq = txq;

	TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
	return txq;
}

struct ol_tx_frms_queue_t *
ol_tx_classify_mgmt(
	struct ol_txrx_vdev_t *vdev,
	struct ol_tx_desc_t *tx_desc,
	qdf_nbuf_t tx_nbuf,
	struct ol_txrx_msdu_info_t *tx_msdu_info)
{
	struct ol_txrx_pdev_t *pdev = vdev->pdev;
	struct ol_txrx_peer_t *peer = NULL;
	struct ol_tx_frms_queue_t *txq = NULL;
	A_UINT8 *dest_addr;
	union ol_txrx_align_mac_addr_t local_mac_addr_aligned, *mac_addr;

	TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);
	dest_addr = ol_tx_dest_addr_find(pdev, tx_nbuf);
	if (unlikely(NULL == dest_addr)) {
		QDF_TRACE(QDF_MODULE_ID_TXRX,
				QDF_TRACE_LEVEL_ERROR,
				"Error: dest_addr is NULL.\n");
		return NULL; /*error*/
	}
	if (IEEE80211_IS_MULTICAST(dest_addr)) {
		/*
		 * AP:  beacons are broadcast,
		 *      public action frames (e.g. extended channel
		 *      switch announce) may be broadcast
		 * STA: probe requests can be either broadcast or unicast
		 */
		txq = &vdev->txqs[OL_TX_VDEV_DEFAULT_MGMT];
		tx_msdu_info->htt.info.peer_id = HTT_INVALID_PEER_ID;
		tx_msdu_info->peer = NULL;
		tx_msdu_info->htt.info.is_unicast = 0;
	} else {
		/*
		 * Find the peer and increment its reference count.
		 * If this vdev is an AP, use the receiver addr (RA) to
		 * determine which peer STA this unicast mgmt frame is for.
		 * If this vdev is a STA, the unicast mgmt frame is for the
		 * AP the STA is associated with.
		 * Probe request / response and Assoc request / response are
		 * sent before the peer exists - in this case, use the
		 * vdev's default tx queue.
		 */
		if (vdev->opmode == wlan_op_mode_sta) {
			/*
			 * TO DO:
			 * To support TDLS, first check if there is a TDLS
			 * peer STA, and if so, check if the DA matches
			 * the TDLS peer STA's MAC address.
			 */
			peer = ol_txrx_assoc_peer_find(vdev);
			/*
			 * Some special case(preauth for example) needs to send
			 * unicast mgmt frame to unassociated AP. In such case,
			 * we need to check if dest addr match the associated
			 * peer addr. If not, we set peer as NULL to queue this
			 * frame to vdev queue.
			 */
			if (peer) {
				int rcnt;

				qdf_mem_copy(
					&local_mac_addr_aligned.raw[0],
					dest_addr, OL_TXRX_MAC_ADDR_LEN);
				mac_addr = &local_mac_addr_aligned;
				if (ol_txrx_peer_find_mac_addr_cmp(
							mac_addr,
							&peer->mac_addr) != 0) {
					rcnt = OL_TXRX_PEER_UNREF_DELETE(peer);
					peer = NULL;
				}
			}
		} else {
			/* find the peer and increment its reference count */
			peer = ol_txrx_peer_find_hash_find(pdev, dest_addr,
							   0, 1);
		}
		tx_msdu_info->peer = peer;
		if (!peer) {
			txq = &vdev->txqs[OL_TX_VDEV_DEFAULT_MGMT];
			tx_msdu_info->htt.info.peer_id = HTT_INVALID_PEER_ID;
		} else {
			txq = &peer->txqs[HTT_TX_EXT_TID_MGMT];
			tx_msdu_info->htt.info.ext_tid = HTT_TX_EXT_TID_MGMT;
			/*
			 * The following line assumes each peer object has a
			 * single ID. This is currently true, and is expected
			 * to remain true.
			 */
			tx_msdu_info->htt.info.peer_id = peer->peer_ids[0];
		}
		tx_msdu_info->htt.info.is_unicast = 1;
	}
	/*
	 * If relevant, do a deeper inspection to determine additional
	 * characteristics of the tx frame.
	 * If the frame is invalid, then the txq will be set to NULL to
	 * indicate an error.
	 */
	OL_TX_CLASSIFY_MGMT_EXTENSION(vdev, tx_desc, tx_nbuf,
				      tx_msdu_info, txq);

	/* Whether this frame can download though HTT2 data pipe or not. */
	OL_TX_CLASSIFY_HTT2_EXTENSION(vdev, tx_nbuf, tx_msdu_info);

	/* Update Tx Queue info */
	tx_desc->txq = txq;

	TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
	return txq;
}

A_STATUS
ol_tx_classify_extension(
	struct ol_txrx_vdev_t *vdev,
	struct ol_tx_desc_t *tx_desc,
	qdf_nbuf_t tx_msdu,
	struct ol_txrx_msdu_info_t *msdu_info)
{
	A_UINT8 *datap = qdf_nbuf_data(tx_msdu);
	struct ol_txrx_peer_t *peer;
	int which_key;

	/*
	 * The following msdu_info fields were already filled in by the
	 * ol_tx entry function or the regular ol_tx_classify function:
	 *     htt.info.vdev_id            (ol_tx_hl or ol_tx_non_std_hl)
	 *     htt.info.ext_tid            (ol_tx_non_std_hl or ol_tx_classify)
	 *     htt.info.frame_type         (ol_tx_hl or ol_tx_non_std_hl)
	 *     htt.info.l2_hdr_type        (ol_tx_hl or ol_tx_non_std_hl)
	 *     htt.info.is_unicast         (ol_tx_classify)
	 *     htt.info.peer_id            (ol_tx_classify)
	 *     peer                        (ol_tx_classify)
	 *     if (is_unicast) {
	 *         htt.info.ethertype      (ol_tx_classify)
	 *         htt.info.l3_hdr_offset  (ol_tx_classify)
	 *     }
	 * The following fields need to be filled in by this function:
	 *     if (!is_unicast) {
	 *         htt.info.ethertype
	 *         htt.info.l3_hdr_offset
	 *     }
	 *     htt.action.band (NOT CURRENTLY USED)
	 *     htt.action.do_encrypt
	 *     htt.action.do_tx_complete
	 * The following fields are not needed for data frames, and can
	 * be left uninitialized:
	 *     htt.info.frame_subtype
	 */

	if (!msdu_info->htt.info.is_unicast) {
		int l2_hdr_size;
		A_UINT16 ethertype;

		if (msdu_info->htt.info.l2_hdr_type == htt_pkt_type_ethernet) {
			struct ethernet_hdr_t *eh;

			eh = (struct ethernet_hdr_t *)datap;
			l2_hdr_size = sizeof(*eh);
			ethertype = (eh->ethertype[0] << 8) | eh->ethertype[1];

			if (ethertype == ETHERTYPE_VLAN) {
				struct ethernet_vlan_hdr_t *evh;

				evh = (struct ethernet_vlan_hdr_t *)datap;
				l2_hdr_size = sizeof(*evh);
				ethertype = (evh->ethertype[0] << 8) |
							evh->ethertype[1];
			}

			if (!IS_ETHERTYPE(ethertype)) {
				/* 802.3 header*/
				struct llc_snap_hdr_t *llc =
					(struct llc_snap_hdr_t *)(datap +
							l2_hdr_size);
				ethertype = (llc->ethertype[0] << 8) |
							llc->ethertype[1];
				l2_hdr_size += sizeof(*llc);
			}
			msdu_info->htt.info.l3_hdr_offset = l2_hdr_size;
			msdu_info->htt.info.ethertype = ethertype;
		} else { /* 802.11 */
			struct llc_snap_hdr_t *llc;
			l2_hdr_size = ol_txrx_ieee80211_hdrsize(datap);
			llc = (struct llc_snap_hdr_t *)(datap + l2_hdr_size);
			ethertype = (llc->ethertype[0] << 8) |
							llc->ethertype[1];
			/*
			 * Don't include the LLC/SNAP header in l2_hdr_size,
			 * because l3_hdr_offset is actually supposed to refer
			 * to the header after the 802.3 or 802.11 header,
			 * which could be a LLC/SNAP header rather
			 * than the L3 header.
			 */
		}
		msdu_info->htt.info.l3_hdr_offset = l2_hdr_size;
		msdu_info->htt.info.ethertype = ethertype;
		which_key = txrx_sec_mcast;
	} else {
		which_key = txrx_sec_ucast;
	}
	peer = msdu_info->peer;
	/*
	 * msdu_info->htt.action.do_encrypt is initially set in ol_tx_desc_hl.
	 * Add more check here.
	 */
	msdu_info->htt.action.do_encrypt = (!peer) ? 0 :
		(peer->security[which_key].sec_type == htt_sec_type_none) ? 0 :
		msdu_info->htt.action.do_encrypt;
	/*
	 * For systems that have a frame by frame spec for whether to receive
	 * a tx completion notification, use the tx completion notification
	 * only  for certain management frames, not for data frames.
	 * (In the future, this may be changed slightly, e.g. to request a
	 * tx completion notification for the final EAPOL message sent by a
	 * STA during the key delivery handshake.)
	 */
	msdu_info->htt.action.do_tx_complete = 0;

	return A_OK;
}

A_STATUS
ol_tx_classify_mgmt_extension(
		struct ol_txrx_vdev_t *vdev,
		struct ol_tx_desc_t *tx_desc,
		qdf_nbuf_t tx_msdu,
		struct ol_txrx_msdu_info_t *msdu_info)
{
	struct ieee80211_frame *wh;

	/*
	 * The following msdu_info fields were already filled in by the
	 * ol_tx entry function or the regular ol_tx_classify_mgmt function:
	 *     htt.info.vdev_id          (ol_txrx_mgmt_send)
	 *     htt.info.frame_type       (ol_txrx_mgmt_send)
	 *     htt.info.l2_hdr_type      (ol_txrx_mgmt_send)
	 *     htt.action.do_tx_complete (ol_txrx_mgmt_send)
	 *     htt.info.peer_id          (ol_tx_classify_mgmt)
	 *     htt.info.ext_tid          (ol_tx_classify_mgmt)
	 *     htt.info.is_unicast       (ol_tx_classify_mgmt)
	 *     peer                      (ol_tx_classify_mgmt)
	 * The following fields need to be filled in by this function:
	 *     htt.info.frame_subtype
	 *     htt.info.l3_hdr_offset
	 *     htt.action.band (NOT CURRENTLY USED)
	 * The following fields are not needed for mgmt frames, and can
	 * be left uninitialized:
	 *     htt.info.ethertype
	 *     htt.action.do_encrypt
	 *         (This will be filled in by other SW, which knows whether
	 *         the peer has robust-managment-frames enabled.)
	 */
	wh = (struct ieee80211_frame *)qdf_nbuf_data(tx_msdu);
	msdu_info->htt.info.frame_subtype =
		(wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) >>
		IEEE80211_FC0_SUBTYPE_SHIFT;
	msdu_info->htt.info.l3_hdr_offset = sizeof(struct ieee80211_frame);

	return A_OK;
}

#endif /* defined(CONFIG_HL_SUPPORT) */
