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

/**
 * DOC: wlan_hdd_tx_rx.c
 *
 * Linux HDD Tx/RX APIs
 */

#include <wlan_hdd_tx_rx.h>
#include <wlan_hdd_softap_tx_rx.h>
#include <wlan_hdd_napi.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <cds_sched.h>

#include <wlan_hdd_p2p.h>
#include <linux/wireless.h>
#include <net/cfg80211.h>
#include <net/ieee80211_radiotap.h>
#include "sap_api.h"
#include "wlan_hdd_wmm.h"

#ifdef FEATURE_WLAN_TDLS
#include "wlan_hdd_tdls.h"
#endif
#include <wlan_hdd_ipa.h>

#include "wlan_hdd_ocb.h"

#include "wlan_hdd_lro.h"

#ifdef FEATURE_WLAN_DIAG_SUPPORT
#define HDD_EAPOL_ETHER_TYPE             (0x888E)
#define HDD_EAPOL_ETHER_TYPE_OFFSET      (12)
#define HDD_EAPOL_PACKET_TYPE_OFFSET     (15)
#define HDD_EAPOL_KEY_INFO_OFFSET        (19)
#define HDD_EAPOL_DEST_MAC_OFFSET        (0)
#define HDD_EAPOL_SRC_MAC_OFFSET         (6)
#endif /* FEATURE_WLAN_DIAG_SUPPORT */

const uint8_t hdd_wmm_ac_to_highest_up[] = {
	SME_QOS_WMM_UP_RESV,
	SME_QOS_WMM_UP_EE,
	SME_QOS_WMM_UP_VI,
	SME_QOS_WMM_UP_NC
};

/* Mapping Linux AC interpretation to SME AC. */
const uint8_t hdd_qdisc_ac_to_tl_ac[] = {
	SME_AC_VO,
	SME_AC_VI,
	SME_AC_BE,
	SME_AC_BK,
};

#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
/**
 * hdd_tx_resume_timer_expired_handler() - TX Q resume timer handler
 * @adapter_context: pointer to vdev adapter
 *
 * If Blocked OS Q is not resumed during timeout period, to prevent
 * permanent stall, resume OS Q forcefully.
 *
 * Return: None
 */
void hdd_tx_resume_timer_expired_handler(void *adapter_context)
{
	hdd_adapter_t *pAdapter = (hdd_adapter_t *) adapter_context;

	if (!pAdapter) {
		/* INVALID ARG */
		return;
	}

	hddLog(LOG1, FL("Enabling queues"));
	wlan_hdd_netif_queue_control(pAdapter, WLAN_WAKE_ALL_NETIF_QUEUE,
				   WLAN_CONTROL_PATH);
	return;
}

/**
 * hdd_tx_resume_cb() - Resume OS TX Q.
 * @adapter_context: pointer to vdev apdapter
 * @tx_resume: TX Q resume trigger
 *
 * Q was stopped due to WLAN TX path low resource condition
 *
 * Return: None
 */
void hdd_tx_resume_cb(void *adapter_context, bool tx_resume)
{
	hdd_adapter_t *pAdapter = (hdd_adapter_t *) adapter_context;
	hdd_station_ctx_t *hdd_sta_ctx = NULL;

	if (!pAdapter) {
		/* INVALID ARG */
		return;
	}

	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);

	/* Resume TX  */
	if (true == tx_resume) {
		if (CDF_TIMER_STATE_STOPPED !=
		    cdf_mc_timer_get_current_state(&pAdapter->
						   tx_flow_control_timer)) {
			cdf_mc_timer_stop(&pAdapter->tx_flow_control_timer);
		}
		if (cdf_unlikely(hdd_sta_ctx->hdd_ReassocScenario)) {
			hddLog(LOGW,
			       FL("flow control, tx queues un-pause avoided as we are in REASSOCIATING state"));
			       return;
		}
		hddLog(LOG1, FL("Enabling queues"));
		wlan_hdd_netif_queue_control(pAdapter,
					 WLAN_WAKE_ALL_NETIF_QUEUE,
					 WLAN_DATA_FLOW_CONTROL);
	}
#if defined(CONFIG_PER_VDEV_TX_DESC_POOL)
	else if (false == tx_resume) {      /* Pause TX  */
		hddLog(LOG1, FL("Disabling queues"));
		wlan_hdd_netif_queue_control(pAdapter,
					WLAN_STOP_ALL_NETIF_QUEUE,
					WLAN_DATA_FLOW_CONTROL);
		if (CDF_TIMER_STATE_STOPPED ==
		    cdf_mc_timer_get_current_state(&pAdapter->
						   tx_flow_control_timer)) {
			CDF_STATUS status;
			status =
				cdf_mc_timer_start(&pAdapter->tx_flow_control_timer,
						   WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
			if (!CDF_IS_STATUS_SUCCESS(status))
				CDF_TRACE(CDF_MODULE_ID_HDD,
					  CDF_TRACE_LEVEL_ERROR,
					  "%s: Failed to start tx_flow_control_timer",
					  __func__);
			else
				pAdapter->hdd_stats.hddTxRxStats.txflow_timer_cnt++;
		}
		pAdapter->hdd_stats.hddTxRxStats.txflow_pause_cnt++;
		pAdapter->hdd_stats.hddTxRxStats.is_txflow_paused = true;
	}
#endif

	return;
}

