/*
 * 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.
 */

/******************************************************************************
* wlan_nlink_srv.c
*
* This file contains the definitions specific to the wlan_nlink_srv
*
******************************************************************************/

#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/netlink.h>
#include <linux/skbuff.h>
#include <net/sock.h>
#include <wlan_nlink_srv.h>
#include <vos_trace.h>

#ifdef CNSS_GENL
#include <vos_memory.h>
#include <wlan_nlink_common.h>
#include <net/genetlink.h>
#include <net/cnss_nl.h>
#endif

#if defined(CONFIG_CNSS_LOGGER)

#include <net/cnss_logger.h>

static int radio_idx = -EINVAL;
static void *wiphy_ptr;
static bool logger_initialized;

/**
 * nl_srv_init() - wrapper function to register to cnss_logger
 * @wiphy:	the pointer to the wiphy structure
 *
 * The netlink socket is no longer initialized in the driver itself, instead
 * will be initialized in the cnss_logger module, the driver should register
 * itself to cnss_logger module to get the radio_index for all the netlink
 * operation. (cfg80211 vendor command is using different netlink socket).
 *
 * The cnss_logger_device_register() use to register the driver with the
 * wiphy structure and the module name (debug purpose) and then return the
 * radio_index depending on the availibility.
 *
 * Return: radio index for success and -EINVAL for failure
 */
int nl_srv_init(void *wiphy)
{
	if (logger_initialized)
		goto initialized;

	wiphy_ptr = wiphy;
	radio_idx = cnss_logger_device_register(wiphy, THIS_MODULE->name);
	VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
		  "%s: radio_index: %d", __func__, radio_idx);

	if (radio_idx >= 0)
		logger_initialized = true;

initialized:
	return radio_idx;
}

/**
 * nl_srv_exit() - wrapper function to unregister from cnss_logger
 *
 * The cnss_logger_device_unregister() use to unregister the driver with
 * the radio_index assigned and wiphy structure from cnss_logger.
 *
 * Return: None
 */
void nl_srv_exit(void)
{
	if (logger_initialized) {
		cnss_logger_device_unregister(radio_idx, wiphy_ptr);
		radio_idx = -EINVAL;
		wiphy_ptr = NULL;
		logger_initialized = false;
	}
}

/**
 * nl_srv_ucast() - wrapper function to do unicast tx through cnss_logger
 * @skb:	the socket buffer to send
 * @dst_pid:	the port id
 * @flag:	the blocking or nonblocking flag
 *
 * The nl_srv_is_initialized() is used to do sanity check if the netlink
 * service is ready, e.g if the radio_index is assigned properly, if not
 * the driver should take the responsibility to free the skb.
 *
 * The cnss_logger_nl_ucast() use the same parameters to send the socket
 * buffers.
 *
 * Return: the error of the transmission status
 */
int nl_srv_ucast(struct sk_buff *skb, int dst_pid, int flag)
{
	int err = -EINVAL;

	/* sender's pid */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
	NETLINK_CB(skb).pid = 0;
#else
	NETLINK_CB(skb).portid = 0;
#endif
	/* not multicast */
	NETLINK_CB(skb).dst_group = 0;

	if (nl_srv_is_initialized() == 0)
		err = cnss_logger_nl_ucast(skb, dst_pid, flag);
	else
		dev_kfree_skb(skb);
	return err;
}

/**
 * nl_srv_bcast() - wrapper function to do broadcast tx through cnss_logger
 * @skb:	the socket buffer to send
 *
 * The cnss_logger_nl_bcast() is used to transmit the socket buffer.
 *
 * Return: status of transmission
 */
