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

/**=========================================================================

  \file        vos_packet.c

  \brief       virtual Operating System Services (vOSS) network Packet APIs

   Network Protocol packet/buffer support interfaces

  ========================================================================*/

/* $Header$ */

/*--------------------------------------------------------------------------
  Include Files
  ------------------------------------------------------------------------*/
#include <vos_packet.h>
#include <i_vos_packet.h>
#include <vos_timer.h>
#include <vos_trace.h>
#include <wlan_hdd_main.h>
#include "adf_nbuf.h"
#include "vos_memory.h"
#include "adf_os_mem.h"
#include <linux/rtc.h>

/* Protocol specific packet tracking feature */
#define VOS_PKT_TRAC_ETH_TYPE_OFFSET 12
#define VOS_PKT_TRAC_IP_OFFSET       14
#define VOS_PKT_TRAC_IP_HEADER_SIZE  20
#define VOS_PKT_TRAC_DHCP_SRV_PORT   67
#define VOS_PKT_TRAC_DHCP_CLI_PORT   68
#define VOS_PKT_TRAC_EAPOL_ETH_TYPE  0x888E
#define VOS_PKT_TRAC_ARP_ETH_TYPE    0x0806
#ifdef QCA_PKT_PROTO_TRACE
#define VOS_PKT_TRAC_MAX_STRING_LEN  40
#define VOS_PKT_TRAC_MAX_TRACE_BUF   50
#define VOS_PKT_TRAC_MAX_STRING_BUF  64

/* protocol Storage Structure */
typedef struct
{
   v_U32_t  order;
   v_TIME_t event_sec_time;
   v_TIME_t event_msec_time;
   char     event_string[VOS_PKT_TRAC_MAX_STRING_LEN];
} vos_pkt_proto_trace_t;

vos_pkt_proto_trace_t   *trace_buffer = NULL;
unsigned int            trace_buffer_order = 0;
unsigned int trace_dump_order = 0;
spinlock_t              trace_buffer_lock;
#endif /* QCA_PKT_PROTO_TRACE */

/**
 * vos_pkt_return_packet  Free the voss Packet
 * @ vos Packet
 */
VOS_STATUS vos_pkt_return_packet(vos_pkt_t *packet)
{
   // Validate the input parameter pointer
   if (unlikely(packet == NULL)) {
      return VOS_STATUS_E_INVAL;
   }

   /* Free up the Adf nbuf */
   adf_nbuf_free(packet->pkt_buf);

   packet->pkt_buf = NULL;

   /* Free up the Rx packet */
   vos_mem_free(packet);

   return VOS_STATUS_SUCCESS;
}

/**--------------------------------------------------------------------------

  \brief vos_pkt_get_packet_length() - Get packet length for a voss Packet

  This API returns the total length of the data in a voss Packet.

  \param pPacket - the voss Packet to get the packet length from.

  \param pPacketSize - location to return the total size of the data contained
                       in the voss Packet.
  \return

  \sa

  ---------------------------------------------------------------------------*/
VOS_STATUS vos_pkt_get_packet_length( vos_pkt_t *pPacket,
                                      v_U16_t *pPacketSize )
{
   // Validate the parameter pointers
   if (unlikely((pPacket == NULL) || (pPacketSize == NULL)) ||
                   (pPacket->pkt_buf == NULL))
   {
      VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
                "VPKT [%d]: NULL pointer", __LINE__);
      return VOS_STATUS_E_INVAL;
   }

   // return the requested information
   *pPacketSize = adf_nbuf_len(pPacket->pkt_buf);
   return VOS_STATUS_SUCCESS;
}

/*
 * TODO: Remove below later since all the below
 * definitions are not required for Host
 * driver 2.0 (still references from HDD and
 * other layers are yet to be removed)
 */
VOS_STATUS vos_pkt_get_available_buffer_pool (VOS_PKT_TYPE  pktType,
                                              v_SIZE_t     *vosFreeBuffer)
{
    return VOS_STATUS_SUCCESS;
}

VOS_STATUS vos_pkt_get_os_packet( vos_pkt_t *pPacket,
                                  v_VOID_t **ppOSPacket,
                                  v_BOOL_t clearOSPacket )
{
   return VOS_STATUS_SUCCESS;
}

VOS_STATUS vos_pkt_wrap_data_packet( vos_pkt_t **ppPacket,
                                     VOS_PKT_TYPE pktType,
                                     v_VOID_t *pOSPacket,
                                     vos_pkt_get_packet_callback callback,
                                     v_VOID_t *userData )
{
   return VOS_STATUS_SUCCESS;
}

VOS_STATUS vos_pkt_set_os_packet( vos_pkt_t *pPacket,
                                  v_VOID_t *pOSPacket )
{
   return VOS_STATUS_SUCCESS;
}

VOS_STATUS vos_pkt_get_timestamp( vos_pkt_t *pPacket,
                                  v_TIME_t* pTstamp )
{
   return VOS_STATUS_SUCCESS;
}