/**
 * hdd_register_tx_flow_control() - Register TX Flow control
 * @adapter: adapter handle
 * @timer_callback: timer callback
 * @flow_control_fp: txrx flow control
 *
 * Return: none
 */
void hdd_register_tx_flow_control(hdd_adapter_t *adapter,
		cdf_mc_timer_callback_t timer_callback,
		ol_txrx_tx_flow_control_fp flow_control_fp)
{
	if (adapter->tx_flow_timer_initialized == false) {
		cdf_mc_timer_init(&adapter->tx_flow_control_timer,
			  CDF_TIMER_TYPE_SW,
			  timer_callback,
			  adapter);
		adapter->tx_flow_timer_initialized = true;
	}
	ol_txrx_register_tx_flow_control(adapter->sessionId,
					flow_control_fp,
					adapter);

}

/**
 * hdd_deregister_tx_flow_control() - Deregister TX Flow control
 * @adapter: adapter handle
 *
 * Return: none
 */
void hdd_deregister_tx_flow_control(hdd_adapter_t *adapter)
{
	ol_txrx_deregister_tx_flow_control_cb(adapter->sessionId);
	if (adapter->tx_flow_timer_initialized == true) {
		cdf_mc_timer_stop(&adapter->tx_flow_control_timer);
		cdf_mc_timer_destroy(&adapter->tx_flow_control_timer);
		adapter->tx_flow_timer_initialized = false;
	}
}

/**
 * hdd_get_tx_resource() - check tx resources and take action
 * @adapter: adapter handle
 * @STAId: station id
 * @timer_value: timer value
 *
 * Return: none
 */
void hdd_get_tx_resource(hdd_adapter_t *adapter,
			uint8_t STAId, uint16_t timer_value)
{
	if (false ==
	    ol_txrx_get_tx_resource(STAId,
				   adapter->tx_flow_low_watermark,
				   adapter->tx_flow_high_watermark_offset)) {
		hdd_info("Disabling queues lwm %d hwm offset %d",
			adapter->tx_flow_low_watermark,
			adapter->tx_flow_high_watermark_offset);
		wlan_hdd_netif_queue_control(adapter, WLAN_STOP_ALL_NETIF_QUEUE,
					     WLAN_DATA_FLOW_CONTROL);
		if ((adapter->tx_flow_timer_initialized == true) &&
		    (CDF_TIMER_STATE_STOPPED ==
		    cdf_mc_timer_get_current_state(&adapter->
						    tx_flow_control_timer))) {
			cdf_mc_timer_start(&adapter->tx_flow_control_timer,
					   timer_value);
			adapter->hdd_stats.hddTxRxStats.txflow_timer_cnt++;
			adapter->hdd_stats.hddTxRxStats.txflow_pause_cnt++;
			adapter->hdd_stats.hddTxRxStats.is_txflow_paused = true;
		}
	}
}

#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */

/**
 * wlan_hdd_is_eapol() - Function to check if frame is EAPOL or not
 * @skb:    skb data
 *
 * This function checks if the frame is an EAPOL frame or not
 *
 * Return: true (1) if packet is EAPOL
 *
 */
static bool wlan_hdd_is_eapol(struct sk_buff *skb)
{
	uint16_t ether_type;

	if (!skb) {
		hdd_err(FL("skb is NULL"));
		return false;
	}

	ether_type = (uint16_t)(*(uint16_t *)
			(skb->data + HDD_ETHERTYPE_802_1_X_FRAME_OFFSET));

	if (ether_type == CDF_SWAP_U16(HDD_ETHERTYPE_802_1_X))
		return true;

	return false;
}

/**
 * wlan_hdd_is_eapol_or_wai() - Check if frame is EAPOL or WAPI
 * @skb:    skb data
 *
 * This function checks if the frame is EAPOL or WAPI.
 * single routine call will check for both types, thus avoiding
 * data path performance penalty.
 *
 * Return: true (1) if packet is EAPOL or WAPI
 *
 */
static bool wlan_hdd_is_eapol_or_wai(struct sk_buff *skb)
{
	uint16_t ether_type;

	if (!skb) {
		hdd_err(FL("skb is NULL"));
		return false;
	}

	ether_type = (uint16_t)(*(uint16_t *)
			(skb->data + HDD_ETHERTYPE_802_1_X_FRAME_OFFSET));

	if (ether_type == CDF_SWAP_U16(HDD_ETHERTYPE_802_1_X) ||
	    ether_type == CDF_SWAP_U16(HDD_ETHERTYPE_WAI))
		return true;

	/* No error msg handled since this will happen often */
	return false;
}