int nl_srv_bcast(struct sk_buff *skb)
{
	int err = -EINVAL;
	int flags = GFP_KERNEL;

	if (in_interrupt() || irqs_disabled() || in_atomic())
		flags = GFP_ATOMIC;

	/* sender's pid */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
	NETLINK_CB(skb).pid = 0;
#else
	NETLINK_CB(skb).portid = 0;
#endif
	 /* destination group */
	NETLINK_CB(skb).dst_group = WLAN_NLINK_MCAST_GRP_ID;

	if (nl_srv_is_initialized() == 0)
		err = cnss_logger_nl_bcast(skb, WLAN_NLINK_MCAST_GRP_ID, flags);
	else
		dev_kfree_skb(skb);
	return err;
}

/**
 * nl_srv_unregister() - wrapper function to unregister event to cnss_logger
 * @msg_type:		the message to unregister
 * @msg_handler:	the message handler
 *
 * The cnss_logger_event_unregister() is used to unregister the message and
 * message handler.
 *
 * Return: 0 if successfully unregister, otherwise proper error code
 */
int nl_srv_unregister(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler)
{
	int ret = -EINVAL;

	if (nl_srv_is_initialized() != 0)
		return ret;

	if ((msg_type >= WLAN_NL_MSG_BASE) && (msg_type < WLAN_NL_MSG_MAX) &&
	    msg_handler != NULL) {
		ret = cnss_logger_event_unregister(radio_idx, msg_type,
						   msg_handler);
	} else {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			  "NLINK: nl_srv_unregister failed for msg_type %d",
			  msg_type);
		ret = -EINVAL;
	}

	return ret;
}

/**
 * nl_srv_register() - wrapper function to register event to cnss_logger
 * @msg_type:		the message to register
 * @msg_handler:	the message handler
 *
 * The cnss_logger_event_register() is used to register the message and
 * message handler.
 *
 * Return: 0 if successfully register, otherwise proper error code
 */
int nl_srv_register(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler)
{
	int ret = -EINVAL;

	if (nl_srv_is_initialized() != 0)
		return ret;

	if ((msg_type >= WLAN_NL_MSG_BASE) && (msg_type < WLAN_NL_MSG_MAX) &&
	    msg_handler != NULL) {
		ret = cnss_logger_event_register(radio_idx, msg_type,
						 msg_handler);
	} else {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			  "NLINK: nl_srv_register failed for msg_type %d",
			  msg_type);
		ret = -EINVAL;
	}

	return ret;
}

/**
 * nl_srv_is_initialized() - check if netlink service is initialized
 *
 * Return: 0 if it is initialized, otherwise error code
 */
inline int nl_srv_is_initialized(void)
{
	if (logger_initialized)
		return 0;
	else
		return -EPERM;
}

#elif !defined(MULTI_IF_NAME)
/* Global variables */
static DEFINE_MUTEX(nl_srv_sem);
static struct sock *nl_srv_sock;
static nl_srv_msg_callback nl_srv_msg_handler[NLINK_MAX_CALLBACKS];

/* Forward declaration */
static void nl_srv_rcv (struct sk_buff *sk);
static void nl_srv_rcv_skb (struct sk_buff *skb);
static void nl_srv_rcv_msg (struct sk_buff *skb, struct nlmsghdr *nlh);

/*
 * Initialize the netlink service.
 * Netlink service is usable after this.
 */
int nl_srv_init(void *wiphy)
{
   int retcode = 0;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
   struct netlink_kernel_cfg cfg = {
      .groups = WLAN_NLINK_MCAST_GRP_ID,
      .input = nl_srv_rcv
   };
#endif

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
   nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_PROTO_FAMILY,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
                                       THIS_MODULE,
#endif
                                       &cfg);
#else
   nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_PROTO_FAMILY,
      WLAN_NLINK_MCAST_GRP_ID, nl_srv_rcv, NULL, THIS_MODULE);
#endif

   if (nl_srv_sock != NULL) {
      memset(nl_srv_msg_handler, 0, sizeof(nl_srv_msg_handler));
   } else {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
         "NLINK: netlink_kernel_create failed");
      retcode = -ECONNREFUSED;
   }
   return retcode;
}

