/*
 * Copyright (C) ST-Ericsson AB 2010
 * Author:	Sjur Brendeland/sjur.brandeland@stericsson.com
 * License terms: GNU General Public License (GPL) version 2
 */

#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__

#include <linux/stddef.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/rculist.h>
#include <net/caif/cfpkt.h>
#include <net/caif/cfmuxl.h>
#include <net/caif/cfsrvl.h>
#include <net/caif/cffrml.h>

#define container_obj(layr) container_of(layr, struct cfmuxl, layer)

#define CAIF_CTRL_CHANNEL 0
#define UP_CACHE_SIZE 8
#define DN_CACHE_SIZE 8

struct cfmuxl {
	struct cflayer layer;
	struct list_head srvl_list;
	struct list_head frml_list;
	struct cflayer *up_cache[UP_CACHE_SIZE];
	struct cflayer *dn_cache[DN_CACHE_SIZE];
	/*
	 * Set when inserting or removing downwards layers.
	 */
	spinlock_t transmit_lock;

	/*
	 * Set when inserting or removing upwards layers.
	 */
	spinlock_t receive_lock;

};

static int cfmuxl_receive(struct cflayer *layr, struct cfpkt *pkt);
static int cfmuxl_transmit(struct cflayer *layr, struct cfpkt *pkt);
static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
			   int phyid);
static struct cflayer *get_up(struct cfmuxl *muxl, u16 id);

struct cflayer *cfmuxl_create(void)
{
	struct cfmuxl *this = kmalloc(sizeof(struct cfmuxl), GFP_ATOMIC);
	if (!this)
		return NULL;
	memset(this, 0, sizeof(*this));
	this->layer.receive = cfmuxl_receive;
	this->layer.transmit = cfmuxl_transmit;
	this->layer.ctrlcmd = cfmuxl_ctrlcmd;
	INIT_LIST_HEAD(&this->srvl_list);
	INIT_LIST_HEAD(&this->frml_list);
	spin_lock_init(&this->transmit_lock);
	spin_lock_init(&this->receive_lock);
	snprintf(this->layer.name, CAIF_LAYER_NAME_SZ, "mux");
	return &this->layer;
}

int cfmuxl_set_dnlayer(struct cflayer *layr, struct cflayer *dn, u8 phyid)
{
	struct cfmuxl *muxl = (struct cfmuxl *) layr;

	spin_lock_bh(&muxl->transmit_lock);
	list_add_rcu(&dn->node, &muxl->frml_list);
	spin_unlock_bh(&muxl->transmit_lock);
	return 0;
}

static struct cflayer *get_from_id(struct list_head *list, u16 id)
{
	struct cflayer *lyr;
	list_for_each_entry_rcu(lyr, list, node) {
		if (lyr->id == id)
			return lyr;
	}

	return NULL;
}

int cfmuxl_set_uplayer(struct cflayer *layr, struct cflayer *up, u8 linkid)
{
	struct cfmuxl *muxl = container_obj(layr);
	struct cflayer *old;

	spin_lock_bh(&muxl->receive_lock);

	/* Two entries with same id is wrong, so remove old layer from mux */
	old = get_from_id(&muxl->srvl_list, linkid);
	if (old != NULL)
		list_del_rcu(&old->node);

	list_add_rcu(&up->node, &muxl->srvl_list);
	spin_unlock_bh(&muxl->receive_lock);

	return 0;
}

struct cflayer *cfmuxl_remove_dnlayer(struct cflayer *layr, u8 phyid)
{
	struct cfmuxl *muxl = container_obj(layr);
	struct cflayer *dn;
	int idx = phyid % DN_CACHE_SIZE;

	spin_lock_bh(&muxl->transmit_lock);
	RCU_INIT_POINTER(muxl->dn_cache[idx], NULL);
	dn = get_from_id(&muxl->frml_list, phyid);
	if (dn == NULL)
		goto out;

	list_del_rcu(&dn->node);
	caif_assert(dn != NULL);
out:
	spin_unlock_bh(&muxl->transmit_lock);
	return dn;
}

static struct cflayer *get_up(struct cfmuxl *muxl, u16 id)
{
	struct cflayer *up;
	int idx = id % UP_CACHE_SIZE;
	up = rcu_dereference(muxl->up_cache[idx]);
	if (up == NULL || up->id != id) {
		spin_lock_bh(&muxl->receive_lock);
		up = get_from_id(&muxl->srvl_list, id);
		rcu_assign_pointer(muxl->up_cache[idx], up);
		spin_unlock_bh(&muxl->receive_lock);
	}
	return up;
}