/**
 * hdd_hard_start_xmit() - Transmit a frame
 * @skb: pointer to OS packet (sk_buff)
 * @dev: pointer to network device
 *
 * Function registered with the Linux OS for transmitting
 * packets. This version of the function directly passes
 * the packet to Transport Layer.
 *
 * Return: Always returns NETDEV_TX_OK
 */
int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
	CDF_STATUS status;
	sme_ac_enum_type ac;
	sme_QosWmmUpType up;
	hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
	bool granted;
	uint8_t STAId = WLAN_MAX_STA_COUNT;
	hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
	uint8_t proto_type = 0;
#ifdef QCA_PKT_PROTO_TRACE
	hdd_context_t *hddCtxt = WLAN_HDD_GET_CTX(pAdapter);
#endif /* QCA_PKT_PROTO_TRACE */

#ifdef QCA_WIFI_FTM
	if (hdd_get_conparam() == CDF_FTM_MODE) {
		kfree_skb(skb);
		return NETDEV_TX_OK;
	}
#endif

	++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;

	if (WLAN_HDD_IBSS == pAdapter->device_mode) {
		struct cdf_mac_addr *pDestMacAddress =
					(struct cdf_mac_addr *) skb->data;

		if (CDF_STATUS_SUCCESS !=
				hdd_ibss_get_sta_id(&pAdapter->sessionCtx.station,
					pDestMacAddress, &STAId))
			STAId = HDD_WLAN_INVALID_STA_ID;

		if ((STAId == HDD_WLAN_INVALID_STA_ID) &&
		    (cdf_is_macaddr_broadcast(pDestMacAddress) ||
		     cdf_is_macaddr_group(pDestMacAddress))) {
			STAId = IBSS_BROADCAST_STAID;
			CDF_TRACE(CDF_MODULE_ID_HDD_DATA,
				  CDF_TRACE_LEVEL_INFO_LOW, "%s: BC/MC packet",
				  __func__);
		} else if (STAId == HDD_WLAN_INVALID_STA_ID) {
			CDF_TRACE(CDF_MODULE_ID_HDD_DATA, CDF_TRACE_LEVEL_WARN,
				  "%s: Received Unicast frame with invalid staID",
				  __func__);
			++pAdapter->stats.tx_dropped;
			++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
			kfree_skb(skb);
			return NETDEV_TX_OK;
		}
	} else {
		STAId = pHddStaCtx->conn_info.staId[0];
	}


	hdd_get_tx_resource(pAdapter, STAId,
				WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);

	/* Get TL AC corresponding to Qdisc queue index/AC. */
	ac = hdd_qdisc_ac_to_tl_ac[skb->queue_mapping];

	if (!(NBUF_OWNER_ID(skb) == IPA_NBUF_OWNER_ID)) {
		/* Check if the buffer has enough header room */
		skb = skb_unshare(skb, GFP_ATOMIC);
		if (!skb)
			goto drop_pkt;

		if (skb_headroom(skb) < dev->hard_header_len) {
			struct sk_buff *tmp;
			tmp = skb;
			skb = skb_realloc_headroom(tmp, dev->hard_header_len);
			dev_kfree_skb(tmp);
			if (!skb)
				goto drop_pkt;
		}
	}

	/* user priority from IP header, which is already extracted and set from
	 * select_queue call back function
	 */
	up = skb->priority;

	++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
#ifdef HDD_WMM_DEBUG
	CDF_TRACE(CDF_MODULE_ID_HDD_DATA, CDF_TRACE_LEVEL_FATAL,
		  "%s: Classified as ac %d up %d", __func__, ac, up);
#endif /* HDD_WMM_DEBUG */

	if (HDD_PSB_CHANGED == pAdapter->psbChanged) {
		/* Function which will determine acquire admittance for a
		 * WMM AC is required or not based on psb configuration done
		 * in the framework
		 */
		hdd_wmm_acquire_access_required(pAdapter, ac);
	}
	/*
	 * Make sure we already have access to this access category
	 * or it is EAPOL or WAPI frame during initial authentication which
	 * can have artifically boosted higher qos priority.
	 */

	if (((pAdapter->psbChanged & (1 << ac)) &&
		likely(pAdapter->hddWmmStatus.wmmAcStatus[ac].
			wmmAcAccessAllowed)) ||
		((pHddStaCtx->conn_info.uIsAuthenticated == false) &&
		 wlan_hdd_is_eapol_or_wai(skb))) {
		granted = true;
	} else {
		status = hdd_wmm_acquire_access(pAdapter, ac, &granted);
		pAdapter->psbChanged |= (1 << ac);
	}

	if (!granted) {
		bool isDefaultAc = false;
		/* ADDTS request for this AC is sent, for now
		 * send this packet through next avaiable lower
		 * Access category until ADDTS negotiation completes.
		 */
		while (!likely
			       (pAdapter->hddWmmStatus.wmmAcStatus[ac].
			       wmmAcAccessAllowed)) {
			switch (ac) {
			case SME_AC_VO:
				ac = SME_AC_VI;
				up = SME_QOS_WMM_UP_VI;
				break;
			case SME_AC_VI:
				ac = SME_AC_BE;
				up = SME_QOS_WMM_UP_BE;
				break;
			case SME_AC_BE:
				ac = SME_AC_BK;
				up = SME_QOS_WMM_UP_BK;
				break;
			default:
				ac = SME_AC_BK;
				up = SME_QOS_WMM_UP_BK;
				isDefaultAc = true;
				break;
			}
			if (isDefaultAc)
				break;
		}
		skb->priority = up;
		skb->queue_mapping = hdd_linux_up_to_ac_map[up];
	}

	wlan_hdd_log_eapol(skb,
			   WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED);