VOS_STATUS vos_pkt_walk_packet_chain( vos_pkt_t *pPacket,
                                      vos_pkt_t **ppChainedPacket,
                                      v_BOOL_t unchainPacket )
{
   return VOS_STATUS_SUCCESS;
}

VOS_STATUS vos_pkt_peek_data( vos_pkt_t *pPacket,
                              v_SIZE_t pktOffset,
                              v_VOID_t **ppPacketData,
                              v_SIZE_t numBytes )
{
   return VOS_STATUS_SUCCESS;
}
VOS_STATUS vos_pkt_get_packet( vos_pkt_t **ppPacket,
                               VOS_PKT_TYPE pktType,
                               v_SIZE_t dataSize,
                               v_SIZE_t numPackets,
                               v_BOOL_t zeroBuffer,
                               vos_pkt_get_packet_callback callback,
                               v_VOID_t *userData )
{
   return VOS_STATUS_SUCCESS;
}

VOS_STATUS vos_pkt_reserve_head( vos_pkt_t *pPacket,
                                 v_VOID_t **ppData,
                                 v_SIZE_t dataSize )
{
   return VOS_STATUS_SUCCESS;
}

VOS_STATUS vos_pkt_pop_head( vos_pkt_t *pPacket,
                             v_VOID_t *pData,
                             v_SIZE_t dataSize )
{
   return VOS_STATUS_SUCCESS;
}

VOS_STATUS vos_pkt_push_head( vos_pkt_t *pPacket,
                              v_VOID_t *pData,
                              v_SIZE_t dataSize )
{
   return VOS_STATUS_SUCCESS;
}

v_VOID_t vos_pkt_set_user_data_ptr( vos_pkt_t *pPacket,
                                    VOS_PKT_USER_DATA_ID userID,
                                    v_VOID_t *pUserData )
{
   return;
}

v_VOID_t vos_pkt_get_user_data_ptr( vos_pkt_t *pPacket,
                                    VOS_PKT_USER_DATA_ID userID,
                                    v_VOID_t **ppUserData )
{
   return;
}

VOS_STATUS vos_pkt_extract_data( vos_pkt_t *pPacket,
                                 v_SIZE_t pktOffset,
                                 v_VOID_t *pOutputBuffer,
                                 v_SIZE_t *pOutputBufferSize )
{
   return VOS_STATUS_SUCCESS;
}

/*---------------------------------------------------------------------------

  * brief vos_pkt_get_proto_type() -
      Find protoco type from packet contents

  * skb Packet Pointer
  * tracking_map packet type want to track
  * dot11_type, type of dot11 frame

---------------------------------------------------------------------------*/
v_U8_t vos_pkt_get_proto_type
(
   struct sk_buff *skb,
   v_U8_t tracking_map,
   v_U8_t dot11_type
)
{
   v_U8_t     pkt_proto_type = 0;

   if (dot11_type)
   {
      if (dot11_type == (VOS_PKT_TRAC_TYPE_MGMT_ACTION & tracking_map))
         pkt_proto_type = VOS_PKT_TRAC_TYPE_MGMT_ACTION;

      /* Protocol type map */
      return pkt_proto_type;
   }

   /* EAPOL Tracking enabled */
   if (VOS_PKT_TRAC_TYPE_EAPOL & tracking_map)
   {
      if (adf_nbuf_is_eapol_pkt(skb)) {
         pkt_proto_type = VOS_PKT_TRAC_TYPE_EAPOL;
         return pkt_proto_type;
      }
   }

   /* DHCP Tracking enabled */
   if (VOS_PKT_TRAC_TYPE_DHCP & tracking_map)
   {
      if (adf_nbuf_is_dhcp_pkt(skb)) {
         pkt_proto_type = VOS_PKT_TRAC_TYPE_DHCP;
         return pkt_proto_type;
      }
   }

   /* ARP Tracking enabled */
   if (VOS_PKT_TRAC_TYPE_ARP & tracking_map) {
      if (adf_nbuf_is_ipv4_arp_pkt(skb)) {
          pkt_proto_type = VOS_PKT_TRAC_TYPE_ARP;
          return pkt_proto_type;
      }
   }

   /* IPV6 NS Tracking enabled */
   if (VOS_PKT_TRAC_TYPE_NS & tracking_map) {
      if (adf_nbuf_is_icmpv6_pkt(skb)) {
          if (adf_nbuf_get_icmpv6_subtype(skb) ==
                   ADF_PROTO_ICMPV6_NS) {
              pkt_proto_type = VOS_PKT_TRAC_TYPE_NS;
              return pkt_proto_type;
          }
      }
   }

   /* IPV6 NA Tracking enabled */
   if (VOS_PKT_TRAC_TYPE_NA & tracking_map) {
      if (adf_nbuf_is_icmpv6_pkt(skb)) {
          if (adf_nbuf_get_icmpv6_subtype(skb) ==
                   ADF_PROTO_ICMPV6_NA) {
              pkt_proto_type = VOS_PKT_TRAC_TYPE_NA;
              return pkt_proto_type;
          }
      }
   }

   /* Protocol type map */
   return pkt_proto_type;
}

