/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 *
 * RMNET Data virtual network driver
 */

#include <linux/types.h>
#include <linux/rmnet_data.h>
#include <linux/msm_rmnet.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
#include <linux/spinlock.h>
#include <net/pkt_sched.h>
#include <linux/atomic.h>
#include <linux/net_map.h>
#include "rmnet_data_config.h"
#include "rmnet_data_handlers.h"
#include "rmnet_data_private.h"
#include "rmnet_map.h"
#include "rmnet_data_vnd.h"
#include "rmnet_data_stats.h"
#include "rmnet_data_trace.h"

RMNET_LOG_MODULE(RMNET_DATA_LOGMASK_VND);

#define RMNET_MAP_FLOW_NUM_TC_HANDLE 3
#define RMNET_VND_UF_ACTION_ADD 0
#define RMNET_VND_UF_ACTION_DEL 1
enum {
	RMNET_VND_UPDATE_FLOW_OK,
	RMNET_VND_UPDATE_FLOW_NO_ACTION,
	RMNET_VND_UPDATE_FLOW_NO_MORE_ROOM,
	RMNET_VND_UPDATE_FLOW_NO_VALID_LEFT
};

struct net_device *rmnet_devices[RMNET_DATA_MAX_VND];

struct rmnet_map_flow_mapping_s {
	struct list_head list;
	u32 map_flow_id;
	u32 tc_flow_valid[RMNET_MAP_FLOW_NUM_TC_HANDLE];
	u32 tc_flow_id[RMNET_MAP_FLOW_NUM_TC_HANDLE];
	atomic_t v4_seq;
	atomic_t v6_seq;
};

struct rmnet_vnd_private_s {
	u32 qos_version;
	struct rmnet_logical_ep_conf_s local_ep;

	rwlock_t flow_map_lock;
	struct list_head flow_head;
	struct rmnet_map_flow_mapping_s root_flow;
};

#define RMNET_VND_FC_QUEUED      0
#define RMNET_VND_FC_NOT_ENABLED 1
#define RMNET_VND_FC_KMALLOC_ERR 2

/* Helper Functions */

/* rmnet_vnd_add_qos_header() - Adds QoS header to front of skb->data
 * @skb:        Socket buffer ("packet") to modify
 * @dev:        Egress interface
 *
 * Does not check for sufficient headroom! Caller must make sure there is enough
 * headroom.
 */
static void rmnet_vnd_add_qos_header(struct sk_buff *skb,
				     struct net_device *dev,
				     uint32_t qos_version)
{
	struct QMI_QOS_HDR_S *qmih;
	struct qmi_qos_hdr8_s *qmi8h;

	if (qos_version & RMNET_IOCTL_QOS_MODE_6) {
		qmih = (struct QMI_QOS_HDR_S *)
			skb_push(skb, sizeof(struct QMI_QOS_HDR_S));
		qmih->version = 1;
		qmih->flags = 0;
		qmih->flow_id = skb->mark;
	} else if (qos_version & RMNET_IOCTL_QOS_MODE_8) {
		qmi8h = (struct qmi_qos_hdr8_s *)
			skb_push(skb, sizeof(struct qmi_qos_hdr8_s));
		/* Flags are 0 always */
		qmi8h->hdr.version = 0;
		qmi8h->hdr.flags = 0;
		memset(qmi8h->reserved, 0, sizeof(qmi8h->reserved));
		qmi8h->hdr.flow_id = skb->mark;
	} else {
		LOGD("%s(): Bad QoS version configured\n", __func__);
	}
}

/* Network Device Operations */

/* rmnet_vnd_start_xmit() - Transmit NDO callback
 * @skb:        Socket buffer ("packet") being sent from network stack
 * @dev:        Virtual Network Device
 *
 * Standard network driver operations hook to transmit packets on virtual
 * network device. Called by network stack. Packet is not transmitted directly
 * from here; instead it is given to the rmnet egress handler.
 *
 * Return:
 *      - NETDEV_TX_OK under all cirumstances (cannot block/fail)
 */
static netdev_tx_t rmnet_vnd_start_xmit(struct sk_buff *skb,
					struct net_device *dev)
{
	struct rmnet_vnd_private_s *dev_conf;

	trace_rmnet_vnd_start_xmit(skb);
	dev_conf = (struct rmnet_vnd_private_s *)netdev_priv(dev);
	if (dev_conf->local_ep.egress_dev) {
		/* QoS header should come after MAP header */
		if (dev_conf->qos_version)
			rmnet_vnd_add_qos_header(skb,
						 dev,
						 dev_conf->qos_version);
		skb_orphan(skb);
		rmnet_egress_handler(skb, &dev_conf->local_ep);
	} else {
		dev->stats.tx_dropped++;
		rmnet_kfree_skb(skb, RMNET_STATS_SKBFREE_VND_NO_EGRESS);
	}
	return NETDEV_TX_OK;
}