#ifdef QCA_PKT_PROTO_TRACE
	if ((hddCtxt->config->gEnableDebugLog & CDS_PKT_TRAC_TYPE_EAPOL) ||
	    (hddCtxt->config->gEnableDebugLog & CDS_PKT_TRAC_TYPE_DHCP)) {
		proto_type = cds_pkt_get_proto_type(skb,
						    hddCtxt->config->
						    gEnableDebugLog, 0);
		if (CDS_PKT_TRAC_TYPE_EAPOL & proto_type) {
			cds_pkt_trace_buf_update("ST:T:EPL");
		} else if (CDS_PKT_TRAC_TYPE_DHCP & proto_type) {
			cds_pkt_trace_buf_update("ST:T:DHC");
		}
	}
#endif /* QCA_PKT_PROTO_TRACE */

	pAdapter->stats.tx_bytes += skb->len;
	++pAdapter->stats.tx_packets;

	/* Zero out skb's context buffer for the driver to use */
	cdf_mem_set(skb->cb, sizeof(skb->cb), 0);
	NBUF_SET_PACKET_TRACK(skb, NBUF_TX_PKT_DATA_TRACK);
	NBUF_UPDATE_TX_PKT_COUNT(skb, NBUF_TX_PKT_HDD);

	cdf_dp_trace_set_track(skb);
	DPTRACE(cdf_dp_trace(skb, CDF_DP_TRACE_HDD_PACKET_PTR_RECORD,
				(uint8_t *)skb->data, sizeof(skb->data)));
	DPTRACE(cdf_dp_trace(skb, CDF_DP_TRACE_HDD_PACKET_RECORD,
				(uint8_t *)skb->data, cdf_nbuf_len(skb)));
	if (cdf_nbuf_len(skb) > CDF_DP_TRACE_RECORD_SIZE)
		DPTRACE(cdf_dp_trace(skb, CDF_DP_TRACE_HDD_PACKET_RECORD,
				(uint8_t *)&skb->data[CDF_DP_TRACE_RECORD_SIZE],
				(cdf_nbuf_len(skb)-CDF_DP_TRACE_RECORD_SIZE)));

	if (ol_tx_send_data_frame(STAId, (cdf_nbuf_t) skb,
							  proto_type) != NULL) {
		CDF_TRACE(CDF_MODULE_ID_HDD_DATA, CDF_TRACE_LEVEL_WARN,
			  "%s: Failed to send packet to txrx for staid:%d",
			  __func__, STAId);
		goto drop_pkt;
	}
	dev->trans_start = jiffies;

	return NETDEV_TX_OK;

drop_pkt:

	DPTRACE(cdf_dp_trace(skb, CDF_DP_TRACE_DROP_PACKET_RECORD,
				(uint8_t *)skb->data, cdf_nbuf_len(skb)));
	if (cdf_nbuf_len(skb) > CDF_DP_TRACE_RECORD_SIZE)
		DPTRACE(cdf_dp_trace(skb, CDF_DP_TRACE_DROP_PACKET_RECORD,
				(uint8_t *)&skb->data[CDF_DP_TRACE_RECORD_SIZE],
				(cdf_nbuf_len(skb)-CDF_DP_TRACE_RECORD_SIZE)));

	++pAdapter->stats.tx_dropped;
	++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
	++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
	kfree_skb(skb);
	return NETDEV_TX_OK;
}

/**
 * hdd_ibss_get_sta_id() - Get the StationID using the Peer Mac address
 * @pHddStaCtx: pointer to HDD Station Context
 * @pMacAddress: pointer to Peer Mac address
 * @staID: pointer to returned Station Index
 *
 * Return: CDF_STATUS_SUCCESS/CDF_STATUS_E_FAILURE
 */

CDF_STATUS hdd_ibss_get_sta_id(hdd_station_ctx_t *pHddStaCtx,
			       struct cdf_mac_addr *pMacAddress, uint8_t *staId)
{
	uint8_t idx;

	for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
		if (cdf_mem_compare(&pHddStaCtx->conn_info.peerMacAddress[idx],
				    pMacAddress, CDF_MAC_ADDR_SIZE)) {
			*staId = pHddStaCtx->conn_info.staId[idx];
			return CDF_STATUS_SUCCESS;
		}
	}

	return CDF_STATUS_E_FAILURE;
}

