/*
 * Copyright (c) 2011, 2013-2016 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 */

#include <ol_htt_rx_api.h>      /* htt_rx_pn_t, etc. */
#include <ol_ctrl_txrx_api.h>   /* ol_rx_err */

#include <ol_txrx_internal.h>   /* ol_rx_mpdu_list_next */
#include <ol_txrx_types.h>      /* ol_txrx_vdev_t, etc. */
#include <ol_rx_pn.h>           /* our own defs */
#include <ol_rx_fwd.h>          /* ol_rx_fwd_check */
#include <ol_rx.h>              /* ol_rx_deliver */

/* add the MSDUs from this MPDU to the list of good frames */
#define ADD_MPDU_TO_LIST(head, tail, mpdu, mpdu_tail) do {		\
		if (!head) {						\
			head = mpdu;					\
		} else {						\
			qdf_nbuf_set_next(tail, mpdu);			\
		}							\
		tail = mpdu_tail;					\
	} while (0)

int ol_rx_pn_cmp24(union htt_rx_pn_t *new_pn,
		   union htt_rx_pn_t *old_pn, int is_unicast, int opmode)
{
	int rc = ((new_pn->pn24 & 0xffffff) <= (old_pn->pn24 & 0xffffff));
	return rc;
}

int ol_rx_pn_cmp48(union htt_rx_pn_t *new_pn,
		   union htt_rx_pn_t *old_pn, int is_unicast, int opmode)
{
	int rc = ((new_pn->pn48 & 0xffffffffffffULL) <=
		  (old_pn->pn48 & 0xffffffffffffULL));
	return rc;
}

int ol_rx_pn_wapi_cmp(union htt_rx_pn_t *new_pn,
		      union htt_rx_pn_t *old_pn, int is_unicast, int opmode)
{
	int pn_is_replay = 0;

	if (new_pn->pn128[1] == old_pn->pn128[1])
		pn_is_replay = (new_pn->pn128[0] <= old_pn->pn128[0]);
	else
		pn_is_replay = (new_pn->pn128[1] < old_pn->pn128[1]);

	if (is_unicast) {
		if (opmode == wlan_op_mode_ap)
			pn_is_replay |= ((new_pn->pn128[0] & 0x1ULL) != 0);
		else
			pn_is_replay |= ((new_pn->pn128[0] & 0x1ULL) != 1);
	}
	return pn_is_replay;
}