/* rmnet_vnd_change_mtu() - Change MTU NDO callback
 * @dev:         Virtual network device
 * @new_mtu:     New MTU value to set (in bytes)
 *
 * Standard network driver operations hook to set the MTU. Called by kernel to
 * set the device MTU. Checks if desired MTU is less than zero or greater than
 * RMNET_DATA_MAX_PACKET_SIZE;
 *
 * Return:
 *      - 0 if successful
 *      - -EINVAL if new_mtu is out of range
 */
static int rmnet_vnd_change_mtu(struct net_device *dev, int new_mtu)
{
	if (new_mtu < 0 || new_mtu > RMNET_DATA_MAX_PACKET_SIZE)
		return -EINVAL;

	dev->mtu = new_mtu;
	return 0;
}

#ifdef CONFIG_RMNET_DATA_FC
static int _rmnet_vnd_do_qos_ioctl(struct net_device *dev,
				   struct ifreq *ifr,
				   int cmd)
{
	struct rmnet_vnd_private_s *dev_conf;
	int rc, qdisc_len = 0;
	struct rmnet_ioctl_data_s ioctl_data;

	rc = 0;
	dev_conf = (struct rmnet_vnd_private_s *)netdev_priv(dev);

	switch (cmd) {
	case RMNET_IOCTL_SET_QOS_ENABLE:
		if (!capable(CAP_NET_ADMIN))
			return -EPERM;
		LOGM("RMNET_IOCTL_SET_QOS_ENABLE on %s", dev->name);
		if (!dev_conf->qos_version)
			dev_conf->qos_version = RMNET_IOCTL_QOS_MODE_6;
		break;

	case RMNET_IOCTL_SET_QOS_DISABLE:
		if (!capable(CAP_NET_ADMIN))
			return -EPERM;
		LOGM("RMNET_IOCTL_SET_QOS_DISABLE on %s", dev->name);
		dev_conf->qos_version = 0;
		break;

	case RMNET_IOCTL_GET_QOS:           /* Get QoS header state    */
		LOGM("RMNET_IOCTL_GET_QOS on %s", dev->name);
		ioctl_data.u.operation_mode = (dev_conf->qos_version ==
						RMNET_IOCTL_QOS_MODE_6);
		if (copy_to_user(ifr->ifr_ifru.ifru_data, &ioctl_data,
				 sizeof(struct rmnet_ioctl_data_s)))
			rc = -EFAULT;
		break;

	case RMNET_IOCTL_FLOW_ENABLE:
		if (!capable(CAP_NET_ADMIN))
			return -EPERM;
		LOGL("RMNET_IOCTL_FLOW_ENABLE on %s", dev->name);
		if (copy_from_user(&ioctl_data, ifr->ifr_ifru.ifru_data,
				   sizeof(struct rmnet_ioctl_data_s))) {
			rc = -EFAULT;
			break;
		}
		qdisc_len = tc_qdisc_flow_control(dev,
						  ioctl_data.u.tcm_handle, 1);
		trace_rmnet_fc_qmi(ioctl_data.u.tcm_handle, qdisc_len, 1);
		break;

	case RMNET_IOCTL_FLOW_DISABLE:
		if (!capable(CAP_NET_ADMIN))
			return -EPERM;
		LOGL("RMNET_IOCTL_FLOW_DISABLE on %s", dev->name);
		if (copy_from_user(&ioctl_data, ifr->ifr_ifru.ifru_data,
				   sizeof(struct rmnet_ioctl_data_s))) {
			rc = -EFAULT;
		break;
		}
		qdisc_len = tc_qdisc_flow_control(dev,
						  ioctl_data.u.tcm_handle, 0);
		trace_rmnet_fc_qmi(ioctl_data.u.tcm_handle, qdisc_len, 0);
		break;

	default:
		rc = -EINVAL;
	}

	return rc;
}

struct rmnet_vnd_fc_work {
	struct work_struct work;
	struct net_device *dev;
	u32 tc_handle;
	int enable;
};

static void _rmnet_vnd_wq_flow_control(struct work_struct *work)
{
	struct rmnet_vnd_fc_work *fcwork;
	int qdisc_len = 0;

	fcwork = (struct rmnet_vnd_fc_work *)work;

	rtnl_lock();
	qdisc_len = tc_qdisc_flow_control(fcwork->dev, fcwork->tc_handle,
					  fcwork->enable);
	trace_rmnet_fc_map(fcwork->tc_handle, qdisc_len, fcwork->enable);
	rtnl_unlock();

	LOGL("[%s] handle:%08X enable:%d",
	     fcwork->dev->name, fcwork->tc_handle, fcwork->enable);

	kfree(work);
}