/**
 * __hdd_tx_timeout() - TX timeout handler
 * @dev: pointer to network device
 *
 * This function is registered as a netdev ndo_tx_timeout method, and
 * is invoked by the kernel if the driver takes too long to transmit a
 * frame.
 *
 * Return: None
 */
static void __hdd_tx_timeout(struct net_device *dev)
{
	struct netdev_queue *txq;
	int i = 0;

	CDF_TRACE(CDF_MODULE_ID_HDD_DATA, CDF_TRACE_LEVEL_ERROR,
		  "%s: Transmission timeout occurred jiffies %lu trans_start %lu",
		  __func__, jiffies, dev->trans_start);
	DPTRACE(cdf_dp_trace(NULL, CDF_DP_TRACE_HDD_TX_TIMEOUT,
				NULL, 0));

	/* Getting here implies we disabled the TX queues for too
	 * long. Queues are disabled either because of disassociation
	 * or low resource scenarios. In case of disassociation it is
	 * ok to ignore this. But if associated, we have do possible
	 * recovery here
	 */

	for (i = 0; i < NUM_TX_QUEUES; i++) {
		txq = netdev_get_tx_queue(dev, i);
		CDF_TRACE(CDF_MODULE_ID_HDD_DATA, CDF_TRACE_LEVEL_INFO,
			  "Queue%d status: %d txq->trans_start %lu",
			   i, netif_tx_queue_stopped(txq), txq->trans_start);
	}

	CDF_TRACE(CDF_MODULE_ID_HDD_DATA, CDF_TRACE_LEVEL_INFO,
		  "carrier state: %d", netif_carrier_ok(dev));
}

/**
 * hdd_tx_timeout() - Wrapper function to protect __hdd_tx_timeout from SSR
 * @dev: pointer to net_device structure
 *
 * Function called by OS if there is any timeout during transmission.
 * Since HDD simply enqueues packet and returns control to OS right away,
 * this would never be invoked
 *
 * Return: none
 */
void hdd_tx_timeout(struct net_device *dev)
{
	cds_ssr_protect(__func__);
	__hdd_tx_timeout(dev);
	cds_ssr_unprotect(__func__);
}

/**
 * @hdd_init_tx_rx() - Initialize Tx/RX module
 * @pAdapter: pointer to adapter context
 *
 * Return: CDF_STATUS_E_FAILURE if any errors encountered,
 *	   CDF_STATUS_SUCCESS otherwise
 */
CDF_STATUS hdd_init_tx_rx(hdd_adapter_t *pAdapter)
{
	CDF_STATUS status = CDF_STATUS_SUCCESS;

	if (NULL == pAdapter) {
		CDF_TRACE(CDF_MODULE_ID_HDD_DATA, CDF_TRACE_LEVEL_ERROR,
			  FL("pAdapter is NULL"));
		CDF_ASSERT(0);
		return CDF_STATUS_E_FAILURE;
	}

	return status;
}

/**
 * @hdd_deinit_tx_rx() - Deinitialize Tx/RX module
 * @pAdapter: pointer to adapter context
 *
 * Return: CDF_STATUS_E_FAILURE if any errors encountered,
 *	   CDF_STATUS_SUCCESS otherwise
 */
CDF_STATUS hdd_deinit_tx_rx(hdd_adapter_t *pAdapter)
{
	CDF_STATUS status = CDF_STATUS_SUCCESS;

	if (NULL == pAdapter) {
		CDF_TRACE(CDF_MODULE_ID_HDD_DATA, CDF_TRACE_LEVEL_ERROR,
			  FL("pAdapter is NULL"));
		CDF_ASSERT(0);
		return CDF_STATUS_E_FAILURE;
	}

	return status;
}

/**
 * hdd_rx_packet_cbk() - Receive packet handler
 * @cds_context: pointer to CDS context
 * @rxBuf: pointer to rx cdf_nbuf
 * @staId: Station Id
 *
 * Receive callback registered with TL.  TL will call this to notify
 * the HDD when one or more packets were received for a registered
 * STA.
 *
 * Return: CDF_STATUS_E_FAILURE if any errors encountered,
 *	   CDF_STATUS_SUCCESS otherwise
 */