static struct cflayer *get_dn(struct cfmuxl *muxl, struct dev_info *dev_info)
{
	struct cflayer *dn;
	int idx = dev_info->id % DN_CACHE_SIZE;
	dn = rcu_dereference(muxl->dn_cache[idx]);
	if (dn == NULL || dn->id != dev_info->id) {
		spin_lock_bh(&muxl->transmit_lock);
		dn = get_from_id(&muxl->frml_list, dev_info->id);
		rcu_assign_pointer(muxl->dn_cache[idx], dn);
		spin_unlock_bh(&muxl->transmit_lock);
	}
	return dn;
}

struct cflayer *cfmuxl_remove_uplayer(struct cflayer *layr, u8 id)
{
	struct cflayer *up;
	struct cfmuxl *muxl = container_obj(layr);
	int idx = id % UP_CACHE_SIZE;

	if (id == 0) {
		pr_warn("Trying to remove control layer\n");
		return NULL;
	}

	spin_lock_bh(&muxl->receive_lock);
	up = get_from_id(&muxl->srvl_list, id);
	if (up == NULL)
		goto out;

	RCU_INIT_POINTER(muxl->up_cache[idx], NULL);
	list_del_rcu(&up->node);
out:
	spin_unlock_bh(&muxl->receive_lock);
	return up;
}

static int cfmuxl_receive(struct cflayer *layr, struct cfpkt *pkt)
{
	int ret;
	struct cfmuxl *muxl = container_obj(layr);
	u8 id;
	struct cflayer *up;
	if (cfpkt_extr_head(pkt, &id, 1) < 0) {
		pr_err("erroneous Caif Packet\n");
		cfpkt_destroy(pkt);
		return -EPROTO;
	}
	rcu_read_lock();
	up = get_up(muxl, id);

	if (up == NULL) {
		pr_debug("Received data on unknown link ID = %d (0x%x)"
			" up == NULL", id, id);
		cfpkt_destroy(pkt);
		/*
		 * Don't return ERROR, since modem misbehaves and sends out
		 * flow on before linksetup response.
		 */

		rcu_read_unlock();
		return /* CFGLU_EPROT; */ 0;
	}

	/* We can't hold rcu_lock during receive, so take a ref count instead */
	cfsrvl_get(up);
	rcu_read_unlock();

	ret = up->receive(up, pkt);

	cfsrvl_put(up);
	return ret;
}

static int cfmuxl_transmit(struct cflayer *layr, struct cfpkt *pkt)
{
	struct cfmuxl *muxl = container_obj(layr);
	int err;
	u8 linkid;
	struct cflayer *dn;
	struct caif_payload_info *info = cfpkt_info(pkt);
	BUG_ON(!info);

	rcu_read_lock();

	dn = get_dn(muxl, info->dev_info);
	if (dn == NULL) {
		pr_debug("Send data on unknown phy ID = %d (0x%x)\n",
			info->dev_info->id, info->dev_info->id);
		rcu_read_unlock();
		cfpkt_destroy(pkt);
		return -ENOTCONN;
	}

	info->hdr_len += 1;
	linkid = info->channel_id;
	cfpkt_add_head(pkt, &linkid, 1);

	/* We can't hold rcu_lock during receive, so take a ref count instead */
	cffrml_hold(dn);

	rcu_read_unlock();

	err = dn->transmit(dn, pkt);

	cffrml_put(dn);
	return err;
}

static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
			   int phyid)
{
	struct cfmuxl *muxl = container_obj(layr);
	struct cflayer *layer;

	rcu_read_lock();
	list_for_each_entry_rcu(layer, &muxl->srvl_list, node) {

		if (cfsrvl_phyid_match(layer, phyid) && layer->ctrlcmd) {

			if ((ctrl == _CAIF_CTRLCMD_PHYIF_DOWN_IND ||
				ctrl == CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND) &&
					layer->id != 0)
				cfmuxl_remove_uplayer(layr, layer->id);

			/* NOTE: ctrlcmd is not allowed to block */
			layer->ctrlcmd(layer, ctrl, phyid);
		}
	}
	rcu_read_unlock();
}