static int _rmnet_vnd_do_flow_control(struct net_device *dev,
				      u32 tc_handle,
				      int enable)
{
	struct rmnet_vnd_fc_work *fcwork;

	fcwork = kmalloc(sizeof(*fcwork), GFP_ATOMIC);
	if (!fcwork)
		return RMNET_VND_FC_KMALLOC_ERR;
	memset(fcwork, 0, sizeof(struct rmnet_vnd_fc_work));

	INIT_WORK((struct work_struct *)fcwork, _rmnet_vnd_wq_flow_control);
	fcwork->dev = dev;
	fcwork->tc_handle = tc_handle;
	fcwork->enable = enable;

	schedule_work((struct work_struct *)fcwork);
	return RMNET_VND_FC_QUEUED;
}
#else
static int _rmnet_vnd_do_qos_ioctl(struct net_device *dev,
				   struct ifreq *ifr,
				   int cmd)
{
	return -EINVAL;
}

static inline int _rmnet_vnd_do_flow_control(struct net_device *dev,
					     u32 tc_handle,
					     int enable)
{
	LOGD("[%s] called with no QoS support", dev->name);
	return RMNET_VND_FC_NOT_ENABLED;
}
#endif /* CONFIG_RMNET_DATA_FC */

static int rmnet_vnd_ioctl_extended(struct net_device *dev, struct ifreq *ifr)
{
	struct rmnet_vnd_private_s *dev_conf;
	struct rmnet_ioctl_extended_s ext_cmd;
	int rc = 0;

	dev_conf = (struct rmnet_vnd_private_s *)netdev_priv(dev);

	rc = copy_from_user(&ext_cmd, ifr->ifr_ifru.ifru_data,
			    sizeof(struct rmnet_ioctl_extended_s));
	if (rc) {
		LOGM("%s(): copy_from_user() failed\n", __func__);
		return rc;
	}

	switch (ext_cmd.extended_ioctl) {
	case RMNET_IOCTL_GET_SUPPORTED_FEATURES:
		ext_cmd.u.data = 0;
		break;

	case RMNET_IOCTL_GET_DRIVER_NAME:
		strlcpy(ext_cmd.u.if_name, "rmnet_data",
			sizeof(ext_cmd.u.if_name));
		break;

	case RMNET_IOCTL_GET_SUPPORTED_QOS_MODES:
		ext_cmd.u.data = RMNET_IOCTL_QOS_MODE_6
				 | RMNET_IOCTL_QOS_MODE_8;
		break;

	case RMNET_IOCTL_GET_QOS_VERSION:
		ext_cmd.u.data = dev_conf->qos_version;
		break;

	case RMNET_IOCTL_SET_QOS_VERSION:
		if (!capable(CAP_NET_ADMIN))
			return -EPERM;
		if (ext_cmd.u.data == RMNET_IOCTL_QOS_MODE_6 ||
		    ext_cmd.u.data == RMNET_IOCTL_QOS_MODE_8 ||
		    ext_cmd.u.data == 0) {
			dev_conf->qos_version = ext_cmd.u.data;
		} else {
			rc = -EINVAL;
			goto done;
		}
		break;

	default:
		rc = -EINVAL;
		goto done;
	}

	rc = copy_to_user(ifr->ifr_ifru.ifru_data, &ext_cmd,
			  sizeof(struct rmnet_ioctl_extended_s));
	if (rc)
		LOGM("%s(): copy_to_user() failed\n", __func__);

done:
	return rc;
}

/* rmnet_vnd_ioctl() - IOCTL NDO callback
 * @dev:         Virtual network device
 * @ifreq:       User data
 * @cmd:         IOCTL command value
 *
 * Standard network driver operations hook to process IOCTLs. Called by kernel
 * to process non-stanard IOCTLs for device
 *
 * Return:
 *      - 0 if successful
 *      - -EINVAL if unknown IOCTL
 */
static int rmnet_vnd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	struct rmnet_vnd_private_s *dev_conf;
	int rc;
	struct rmnet_ioctl_data_s ioctl_data;

	rc = 0;
	dev_conf = (struct rmnet_vnd_private_s *)netdev_priv(dev);

	rc = _rmnet_vnd_do_qos_ioctl(dev, ifr, cmd);
	if (rc != -EINVAL)
		return rc;
	rc = 0; /* Reset rc as it may contain -EINVAL from above */

	switch (cmd) {
	case RMNET_IOCTL_OPEN: /* Do nothing. Support legacy behavior */
		LOGM("RMNET_IOCTL_OPEN on %s (ignored)", dev->name);
		break;

	case RMNET_IOCTL_CLOSE: /* Do nothing. Support legacy behavior */
		LOGM("RMNET_IOCTL_CLOSE on %s (ignored)", dev->name);
		break;

	case RMNET_IOCTL_SET_LLP_ETHERNET:
		LOGM("RMNET_IOCTL_SET_LLP_ETHERNET on %s (no support)",
		     dev->name);
		rc = -EINVAL;
		break;

	case RMNET_IOCTL_SET_LLP_IP: /* Do nothing. Support legacy behavior */
		LOGM("RMNET_IOCTL_SET_LLP_IP on %s (ignored)", dev->name);
		break;

	case RMNET_IOCTL_GET_LLP: /* Always return IP mode */
		LOGM("RMNET_IOCTL_GET_LLP on %s", dev->name);
		ioctl_data.u.operation_mode = RMNET_MODE_LLP_IP;
		if (copy_to_user(ifr->ifr_ifru.ifru_data, &ioctl_data,
				 sizeof(struct rmnet_ioctl_data_s)))
			rc = -EFAULT;
		break;

	case RMNET_IOCTL_EXTENDED:
		rc = rmnet_vnd_ioctl_extended(dev, ifr);
		break;

	default:
		LOGM("Unknown IOCTL 0x%08X", cmd);
		rc = -EINVAL;
	}

	return rc;
}