#ifdef QCA_PKT_PROTO_TRACE
/**
 * vos_pkt_trace_buf_update - Update storage buffer with interested event string
 * @event_string: A string for packet type or outstanding event
 */
void vos_pkt_trace_buf_update
(
   char    *event_string
)
{
   v_U32_t slot;
   struct timeval tv;

   VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
             "%s %d, %s", __func__, __LINE__, event_string);

   if (!trace_buffer) {
      VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
                "trace_buffer is already free");
      return;
   }

   SPIN_LOCK_BH(&trace_buffer_lock);
   slot = trace_buffer_order % VOS_PKT_TRAC_MAX_TRACE_BUF;
   trace_buffer[slot].order = trace_buffer_order;
   trace_buffer_order++;
   SPIN_UNLOCK_BH(&trace_buffer_lock);
   do_gettimeofday(&tv);
   trace_buffer[slot].event_sec_time = tv.tv_sec;
   trace_buffer[slot].event_msec_time = tv.tv_usec;
   strlcpy(trace_buffer[slot].event_string, event_string,
          sizeof(trace_buffer[slot].event_string));

   return;
}

/**
 * vos_pkt_trace_dump_slot_buf() - Helper function to dump pkt trace
 * @slot: index
 *
 * Return: none
 */
void vos_pkt_trace_dump_slot_buf(int slot)
{
	struct rtc_time tm;
	unsigned long local_time;

	local_time = (u32)(trace_buffer[slot].event_sec_time -
		(sys_tz.tz_minuteswest * 60));
	rtc_time_to_tm(local_time, &tm);
	VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
		"%5d : [%02d:%02d:%02d.%06lu] : %s",
		trace_buffer[slot].order,
		tm.tm_hour, tm.tm_min, tm.tm_sec,
		trace_buffer[slot].event_sec_time,
		trace_buffer[slot].event_string);
}

/**
 * vos_pkt_trace_buf_dump - Dump stored information into kernel log
 */
void vos_pkt_trace_buf_dump(void)
{
	uint32_t i, latest_idx = trace_buffer_order;
	int slot;

	if (!trace_buffer || !latest_idx) {
		VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO,
                "trace_buffer is already free trace_buffer_order: %d",
		trace_buffer_order);
		return;
	}
	VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
		"PACKET TRACE DUMP START Current Timestamp %u",
		(unsigned int)vos_timer_get_system_time());
	VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
		"ORDER :          RTC TIME :    EVT");

	if (VOS_PKT_TRAC_MAX_TRACE_BUF > latest_idx) {
		/*
		 * Scenario: Number of trace records less than MAX,
		 * Circular buffer not overwritten.
		 */
		for (slot = latest_idx - 1; slot >= 0 &&
		     slot > trace_dump_order; slot--)
			vos_pkt_trace_dump_slot_buf(slot);
	} else {
		/*
		 * Scenario: Number of trace records exceeded MAX,
		 * Circular buffer is overwritten.
		 */
		for (i = 0; (i < VOS_PKT_TRAC_MAX_TRACE_BUF) &&
		     (latest_idx - i - 1 > trace_dump_order); i++) {
			slot = ((latest_idx - i - 1) %
				VOS_PKT_TRAC_MAX_TRACE_BUF);
			vos_pkt_trace_dump_slot_buf(slot);
		}
	}

	trace_dump_order = latest_idx - 1;
	VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
			"PACKET TRACE DUMP END");

	return;
}

/**
 * vos_pkt_proto_trace_init -  Initialize protocol trace functionality and
 * allocate required resources
 */
void vos_pkt_proto_trace_init
(
   void
)
{
   /* Init spin lock to protect global memory */
   spin_lock_init(&trace_buffer_lock);
   trace_buffer_order = 0;
   trace_buffer = vos_mem_malloc(
       VOS_PKT_TRAC_MAX_TRACE_BUF * sizeof(vos_pkt_proto_trace_t));
   vos_mem_zero((void *)trace_buffer,
       VOS_PKT_TRAC_MAX_TRACE_BUF * sizeof(vos_pkt_proto_trace_t));

   /* Register callback function to NBUF
    * Lower layer event also will be reported to here */
   adf_nbuf_reg_trace_cb(vos_pkt_trace_buf_update);
   return;
}

/*---------------------------------------------------------------------------

  * brief vos_pkt_proto_trace_close() -
      Free required resource

---------------------------------------------------------------------------*/
void vos_pkt_proto_trace_close
(
   void
)
{
   VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
             "%s %d", __func__, __LINE__);
   SPIN_LOCK_BH(&trace_buffer_lock);
   vos_mem_free(trace_buffer);
   trace_buffer = NULL;
   SPIN_UNLOCK_BH(&trace_buffer_lock);

   return;
}
#endif /* QCA_PKT_PROTO_TRACE */