qdf_nbuf_t
ol_rx_pn_check_base(struct ol_txrx_vdev_t *vdev,
		    struct ol_txrx_peer_t *peer,
		    unsigned tid, qdf_nbuf_t msdu_list)
{
	struct ol_txrx_pdev_t *pdev = vdev->pdev;
	union htt_rx_pn_t *last_pn;
	qdf_nbuf_t out_list_head = NULL;
	qdf_nbuf_t out_list_tail = NULL;
	qdf_nbuf_t mpdu;
	int index;              /* unicast vs. multicast */
	int pn_len;
	void *rx_desc;
	int last_pn_valid;

	/* Make sure host pn check is not redundant */
	if ((qdf_atomic_read(&peer->fw_pn_check)) ||
		(vdev->opmode == wlan_op_mode_ibss)) {
		return msdu_list;
	}

	/* First, check whether the PN check applies */
	rx_desc = htt_rx_msdu_desc_retrieve(pdev->htt_pdev, msdu_list);
	qdf_assert(htt_rx_msdu_has_wlan_mcast_flag(pdev->htt_pdev, rx_desc));
	index = htt_rx_msdu_is_wlan_mcast(pdev->htt_pdev, rx_desc) ?
		txrx_sec_mcast : txrx_sec_ucast;
	pn_len = pdev->rx_pn[peer->security[index].sec_type].len;
	if (pn_len == 0)
		return msdu_list;

	last_pn_valid = peer->tids_last_pn_valid[tid];
	last_pn = &peer->tids_last_pn[tid];
	mpdu = msdu_list;
	while (mpdu) {
		qdf_nbuf_t mpdu_tail, next_mpdu;
		union htt_rx_pn_t new_pn;
		int pn_is_replay = 0;

		rx_desc = htt_rx_msdu_desc_retrieve(pdev->htt_pdev, mpdu);

		/*
		 * Find the last MSDU within this MPDU, and
		 * the find the first MSDU within the next MPDU.
		 */
		ol_rx_mpdu_list_next(pdev, mpdu, &mpdu_tail, &next_mpdu);

		/* Don't check the PN replay for non-encrypted frames */
		if (!htt_rx_mpdu_is_encrypted(pdev->htt_pdev, rx_desc)) {
			ADD_MPDU_TO_LIST(out_list_head, out_list_tail, mpdu,
					 mpdu_tail);
			mpdu = next_mpdu;
			continue;
		}

		/* retrieve PN from rx descriptor */
		htt_rx_mpdu_desc_pn(pdev->htt_pdev, rx_desc, &new_pn, pn_len);

		/* if there was no prior PN, there's nothing to check */
		if (last_pn_valid) {
			pn_is_replay =
				pdev->rx_pn[peer->security[index].sec_type].
				cmp(&new_pn, last_pn, index == txrx_sec_ucast,
				    vdev->opmode);
		} else {
			last_pn_valid = peer->tids_last_pn_valid[tid] = 1;
		}

		if (pn_is_replay) {
			qdf_nbuf_t msdu;
			static uint32_t last_pncheck_print_time /* = 0 */;
			int log_level;
			uint32_t current_time_ms;

			/*
			 * This MPDU failed the PN check:
			 * 1.  notify the control SW of the PN failure
			 *     (so countermeasures can be taken, if necessary)
			 * 2.  Discard all the MSDUs from this MPDU.
			 */
			msdu = mpdu;
			current_time_ms =
				qdf_system_ticks_to_msecs(qdf_system_ticks());
			if (TXRX_PN_CHECK_FAILURE_PRINT_PERIOD_MS <
			    (current_time_ms - last_pncheck_print_time)) {
				last_pncheck_print_time = current_time_ms;
				log_level = TXRX_PRINT_LEVEL_WARN;
			} else {
				log_level = TXRX_PRINT_LEVEL_INFO2;
			}

			TXRX_PRINT(log_level,
				   "PN check failed - TID %d, peer %p "
				   "(%02x:%02x:%02x:%02x:%02x:%02x) %s\n"
				   "    old PN (u64 x2)= 0x%08llx %08llx (LSBs = %lld)\n"
				   "    new PN (u64 x2)= 0x%08llx %08llx (LSBs = %lld)\n"
				   "    new seq num = %d\n",
				   tid, peer,
				   peer->mac_addr.raw[0], peer->mac_addr.raw[1],
				   peer->mac_addr.raw[2], peer->mac_addr.raw[3],
				   peer->mac_addr.raw[4], peer->mac_addr.raw[5],
				   (index ==
				    txrx_sec_ucast) ? "ucast" : "mcast",
				   last_pn->pn128[1], last_pn->pn128[0],
				   last_pn->pn128[0] & 0xffffffffffffULL,
				   new_pn.pn128[1], new_pn.pn128[0],
				   new_pn.pn128[0] & 0xffffffffffffULL,
				   htt_rx_mpdu_desc_seq_num(pdev->htt_pdev,
							    rx_desc));
#if defined(ENABLE_RX_PN_TRACE)
			ol_rx_pn_trace_display(pdev, 1);
#endif /* ENABLE_RX_PN_TRACE */
			ol_rx_err(pdev->ctrl_pdev,
				  vdev->vdev_id, peer->mac_addr.raw, tid,
				  htt_rx_mpdu_desc_tsf32(pdev->htt_pdev,
							 rx_desc), OL_RX_ERR_PN,
				  mpdu, NULL, 0);
			/* free all MSDUs within this MPDU */
			do {
				qdf_nbuf_t next_msdu;
				OL_RX_ERR_STATISTICS_1(pdev, vdev, peer,
						       rx_desc, OL_RX_ERR_PN);
				next_msdu = qdf_nbuf_next(msdu);
				htt_rx_desc_frame_free(pdev->htt_pdev, msdu);
				if (msdu == mpdu_tail)
					break;
				else
					msdu = next_msdu;
			} while (1);
		} else {
			ADD_MPDU_TO_LIST(out_list_head, out_list_tail, mpdu,
					 mpdu_tail);
			/*
			 * Remember the new PN.
			 * For simplicity, just do 2 64-bit word copies to
			 * cover the worst case (WAPI), regardless of the length
			 * of the PN.
			 * This is more efficient than doing a conditional
			 * branch to copy only the relevant portion.
			 */
			last_pn->pn128[0] = new_pn.pn128[0];
			last_pn->pn128[1] = new_pn.pn128[1];
			OL_RX_PN_TRACE_ADD(pdev, peer, tid, rx_desc);
		}

		mpdu = next_mpdu;
	}
	/* make sure the list is null-terminated */
	if (out_list_tail)
		qdf_nbuf_set_next(out_list_tail, NULL);

	return out_list_head;
}