static const struct net_device_ops rmnet_data_vnd_ops = {
	.ndo_init = 0,
	.ndo_start_xmit = rmnet_vnd_start_xmit,
	.ndo_do_ioctl = rmnet_vnd_ioctl,
	.ndo_change_mtu = rmnet_vnd_change_mtu,
	.ndo_set_mac_address = 0,
	.ndo_validate_addr = 0,
};

/* rmnet_vnd_setup() - net_device initialization callback
 * @dev:      Virtual network device
 *
 * Called by kernel whenever a new rmnet_data<n> device is created. Sets MTU,
 * flags, ARP type, needed headroom, etc...
 */
static void rmnet_vnd_setup(struct net_device *dev)
{
	struct rmnet_vnd_private_s *dev_conf;

	LOGM("Setting up device %s", dev->name);

	/* Clear out private data */
	dev_conf = (struct rmnet_vnd_private_s *)netdev_priv(dev);
	memset(dev_conf, 0, sizeof(struct rmnet_vnd_private_s));

	dev->netdev_ops = &rmnet_data_vnd_ops;
	dev->mtu = RMNET_DATA_DFLT_PACKET_SIZE;
	dev->needed_headroom = RMNET_DATA_NEEDED_HEADROOM;
	random_ether_addr(dev->dev_addr);
	dev->tx_queue_len = RMNET_DATA_TX_QUEUE_LEN;

	/* Raw IP mode */
	dev->header_ops = 0;  /* No header */
	dev->type = ARPHRD_RAWIP;
	dev->hard_header_len = 0;
	dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST);

	/* Flow control */
	rwlock_init(&dev_conf->flow_map_lock);
	INIT_LIST_HEAD(&dev_conf->flow_head);
}

/* rmnet_vnd_setup() - net_device initialization helper function
 * @dev:      Virtual network device
 *
 * Called during device initialization. Disables GRO.
 */
static void rmnet_vnd_disable_offload(struct net_device *dev)
{
	dev->wanted_features &= ~NETIF_F_GRO;
	__netdev_update_features(dev);
}

/* Exposed API */

/* rmnet_vnd_exit() - Shutdown cleanup hook
 *
 * Called by RmNet main on module unload. Cleans up data structures and
 * unregisters/frees net_devices.
 */
void rmnet_vnd_exit(void)
{
	int i;

	for (i = 0; i < RMNET_DATA_MAX_VND; i++)
		if (rmnet_devices[i]) {
			unregister_netdev(rmnet_devices[i]);
			free_netdev(rmnet_devices[i]);
	}
}

/* rmnet_vnd_init() - Init hook
 *
 * Called by RmNet main on module load. Initializes data structures
 */
int rmnet_vnd_init(void)
{
	memset(rmnet_devices, 0,
	       sizeof(struct net_device *) * RMNET_DATA_MAX_VND);
	return 0;
}

/* rmnet_vnd_create_dev() - Create a new virtual network device node.
 * @id:         Virtual device node id
 * @new_device: Pointer to newly created device node
 * @prefix:     Device name prefix
 *
 * Allocates structures for new virtual network devices. Sets the name of the
 * new device and registers it with the network stack. Device will appear in
 * ifconfig list after this is called. If the prefix is null, then
 * RMNET_DATA_DEV_NAME_STR will be assumed.
 *
 * Return:
 *      - 0 if successful
 *      - RMNET_CONFIG_BAD_ARGUMENTS if id is out of range or prefix is too long
 *      - RMNET_CONFIG_DEVICE_IN_USE if id already in use
 *      - RMNET_CONFIG_NOMEM if net_device allocation failed
 *      - RMNET_CONFIG_UNKNOWN_ERROR if register_netdevice() fails
 */