/*
 * Deinit the netlink service.
 * Netlink service is unusable after this.
 */
void nl_srv_exit(void)
{
   netlink_kernel_release(nl_srv_sock);
   nl_srv_sock = NULL;
}

/*
 * Register a message handler for a specified module.
 * Each module (e.g. WLAN_NL_MSG_BTC )will register a
 * handler to handle messages addressed to it.
 */
int nl_srv_register(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler)
{
   int retcode = 0;

   if ((msg_type >= WLAN_NL_MSG_BASE) && (msg_type < WLAN_NL_MSG_MAX) &&
        msg_handler != NULL)
   {
      nl_srv_msg_handler[msg_type - WLAN_NL_MSG_BASE] = msg_handler;
   }
   else {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
         "NLINK: nl_srv_register failed for msg_type %d", msg_type);
      retcode = -EINVAL;
   }

   return retcode;
}
/*
 * Unregister the message handler for a specified module.
 */
int nl_srv_unregister(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler)
{
   int retcode = 0;

   if ((msg_type >= WLAN_NL_MSG_BASE) && (msg_type < WLAN_NL_MSG_MAX) &&
       (nl_srv_msg_handler[msg_type - WLAN_NL_MSG_BASE] == msg_handler))
   {
      nl_srv_msg_handler[msg_type - WLAN_NL_MSG_BASE] = NULL;
   }
   else
   {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
         "NLINK: nl_srv_unregister failed for msg_type %d", msg_type);
      retcode = -EINVAL;
   }

   return retcode;
}

#ifdef CNSS_GENL

/**
 * nl80211hdr_put() - API to fill genlmsg header
 * @skb: Sk buffer
 * @portid: Port ID
 * @seq: Sequence number
 * @flags: Flags
 * @cmd: Command id
 *
 * API to fill genl message header for brodcast events to user space
 *
 * Return: Pointer to user specific header/payload
 */
static inline void *nl80211hdr_put(struct sk_buff *skb, uint32_t portid,
					uint32_t seq, int flags, uint8_t cmd)
{
	struct genl_family *cld80211_fam = cld80211_get_genl_family();

	return genlmsg_put(skb, portid, seq, cld80211_fam, flags, cmd);
}

/**
 * cld80211_fill_data() - API to fill payload to nl message
 * @msg: Sk buffer
 * @portid: Port ID
 * @seq: Sequence number
 * @flags: Flags
 * @cmd: Command ID
 * @buf: data buffer/payload to be filled
 * @len: length of the payload ie. @buf
 *
 * API to fill the payload/data of the nl message to be sent
 *
 * Return: zero on success
 */
static int cld80211_fill_data(struct sk_buff *msg, uint32_t portid,
					uint32_t seq, int flags, uint8_t cmd,
					uint8_t *buf, int len)
{
	void *hdr;
	struct nlattr *nest;

	hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
	if (!hdr) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
						"nl80211 hdr put failed");
		return -EPERM;
	}

	nest = nla_nest_start(msg, CLD80211_ATTR_VENDOR_DATA);
	if (!nest) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
						"nla_nest_start failed");
		goto nla_put_failure;
	}

	if (nla_put(msg, CLD80211_ATTR_DATA, len, buf)) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
							"nla_put failed");
		goto nla_put_failure;
	}

	nla_nest_end(msg, nest);
	genlmsg_end(msg, hdr);

	return 0;
nla_put_failure:
	genlmsg_cancel(msg, hdr);
	return -EPERM;
}

/**
 * send_msg_to_cld80211() - API to send message to user space Application
 * @mcgroup_id: Multicast group ID
 * @pid: Port ID
 * @app_id: Application ID
 * @buf: Data/payload buffer to be sent
 * @len: Length of the data ie. @buf
 *
 * API to send the nl message to user space application.
 *
 * Return: zero on success
 */