CDF_STATUS hdd_rx_packet_cbk(void *cds_context, cdf_nbuf_t rxBuf, uint8_t staId)
{
	hdd_adapter_t *pAdapter = NULL;
	hdd_context_t *pHddCtx = NULL;
	int rxstat;
	struct sk_buff *skb = NULL;
#ifdef QCA_PKT_PROTO_TRACE
	uint8_t proto_type;
#endif /* QCA_PKT_PROTO_TRACE */
	hdd_station_ctx_t *pHddStaCtx = NULL;
	unsigned int cpu_index;

	/* Sanity check on inputs */
	if ((NULL == cds_context) || (NULL == rxBuf)) {
		CDF_TRACE(CDF_MODULE_ID_HDD_DATA, CDF_TRACE_LEVEL_ERROR,
			  "%s: Null params being passed", __func__);
		return CDF_STATUS_E_FAILURE;
	}

	pHddCtx = cds_get_context(CDF_MODULE_ID_HDD);
	if (NULL == pHddCtx) {
		CDF_TRACE(CDF_MODULE_ID_HDD_DATA, CDF_TRACE_LEVEL_ERROR,
			  "%s: HDD context is Null", __func__);
		return CDF_STATUS_E_FAILURE;
	}

	pAdapter = pHddCtx->sta_to_adapter[staId];
	if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) {
		hddLog(LOGE,
			FL("invalid adapter %p or adapter has invalid magic"),
			pAdapter);
		return CDF_STATUS_E_FAILURE;
	}
	cpu_index = wlan_hdd_get_cpu();

	skb = (struct sk_buff *)rxBuf;

	if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) {
		CDF_TRACE(CDF_MODULE_ID_HDD_DATA, CDF_TRACE_LEVEL_FATAL,
			  "Magic cookie(%x) for adapter sanity verification is invalid",
			  pAdapter->magic);
		return CDF_STATUS_E_FAILURE;
	}

	pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
	if ((pHddStaCtx->conn_info.proxyARPService) &&
	    cfg80211_is_gratuitous_arp_unsolicited_na(skb)) {
		++pAdapter->hdd_stats.hddTxRxStats.rxDropped[cpu_index];
		CDF_TRACE(CDF_MODULE_ID_HDD_DATA, CDF_TRACE_LEVEL_INFO,
			  "%s: Dropping HS 2.0 Gratuitous ARP or Unsolicited NA",
			  __func__);
		/* Remove SKB from internal tracking table before submitting
		 * it to stack
		 */
		cdf_nbuf_free(skb);
		return CDF_STATUS_SUCCESS;
	}

	wlan_hdd_log_eapol(skb, WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED);

#ifdef QCA_PKT_PROTO_TRACE
	if ((pHddCtx->config->gEnableDebugLog & CDS_PKT_TRAC_TYPE_EAPOL) ||
	    (pHddCtx->config->gEnableDebugLog & CDS_PKT_TRAC_TYPE_DHCP)) {
		proto_type = cds_pkt_get_proto_type(skb,
						    pHddCtx->config->
						    gEnableDebugLog, 0);
		if (CDS_PKT_TRAC_TYPE_EAPOL & proto_type) {
			cds_pkt_trace_buf_update("ST:R:EPL");
		} else if (CDS_PKT_TRAC_TYPE_DHCP & proto_type) {
			cds_pkt_trace_buf_update("ST:R:DHC");
		}
	}
#endif /* QCA_PKT_PROTO_TRACE */

	skb->dev = pAdapter->dev;
	skb->protocol = eth_type_trans(skb, skb->dev);
	++pAdapter->hdd_stats.hddTxRxStats.rxPackets[cpu_index];
	++pAdapter->stats.rx_packets;
	pAdapter->stats.rx_bytes += skb->len;
#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
	cdf_wake_lock_timeout_acquire(&pHddCtx->rx_wake_lock,
				      HDD_WAKE_LOCK_DURATION,
				      WIFI_POWER_EVENT_WAKELOCK_HOLD_RX);
#endif

	/* Remove SKB from internal tracking table before submitting
	 * it to stack
	 */
	cdf_net_buf_debug_release_skb(rxBuf);

	if (HDD_LRO_NO_RX ==
		 hdd_lro_rx(pHddCtx, pAdapter, skb)) {
		if (hdd_napi_enabled(HDD_NAPI_ANY))
			rxstat = netif_receive_skb(skb);
		else
			rxstat = netif_rx_ni(skb);

		if (NET_RX_SUCCESS == rxstat)
			++pAdapter->hdd_stats.hddTxRxStats.
				 rxDelivered[cpu_index];
		else
			++pAdapter->hdd_stats.hddTxRxStats.
				 rxRefused[cpu_index];

	} else {
		++pAdapter->hdd_stats.hddTxRxStats.
			 rxDelivered[cpu_index];
	}

	pAdapter->dev->last_rx = jiffies;

	return CDF_STATUS_SUCCESS;
}

#ifdef FEATURE_WLAN_DIAG_SUPPORT

/**
 * wlan_hdd_get_eapol_params() - Function to extract EAPOL params
 * @skb:                sbb data
 * @eapol_params:       Pointer to hold the parsed EAPOL params
 * @event_type:         Event type to indicate Tx/Rx
 *
 * This function parses the input skb data and return the EAPOL parameters if
 * the packet is an eapol packet.
 *
 * Return: -EINVAL if the packet is not an EAPOL packet and 0 on success
 *
 */