int rmnet_vnd_create_dev(int id, struct net_device **new_device,
			 const char *prefix, int use_name)
{
	struct net_device *dev;
	char dev_prefix[IFNAMSIZ];
	int p, rc = 0;

	if (id < 0 || id >= RMNET_DATA_MAX_VND) {
		*new_device = 0;
		return RMNET_CONFIG_BAD_ARGUMENTS;
	}

	if (rmnet_devices[id] != 0) {
		*new_device = 0;
		return RMNET_CONFIG_DEVICE_IN_USE;
	}

	if (!prefix && !use_name)
		p = scnprintf(dev_prefix, IFNAMSIZ, "%s%%d",
			      RMNET_DATA_DEV_NAME_STR);
	else if (prefix && use_name)
		p = scnprintf(dev_prefix, IFNAMSIZ, "%s", prefix);
	else if (prefix && !use_name)
		p = scnprintf(dev_prefix, IFNAMSIZ, "%s%%d", prefix);
	else
		return RMNET_CONFIG_BAD_ARGUMENTS;

	if (p >= (IFNAMSIZ - 1)) {
		LOGE("Specified prefix longer than IFNAMSIZ");
		return RMNET_CONFIG_BAD_ARGUMENTS;
	}

	dev = alloc_netdev(sizeof(struct rmnet_vnd_private_s),
			   dev_prefix,
			   use_name ? NET_NAME_UNKNOWN : NET_NAME_ENUM,
			   rmnet_vnd_setup);
	if (!dev) {
		LOGE("Failed to to allocate netdev for id %d", id);
		*new_device = 0;
		return RMNET_CONFIG_NOMEM;
	}

	if (!prefix) {
		/* Configuring DL checksum offload on rmnet_data interfaces */
		dev->hw_features = NETIF_F_RXCSUM;
		/* Configuring UL checksum offload on rmnet_data interfaces */
		dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
		/* Configuring GRO on rmnet_data interfaces */
		dev->hw_features |= NETIF_F_GRO;
		/* Configuring Scatter-Gather on rmnet_data interfaces */
		dev->hw_features |= NETIF_F_SG;
		/* Configuring GSO on rmnet_data interfaces */
		dev->hw_features |= NETIF_F_GSO;
		dev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
		dev->hw_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
	}

	rc = register_netdevice(dev);
	if (rc != 0) {
		LOGE("Failed to to register netdev [%s]", dev->name);
		free_netdev(dev);
		*new_device = 0;
		return RMNET_CONFIG_UNKNOWN_ERROR;
	} else {
		rmnet_devices[id] = dev;
		*new_device = dev;
		LOGM("Registered device %s", dev->name);
	}

	rmnet_vnd_disable_offload(dev);

	return rc;
}

/* rmnet_vnd_free_dev() - free a virtual network device node.
 * @id:         Virtual device node id
 *
 * Unregisters the virtual network device node and frees it.
 * unregister_netdev locks the rtnl mutex, so the mutex must not be locked
 * by the caller of the function. unregister_netdev enqueues the request to
 * unregister the device into a TODO queue. The requests in the TODO queue
 * are only done after rtnl mutex is unlocked, therefore free_netdev has to
 * called after unlocking rtnl mutex.
 *
 * Return:
 *      - 0 if successful
 *      - RMNET_CONFIG_NO_SUCH_DEVICE if id is invalid or not in range
 *      - RMNET_CONFIG_DEVICE_IN_USE if device has logical ep that wasn't unset
 */
int rmnet_vnd_free_dev(int id)
{
	struct rmnet_logical_ep_conf_s *epconfig_l;
	struct net_device *dev;

	rtnl_lock();
	if ((id < 0) || (id >= RMNET_DATA_MAX_VND) || !rmnet_devices[id]) {
		rtnl_unlock();
		LOGM("Invalid id [%d]", id);
		return RMNET_CONFIG_NO_SUCH_DEVICE;
	}

	epconfig_l = rmnet_vnd_get_le_config(rmnet_devices[id]);
	if (epconfig_l && epconfig_l->refcount) {
		rtnl_unlock();
		return RMNET_CONFIG_DEVICE_IN_USE;
	}

	dev = rmnet_devices[id];
	rmnet_devices[id] = 0;
	rtnl_unlock();

	if (dev) {
		unregister_netdev(dev);
		free_netdev(dev);
		return 0;
	} else {
		return RMNET_CONFIG_NO_SUCH_DEVICE;
	}
}

/* rmnet_vnd_get_name() - Gets the string name of a VND based on ID
 * @id:         Virtual device node id
 * @name:       Buffer to store name of virtual device node
 * @name_len:   Length of name buffer
 *
 * Copies the name of the virtual device node into the users buffer. Will throw
 * an error if the buffer is null, or too small to hold the device name.
 *
 * Return:
 *      - 0 if successful
 *      - -EINVAL if name is null
 *      - -EINVAL if id is invalid or not in range
 *      - -EINVAL if name is too small to hold things
 */
int rmnet_vnd_get_name(int id, char *name, int name_len)
{
	int p;

	if (!name) {
		LOGM("%s", "Bad arguments; name buffer null");
		return -EINVAL;
	}

	if ((id < 0) || (id >= RMNET_DATA_MAX_VND) || !rmnet_devices[id]) {
		LOGM("Invalid id [%d]", id);
		return -EINVAL;
	}

	p = strlcpy(name, rmnet_devices[id]->name, name_len);
	if (p >= name_len) {
		LOGM("Buffer to small (%d) to fit device name", name_len);
		return -EINVAL;
	}
	LOGL("Found mapping [%d]->\"%s\"", id, name);

	return 0;
}