void
ol_rx_pn_check(struct ol_txrx_vdev_t *vdev,
	       struct ol_txrx_peer_t *peer, unsigned tid, qdf_nbuf_t msdu_list)
{
	msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list);
	ol_rx_fwd_check(vdev, peer, tid, msdu_list);
}

void
ol_rx_pn_check_only(struct ol_txrx_vdev_t *vdev,
		    struct ol_txrx_peer_t *peer,
		    unsigned tid, qdf_nbuf_t msdu_list)
{
	msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list);
	ol_rx_deliver(vdev, peer, tid, msdu_list);
}

#if defined(ENABLE_RX_PN_TRACE)

A_STATUS ol_rx_pn_trace_attach(ol_txrx_pdev_handle pdev)
{
	int num_elems;

	num_elems = 1 << TXRX_RX_PN_TRACE_SIZE_LOG2;
	pdev->rx_pn_trace.idx = 0;
	pdev->rx_pn_trace.cnt = 0;
	pdev->rx_pn_trace.mask = num_elems - 1;
	pdev->rx_pn_trace.data =
		qdf_mem_malloc(sizeof(*pdev->rx_pn_trace.data) * num_elems);
	if (!pdev->rx_pn_trace.data)
		return A_NO_MEMORY;
	return A_OK;
}

void ol_rx_pn_trace_detach(ol_txrx_pdev_handle pdev)
{
	qdf_mem_free(pdev->rx_pn_trace.data);
}

void
ol_rx_pn_trace_add(struct ol_txrx_pdev_t *pdev,
		   struct ol_txrx_peer_t *peer, uint16_t tid, void *rx_desc)
{
	uint32_t idx = pdev->rx_pn_trace.idx;
	union htt_rx_pn_t pn;
	uint32_t pn32;
	uint16_t seq_num;
	uint8_t unicast;

	htt_rx_mpdu_desc_pn(pdev->htt_pdev, rx_desc, &pn, 48);
	pn32 = pn.pn48 & 0xffffffff;
	seq_num = htt_rx_mpdu_desc_seq_num(pdev->htt_pdev, rx_desc);
	unicast = !htt_rx_msdu_is_wlan_mcast(pdev->htt_pdev, rx_desc);

	pdev->rx_pn_trace.data[idx].peer = peer;
	pdev->rx_pn_trace.data[idx].tid = tid;
	pdev->rx_pn_trace.data[idx].seq_num = seq_num;
	pdev->rx_pn_trace.data[idx].unicast = unicast;
	pdev->rx_pn_trace.data[idx].pn32 = pn32;
	pdev->rx_pn_trace.cnt++;
	idx++;
	pdev->rx_pn_trace.idx = idx & pdev->rx_pn_trace.mask;
}

void ol_rx_pn_trace_display(ol_txrx_pdev_handle pdev, int just_once)
{
	static int print_count /* = 0 */;
	uint32_t i, start, end;
	uint64_t cnt;
	int elems;
	int limit = 0;          /* move this to the arg list? */

	if (print_count != 0 && just_once)
		return;

	print_count++;

	end = pdev->rx_pn_trace.idx;
	if (pdev->rx_pn_trace.cnt <= pdev->rx_pn_trace.mask) {
		/* trace log has not yet wrapped around - start at the top */
		start = 0;
		cnt = 0;
	} else {
		start = end;
		cnt = pdev->rx_pn_trace.cnt - (pdev->rx_pn_trace.mask + 1);
	}
	elems = (end - 1 - start) & pdev->rx_pn_trace.mask;
	if (limit > 0 && elems > limit) {
		int delta;
		delta = elems - limit;
		start += delta;
		start &= pdev->rx_pn_trace.mask;
		cnt += delta;
	}

	i = start;
	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
		  "                                 seq     PN");
	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
		  "   count  idx    peer   tid uni  num    LSBs");
	do {
		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
			  "  %6lld %4d  %p %2d   %d %4d %8d",
			  cnt, i,
			  pdev->rx_pn_trace.data[i].peer,
			  pdev->rx_pn_trace.data[i].tid,
			  pdev->rx_pn_trace.data[i].unicast,
			  pdev->rx_pn_trace.data[i].seq_num,
			  pdev->rx_pn_trace.data[i].pn32);
		cnt++;
		i++;
		i &= pdev->rx_pn_trace.mask;
	} while (i != end);
}
#endif /* ENABLE_RX_PN_TRACE */