static int wlan_hdd_get_eapol_params(struct sk_buff *skb,
		struct host_event_wlan_eapol *eapol_params,
		uint8_t event_type)
{
	bool ret;
	uint8_t packet_type;

	ret = wlan_hdd_is_eapol(skb);

	if (!ret)
		return -EINVAL;

	packet_type = (uint8_t)(*(uint8_t *)
			(skb->data + HDD_EAPOL_PACKET_TYPE_OFFSET));

	eapol_params->eapol_packet_type = packet_type;
	eapol_params->eapol_key_info = (uint16_t)(*(uint16_t *)
			(skb->data + HDD_EAPOL_KEY_INFO_OFFSET));
	eapol_params->event_sub_type = event_type;
	eapol_params->eapol_rate = 0;/* As of now, zero */

	cdf_mem_copy(eapol_params->dest_addr,
			(skb->data + HDD_EAPOL_DEST_MAC_OFFSET),
			sizeof(eapol_params->dest_addr));
	cdf_mem_copy(eapol_params->src_addr,
			(skb->data + HDD_EAPOL_SRC_MAC_OFFSET),
			sizeof(eapol_params->src_addr));
	return 0;
}

/**
 * wlan_hdd_event_eapol_log() - Function to log EAPOL events
 * @eapol_params:    Structure containing EAPOL params
 *
 * This function logs the parsed EAPOL params
 *
 * Return: None
 *
 */
static void wlan_hdd_event_eapol_log(struct host_event_wlan_eapol eapol_params)
{
	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct host_event_wlan_eapol);

	wlan_diag_event.event_sub_type = eapol_params.event_sub_type;
	wlan_diag_event.eapol_packet_type = eapol_params.eapol_packet_type;
	wlan_diag_event.eapol_key_info = eapol_params.eapol_key_info;
	wlan_diag_event.eapol_rate = eapol_params.eapol_rate;
	cdf_mem_copy(wlan_diag_event.dest_addr,
			eapol_params.dest_addr,
			sizeof(wlan_diag_event.dest_addr));
	cdf_mem_copy(wlan_diag_event.src_addr,
			eapol_params.src_addr,
			sizeof(wlan_diag_event.src_addr));

	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_EAPOL);
}

/**
 * wlan_hdd_log_eapol() - Logs the EAPOL parameters of a packet
 * @skb:               skb data
 * @event_type:        One of enum wifi_connectivity_events to indicate Tx/Rx
 *
 * This function parses the input skb data to get the EAPOL params and log
 * them to user space, if the packet is EAPOL
 *
 * Return: None
 *
 */
void wlan_hdd_log_eapol(struct sk_buff *skb,
		uint8_t event_type)
{
	int ret;
	struct host_event_wlan_eapol eapol_params;

	ret = wlan_hdd_get_eapol_params(skb, &eapol_params, event_type);
	if (!ret)
		wlan_hdd_event_eapol_log(eapol_params);
}
#endif /* FEATURE_WLAN_DIAG_SUPPORT */

/**
 * hdd_reason_type_to_string() - return string conversion of reason type
 * @reason: reason type
 *
 * This utility function helps log string conversion of reason type.
 *
 * Return: string conversion of device mode, if match found;
 *        "Unknown" otherwise.
 */
const char *hdd_reason_type_to_string(enum netif_reason_type reason)
{
	switch (reason) {
	CASE_RETURN_STRING(WLAN_CONTROL_PATH);
	CASE_RETURN_STRING(WLAN_DATA_FLOW_CONTROL);
	CASE_RETURN_STRING(WLAN_FW_PAUSE);
	CASE_RETURN_STRING(WLAN_TX_ABORT);
	CASE_RETURN_STRING(WLAN_VDEV_STOP);
	CASE_RETURN_STRING(WLAN_PEER_UNAUTHORISED);
	CASE_RETURN_STRING(WLAN_THERMAL_MITIGATION);
	default:
		return "Unknown";
	}
}

/**
 * hdd_action_type_to_string() - return string conversion of action type
 * @action: action type
 *
 * This utility function helps log string conversion of action_type.
 *
 * Return: string conversion of device mode, if match found;
 *        "Unknown" otherwise.
 */
const char *hdd_action_type_to_string(enum netif_action_type action)
{

	switch (action) {
	CASE_RETURN_STRING(WLAN_STOP_ALL_NETIF_QUEUE);
	CASE_RETURN_STRING(WLAN_START_ALL_NETIF_QUEUE);
	CASE_RETURN_STRING(WLAN_WAKE_ALL_NETIF_QUEUE);
	CASE_RETURN_STRING(WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER);
	CASE_RETURN_STRING(WLAN_START_ALL_NETIF_QUEUE_N_CARRIER);
	CASE_RETURN_STRING(WLAN_NETIF_TX_DISABLE);
	CASE_RETURN_STRING(WLAN_NETIF_TX_DISABLE_N_CARRIER);
	CASE_RETURN_STRING(WLAN_NETIF_CARRIER_ON);
	CASE_RETURN_STRING(WLAN_NETIF_CARRIER_OFF);
	default:
		return "Unknown";
	}
}

/**
 * wlan_hdd_update_queue_oper_stats - update queue operation statistics
 * @adapter: adapter handle
 * @action: action type
 * @reason: reason type
 */