/* rmnet_vnd_is_vnd() - Determine if net_device is RmNet owned virtual devices
 * @dev:        Network device to test
 *
 * Searches through list of known RmNet virtual devices. This function is O(n)
 * and should not be used in the data path.
 *
 * Return:
 *      - 0 if device is not RmNet virtual device
 *      - 1 if device is RmNet virtual device
 */
int rmnet_vnd_is_vnd(struct net_device *dev)
{
	/* This is not an efficient search, but, this will only be called in
	 * a configuration context, and the list is small.
	 */
	int i;

	if (!dev)
		return 0;

	for (i = 0; i < RMNET_DATA_MAX_VND; i++)
		if (dev == rmnet_devices[i])
			return i + 1;

	return 0;
}

/* rmnet_vnd_get_le_config() - Get the logical endpoint configuration
 * @dev:      Virtual device node
 *
 * Gets the logical endpoint configuration for a RmNet virtual network device
 * node. Caller should confirm that devices is a RmNet VND before calling.
 *
 * Return:
 *      - Pointer to logical endpoint configuration structure
 *      - 0 (null) if dev is null
 */
struct rmnet_logical_ep_conf_s *rmnet_vnd_get_le_config(struct net_device *dev)
{
	struct rmnet_vnd_private_s *dev_conf;

	if (!dev)
		return 0;

	dev_conf = (struct rmnet_vnd_private_s *)netdev_priv(dev);
	if (!dev_conf)
		return 0;

	return &dev_conf->local_ep;
}

/* _rmnet_vnd_get_flow_map() - Gets object representing a MAP flow handle
 * @dev_conf: Private configuration structure for virtual network device
 * @map_flow: MAP flow handle IF
 *
 * Loops through available flow mappings and compares the MAP flow handle.
 * Returns when mapping is found.
 *
 * Return:
 *      - Null if no mapping was found
 *      - Pointer to mapping otherwise
 */
static struct rmnet_map_flow_mapping_s *_rmnet_vnd_get_flow_map
					(struct rmnet_vnd_private_s *dev_conf,
					 u32 map_flow)
{
	struct list_head *p;
	struct rmnet_map_flow_mapping_s *itm;

	list_for_each(p, &dev_conf->flow_head) {
		itm = list_entry(p, struct rmnet_map_flow_mapping_s, list);

		if (unlikely(!itm))
			return 0;

		if (itm->map_flow_id == map_flow)
			return itm;
	}
	return 0;
}

/* _rmnet_vnd_update_flow_map() - Add or remove individual TC flow handles
 * @action: One of RMNET_VND_UF_ACTION_ADD / RMNET_VND_UF_ACTION_DEL
 * @itm: Flow mapping object
 * @map_flow: TC flow handle
 *
 * RMNET_VND_UF_ACTION_ADD:
 * Will check for a free mapping slot in the mapping object. If one is found,
 * valid for that slot will be set to 1 and the value will be set.
 *
 * RMNET_VND_UF_ACTION_DEL:
 * Will check for matching tc handle. If found, valid for that slot will be
 * set to 0 and the value will also be zeroed.
 *
 * Return:
 *      - RMNET_VND_UPDATE_FLOW_OK tc flow handle is added/removed ok
 *      - RMNET_VND_UPDATE_FLOW_NO_MORE_ROOM if there are no more tc handles
 *      - RMNET_VND_UPDATE_FLOW_NO_VALID_LEFT if flow mapping is now empty
 *      - RMNET_VND_UPDATE_FLOW_NO_ACTION if no action was taken
 */
static int _rmnet_vnd_update_flow_map(u8 action,
				      struct rmnet_map_flow_mapping_s *itm,
				      u32 tc_flow)
{
	int rc, i, j;

	rc = RMNET_VND_UPDATE_FLOW_OK;

	switch (action) {
	case RMNET_VND_UF_ACTION_ADD:
		rc = RMNET_VND_UPDATE_FLOW_NO_MORE_ROOM;
		for (i = 0; i < RMNET_MAP_FLOW_NUM_TC_HANDLE; i++) {
			if (itm->tc_flow_valid[i] == 0) {
				itm->tc_flow_valid[i] = 1;
				itm->tc_flow_id[i] = tc_flow;
				rc = RMNET_VND_UPDATE_FLOW_OK;
				LOGD("{%pK}->tc_flow_id[%d]=%08X",
				     itm, i, tc_flow);
				break;
			}
		}
		break;

	case RMNET_VND_UF_ACTION_DEL:
		j = 0;
		rc = RMNET_VND_UPDATE_FLOW_OK;
		for (i = 0; i < RMNET_MAP_FLOW_NUM_TC_HANDLE; i++) {
			if (itm->tc_flow_valid[i] == 1) {
				if (itm->tc_flow_id[i] == tc_flow) {
					itm->tc_flow_valid[i] = 0;
					itm->tc_flow_id[i] = 0;
					j++;
					LOGD("{%pK}->tc_flow_id[%d]=0", itm, i);
				}
			} else {
				j++;
			}
		}
		if (j == RMNET_MAP_FLOW_NUM_TC_HANDLE)
			rc = RMNET_VND_UPDATE_FLOW_NO_VALID_LEFT;
		break;

	default:
		rc = RMNET_VND_UPDATE_FLOW_NO_ACTION;
		break;
	}
	return rc;
}