static int send_msg_to_cld80211(int mcgroup_id, int pid, int app_id,
						uint8_t *buf, int len)
{
	struct sk_buff *msg;
	struct genl_family *cld80211_fam = cld80211_get_genl_family();
	int status;
	int flags = GFP_KERNEL;

	if (in_interrupt() || irqs_disabled() || in_atomic())
		flags = GFP_ATOMIC;

	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, flags);
	if (!msg) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
						"nlmsg malloc fails");
		return -EPERM;
	}

	status = cld80211_fill_data(msg, pid, 0, 0, app_id, buf, len);
	if (status) {
		nlmsg_free(msg);
		return -EPERM;
	}

	genlmsg_multicast_netns(cld80211_fam, &init_net, msg, 0,
						mcgroup_id, flags);
	return 0;
}

/**
 * nl_srv_bcast() - wrapper function to do broadcast events to user space apps
 * @skb: the socket buffer to send
 * @mcgroup_id: multicast group id
 * @app_id: application id
 *
 * This function is common wrapper to send broadcast events to different
 * user space applications.
 *
 * return: none
 */
int nl_srv_bcast(struct sk_buff *skb, int mcgroup_id, int app_id)
{
	struct nlmsghdr *nlh = (struct nlmsghdr *)skb->data;
	void *msg = NLMSG_DATA(nlh);
	uint32_t msg_len = nlmsg_len(nlh);
	uint8_t *tempbuf;
	int status;

	tempbuf = (uint8_t *)vos_mem_malloc(msg_len);
	vos_mem_copy(tempbuf, msg, msg_len);
	status = send_msg_to_cld80211(mcgroup_id, 0, app_id, tempbuf, msg_len);
	if (status) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			"send msg to cld80211 fails for app id %d", app_id);
		return -EPERM;
	}

	dev_kfree_skb(skb);
	vos_mem_free(tempbuf);
	return 0;
}

/**
 * nl_srv_ucast() - wrapper function to do unicast events to user space apps
 * @skb: the socket buffer to send
 * @dst_pid: destination process IF
 * @flag: flags
 * @app_id: application id
 * @mcgroup_id: Multicast group ID
 *
 * This function is common wrapper to send unicast events to different
 * user space applications. This internally used broadcast API with multicast
 * group mcgrp_id. This wrapper serves as a common API in both
 * new generic netlink infra and legacy implementation.
 *
 * return: zero on success, error code otherwise
 */
int nl_srv_ucast(struct sk_buff *skb, int dst_pid, int flag,
					int app_id, int mcgroup_id)
{
	struct nlmsghdr *nlh = (struct nlmsghdr *)skb->data;
	void *msg = NLMSG_DATA(nlh);
	uint32_t msg_len = nlmsg_len(nlh);
	uint8_t *tempbuf;
	int status;

	tempbuf = (uint8_t *)vos_mem_malloc(msg_len);
	vos_mem_copy(tempbuf, msg, msg_len);
	status = send_msg_to_cld80211(mcgroup_id, dst_pid, app_id,
					tempbuf, msg_len);
	if (status) {
		VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
			"send msg to cld80211 fails for app id %d", app_id);
		return -EPERM;
	}

	dev_kfree_skb(skb);
	vos_mem_free(tempbuf);
	return 0;
}

#else
/*
 * Unicast the message to the process in user space identfied
 * by the dst-pid
 */
int nl_srv_ucast(struct sk_buff *skb, int dst_pid, int flag)
{
   int err = 0;

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
   NETLINK_CB(skb).pid = 0; //sender's pid
#else
   NETLINK_CB(skb).portid = 0; //sender's pid
#endif
   NETLINK_CB(skb).dst_group = 0; //not multicast

   if (nl_srv_sock != NULL) {
       err = netlink_unicast(nl_srv_sock, skb, dst_pid, flag);
   } else {
       dev_kfree_skb(skb);
   }

   if (err < 0)
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
      "NLINK: netlink_unicast to pid[%d] failed, ret[%d]", dst_pid, err);

   return err;
}