static void wlan_hdd_update_queue_oper_stats(hdd_adapter_t *adapter,
	enum netif_action_type action, enum netif_reason_type reason)
{
	switch (action) {
	case WLAN_STOP_ALL_NETIF_QUEUE:
	case WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER:
	case WLAN_NETIF_TX_DISABLE:
	case WLAN_NETIF_TX_DISABLE_N_CARRIER:
		adapter->queue_oper_stats[reason].pause_count++;
		break;
	case WLAN_START_ALL_NETIF_QUEUE:
	case WLAN_WAKE_ALL_NETIF_QUEUE:
	case WLAN_START_ALL_NETIF_QUEUE_N_CARRIER:
		adapter->queue_oper_stats[reason].unpause_count++;
		break;
	default:
		break;
	}

	return;
}

/**
 * wlan_hdd_netif_queue_control() - Use for netif_queue related actions
 * @adapter: adapter handle
 * @action: action type
 * @reason: reason type
 *
 * This is single function which is used for netif_queue related
 * actions like start/stop of network queues and on/off carrier
 * option.
 *
 * Return: None
 */
void wlan_hdd_netif_queue_control(hdd_adapter_t *adapter,
	enum netif_action_type action, enum netif_reason_type reason)
{

	if ((!adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) ||
		 (!adapter->dev)) {
		hdd_err("adapter is invalid");
		return;
	}

	switch (action) {

	case WLAN_NETIF_CARRIER_ON:
		netif_carrier_on(adapter->dev);
		break;

	case WLAN_NETIF_CARRIER_OFF:
		netif_carrier_off(adapter->dev);
		break;

	case WLAN_STOP_ALL_NETIF_QUEUE:
		spin_lock_bh(&adapter->pause_map_lock);
		if (!adapter->pause_map)
			netif_tx_stop_all_queues(adapter->dev);
		adapter->pause_map |= (1 << reason);
		spin_unlock_bh(&adapter->pause_map_lock);
		break;

	case WLAN_START_ALL_NETIF_QUEUE:
		spin_lock_bh(&adapter->pause_map_lock);
		adapter->pause_map &= ~(1 << reason);
		if (!adapter->pause_map)
			netif_tx_start_all_queues(adapter->dev);
		spin_unlock_bh(&adapter->pause_map_lock);
		break;

	case WLAN_WAKE_ALL_NETIF_QUEUE:
		spin_lock_bh(&adapter->pause_map_lock);
		adapter->pause_map &= ~(1 << reason);
		if (!adapter->pause_map)
			netif_tx_wake_all_queues(adapter->dev);
		spin_unlock_bh(&adapter->pause_map_lock);
		break;

	case WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER:
		spin_lock_bh(&adapter->pause_map_lock);
		if (!adapter->pause_map)
			netif_tx_stop_all_queues(adapter->dev);
		adapter->pause_map |= (1 << reason);
		netif_carrier_off(adapter->dev);
		spin_unlock_bh(&adapter->pause_map_lock);
		break;

	case WLAN_START_ALL_NETIF_QUEUE_N_CARRIER:
		spin_lock_bh(&adapter->pause_map_lock);
		netif_carrier_on(adapter->dev);
		adapter->pause_map &= ~(1 << reason);
		if (!adapter->pause_map)
			netif_tx_start_all_queues(adapter->dev);
		spin_unlock_bh(&adapter->pause_map_lock);
		break;

	case WLAN_NETIF_TX_DISABLE:
		spin_lock_bh(&adapter->pause_map_lock);
		if (!adapter->pause_map)
			netif_tx_disable(adapter->dev);
		adapter->pause_map |= (1 << reason);
		spin_unlock_bh(&adapter->pause_map_lock);
		break;

	case WLAN_NETIF_TX_DISABLE_N_CARRIER:
		spin_lock_bh(&adapter->pause_map_lock);
		if (!adapter->pause_map)
			netif_tx_disable(adapter->dev);
		adapter->pause_map |= (1 << reason);
		netif_carrier_off(adapter->dev);
		spin_unlock_bh(&adapter->pause_map_lock);
		break;

	default:
		hdd_err("unsupported action %d", action);
	}

	spin_lock_bh(&adapter->pause_map_lock);
	if (adapter->pause_map & (1 << WLAN_PEER_UNAUTHORISED))
		wlan_hdd_process_peer_unauthorised_pause(adapter);
	spin_unlock_bh(&adapter->pause_map_lock);


	wlan_hdd_update_queue_oper_stats(adapter, action, reason);

	adapter->queue_oper_history[adapter->history_index].time =
							cdf_system_ticks();
	adapter->queue_oper_history[adapter->history_index].netif_action =
									action;
	adapter->queue_oper_history[adapter->history_index].netif_reason =
									reason;
	adapter->queue_oper_history[adapter->history_index].pause_map =
							adapter->pause_map;
	if (++adapter->history_index == WLAN_HDD_MAX_HISTORY_ENTRY)
		adapter->history_index = 0;

	return;
}