/* rmnet_vnd_add_tc_flow() - Add a MAP/TC flow handle mapping
 * @id: Virtual network device ID
 * @map_flow: MAP flow handle
 * @tc_flow: TC flow handle
 *
 * Checkes for an existing flow mapping object corresponding to map_flow. If one
 * is found, then it will try to add to the existing mapping object. Otherwise,
 * a new mapping object is created.
 *
 * Return:
 *      - RMNET_CONFIG_OK if successful
 *      - RMNET_CONFIG_TC_HANDLE_FULL if there is no more room in the map object
 *      - RMNET_CONFIG_NOMEM failed to allocate a new map object
 */
int rmnet_vnd_add_tc_flow(u32 id, u32 map_flow, u32 tc_flow)
{
	struct rmnet_map_flow_mapping_s *itm;
	struct net_device *dev;
	struct rmnet_vnd_private_s *dev_conf;
	int r;
	unsigned long flags;

	if ((id < 0) || (id >= RMNET_DATA_MAX_VND) || !rmnet_devices[id]) {
		LOGM("Invalid VND id [%d]", id);
		return RMNET_CONFIG_NO_SUCH_DEVICE;
	}

	dev = rmnet_devices[id];
	dev_conf = (struct rmnet_vnd_private_s *)netdev_priv(dev);

	if (!dev_conf)
		return RMNET_CONFIG_NO_SUCH_DEVICE;

	write_lock_irqsave(&dev_conf->flow_map_lock, flags);
	itm = _rmnet_vnd_get_flow_map(dev_conf, map_flow);
	if (itm) {
		r = _rmnet_vnd_update_flow_map(RMNET_VND_UF_ACTION_ADD,
					       itm, tc_flow);
		if (r != RMNET_VND_UPDATE_FLOW_OK) {
			write_unlock_irqrestore(&dev_conf->flow_map_lock,
						flags);
			return RMNET_CONFIG_TC_HANDLE_FULL;
		}
		write_unlock_irqrestore(&dev_conf->flow_map_lock, flags);
		return RMNET_CONFIG_OK;
	}
	write_unlock_irqrestore(&dev_conf->flow_map_lock, flags);

	itm = kmalloc(sizeof(*itm), GFP_KERNEL);

	if (!itm) {
		LOGM("%s", "Failure allocating flow mapping");
		return RMNET_CONFIG_NOMEM;
	}
	memset(itm, 0, sizeof(struct rmnet_map_flow_mapping_s));

	itm->map_flow_id = map_flow;
	itm->tc_flow_valid[0] = 1;
	itm->tc_flow_id[0] = tc_flow;

	/* How can we dynamically init these safely? Kernel only provides static
	 * initializers for atomic_t
	 */
	itm->v4_seq.counter =  0; /* Init is broken: ATOMIC_INIT(0); */
	itm->v6_seq.counter =  0; /* Init is broken: ATOMIC_INIT(0); */

	write_lock_irqsave(&dev_conf->flow_map_lock, flags);
	list_add(&itm->list, &dev_conf->flow_head);
	write_unlock_irqrestore(&dev_conf->flow_map_lock, flags);

	LOGD("Created flow mapping [%s][0x%08X][0x%08X]@%pK",
	     dev->name, itm->map_flow_id, itm->tc_flow_id[0], itm);

	return RMNET_CONFIG_OK;
}

/* rmnet_vnd_del_tc_flow() - Delete a MAP/TC flow handle mapping
 * @id: Virtual network device ID
 * @map_flow: MAP flow handle
 * @tc_flow: TC flow handle
 *
 * Checkes for an existing flow mapping object corresponding to map_flow. If one
 * is found, then it will try to remove the existing tc_flow mapping. If the
 * mapping object no longer contains any mappings, then it is freed. Otherwise
 * the mapping object is left in the list
 *
 * Return:
 *      - RMNET_CONFIG_OK if successful or if there was no such tc_flow
 *      - RMNET_CONFIG_INVALID_REQUEST if there is no such map_flow
 */