int nl_srv_bcast(struct sk_buff *skb)
{
   int err = 0;
   int flags = GFP_KERNEL;

   if (in_interrupt() || irqs_disabled() || in_atomic())
       flags = GFP_ATOMIC;

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
   NETLINK_CB(skb).pid = 0; //sender's pid
#else
   NETLINK_CB(skb).portid = 0; //sender's pid
#endif
   NETLINK_CB(skb).dst_group = WLAN_NLINK_MCAST_GRP_ID; //destination group

   if (nl_srv_sock != NULL)
       err = netlink_broadcast(nl_srv_sock, skb, 0, WLAN_NLINK_MCAST_GRP_ID, flags);
   else
       dev_kfree_skb(skb);

   if ((err < 0) && (err != -ESRCH))
   {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
         "NLINK: netlink_broadcast failed err = %d", err);
   }
   return err;
}

#endif

/*
 *  Processes the Netlink socket input queue.
 *  Dequeue skb's from the socket input queue and process
 *  all the netlink messages in that skb, before moving
 *  to the next skb.
 */
static void nl_srv_rcv(struct sk_buff *sk)
{
   mutex_lock(&nl_srv_sem);
   nl_srv_rcv_skb(sk);
   mutex_unlock(&nl_srv_sem);
}

/*
 * Each skb could contain multiple Netlink messages. Process all the
 * messages in one skb and discard malformed skb's silently.
 */
static void nl_srv_rcv_skb (struct sk_buff *skb)
{
   struct nlmsghdr * nlh;

   while (skb->len >= NLMSG_SPACE(0)) {
      u32 rlen;

      nlh = (struct nlmsghdr *)skb->data;

      if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) {
         VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "NLINK: Invalid "
            "Netlink message: skb[%pK], len[%d], nlhdr[%pK], nlmsg_len[%d]",
            skb, skb->len, nlh, nlh->nlmsg_len);
         return;
      }

      rlen = NLMSG_ALIGN(nlh->nlmsg_len);
      if (rlen > skb->len)
         rlen = skb->len;
      nl_srv_rcv_msg(skb, nlh);
      skb_pull(skb, rlen);
   }
}

/*
 * Process a netlink message.
 * Each netlink message will have a message of type tAniMsgHdr inside.
 */
static void nl_srv_rcv_msg (struct sk_buff *skb, struct nlmsghdr *nlh)
{
   int type;

   /* Only requests are handled by kernel now */
   if (!(nlh->nlmsg_flags & NLM_F_REQUEST)) {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
         "NLINK: Received Invalid NL Req type [%x]", nlh->nlmsg_flags);
      return;
   }

   type = nlh->nlmsg_type;

   /* Unknown message */
   if (type < WLAN_NL_MSG_BASE || type >= WLAN_NL_MSG_MAX) {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
         "NLINK: Received Invalid NL Msg type [%x]", type);
      return;
   }

   /*
   * All the messages must at least carry the tAniMsgHdr
   * Drop any message with invalid length
   */
   if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(tAniMsgHdr))) {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
         "NLINK: Received NL Msg with invalid len[%x]", nlh->nlmsg_len);
      return;
   }

   // turn type into dispatch table offset
   type -= WLAN_NL_MSG_BASE;

   // dispatch to handler
   if (nl_srv_msg_handler[type] != NULL) {
      (nl_srv_msg_handler[type])(skb);
   } else {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
         "NLINK: No handler for Netlink Msg [0x%X]", type);
   }
}

/**
 * nl_srv_is_initialized() - This function is used check if the netlink
 * service is initialized
 *
 * This function is used check if the netlink service is initialized
 *
 * Return: Return -EPERM if the service is not initialized
 *
 */
int nl_srv_is_initialized()
{
	if (nl_srv_sock)
		return 0;
	else
		return -EPERM;
}

#endif