int rmnet_vnd_del_tc_flow(u32 id, u32 map_flow, u32 tc_flow)
{
	struct rmnet_vnd_private_s *dev_conf;
	struct net_device *dev;
	struct rmnet_map_flow_mapping_s *itm;
	int r;
	unsigned long flags;
	int rc = RMNET_CONFIG_OK;

	if ((id < 0) || (id >= RMNET_DATA_MAX_VND) || !rmnet_devices[id]) {
		LOGM("Invalid VND id [%d]", id);
		return RMNET_CONFIG_NO_SUCH_DEVICE;
	}

	dev = rmnet_devices[id];
	dev_conf = (struct rmnet_vnd_private_s *)netdev_priv(dev);

	if (!dev_conf)
		return RMNET_CONFIG_NO_SUCH_DEVICE;

	r = RMNET_VND_UPDATE_FLOW_NO_ACTION;
	write_lock_irqsave(&dev_conf->flow_map_lock, flags);
	itm = _rmnet_vnd_get_flow_map(dev_conf, map_flow);
	if (!itm) {
		rc = RMNET_CONFIG_INVALID_REQUEST;
	} else {
		r = _rmnet_vnd_update_flow_map(RMNET_VND_UF_ACTION_DEL,
					       itm, tc_flow);
		if (r ==  RMNET_VND_UPDATE_FLOW_NO_VALID_LEFT)
			list_del(&itm->list);
	}
	write_unlock_irqrestore(&dev_conf->flow_map_lock, flags);

	if (r ==  RMNET_VND_UPDATE_FLOW_NO_VALID_LEFT) {
		if (itm)
			LOGD("Removed flow mapping [%s][0x%08X]@%pK",
			     dev->name, itm->map_flow_id, itm);
		kfree(itm);
	}

	return rc;
}

/* rmnet_vnd_do_flow_control() - Process flow control request
 * @dev: Virtual network device node to do lookup on
 * @map_flow_id: Flow ID from MAP message
 * @v4_seq: pointer to IPv4 indication sequence number
 * @v6_seq: pointer to IPv6 indication sequence number
 * @enable: boolean to enable/disable flow.
 *
 * Return:
 *      - 0 if successful
 *      - 1 if no mapping is found
 *      - 2 if dev is not RmNet virtual network device node
 */
int rmnet_vnd_do_flow_control(struct net_device *dev,
			      u32 map_flow_id,
			      u16 v4_seq,
			      u16 v6_seq,
			      int enable)
{
	struct rmnet_vnd_private_s *dev_conf;
	struct rmnet_map_flow_mapping_s *itm;
	int do_fc, error, i;

	error = 0;
	do_fc = 0;

	if (unlikely(!dev))
		return 2;

	if (!rmnet_vnd_is_vnd(dev))
		return 2;

	dev_conf = (struct rmnet_vnd_private_s *)netdev_priv(dev);

	if (unlikely(!dev_conf))
		return 2;

	read_lock(&dev_conf->flow_map_lock);
	if (map_flow_id == 0xFFFFFFFF) {
		itm = &dev_conf->root_flow;
		goto nolookup;
	}

	itm = _rmnet_vnd_get_flow_map(dev_conf, map_flow_id);

	if (!itm) {
		LOGL("Got flow control request for unknown flow %08X",
		     map_flow_id);
		goto fcdone;
	}

nolookup:
	if (v4_seq == 0 || v4_seq >= atomic_read(&itm->v4_seq)) {
		atomic_set(&itm->v4_seq, v4_seq);
		if (map_flow_id == 0xFFFFFFFF) {
			LOGD("Setting VND TX queue state to %d", enable);
			/* Although we expect similar number of enable/disable
			 * commands, optimize for the disable. That is more
			 * latency sensitive than enable
			 */
			if (unlikely(enable))
				netif_wake_queue(dev);
			else
				netif_stop_queue(dev);
			trace_rmnet_fc_map(0xFFFFFFFF, 0, enable);
			goto fcdone;
		}
		for (i = 0; i < RMNET_MAP_FLOW_NUM_TC_HANDLE; i++) {
			if (itm->tc_flow_valid[i] == 1) {
				LOGD("Found [%s][0x%08X][%d:0x%08X]",
				     dev->name, itm->map_flow_id, i,
				     itm->tc_flow_id[i]);

				_rmnet_vnd_do_flow_control(dev,
							   itm->tc_flow_id[i],
							   enable);
			}
		}
	} else {
		LOGD("Internal seq(%hd) higher than called(%hd)",
		     atomic_read(&itm->v4_seq), v4_seq);
	}

fcdone:
	read_unlock(&dev_conf->flow_map_lock);

	return error;
}

/* rmnet_vnd_get_by_id() - Get VND by array index ID
 * @id: Virtual network deice id [0:RMNET_DATA_MAX_VND]
 *
 * Return:
 *      - 0 if no device or ID out of range
 *      - otherwise return pointer to VND net_device struct
 */
struct net_device *rmnet_vnd_get_by_id(int id)
{
	if (id < 0 || id >= RMNET_DATA_MAX_VND) {
		LOGE("Bug; VND ID out of bounds");
		return 0;
	}
	return rmnet_devices[id];
}
