/*
 * Copyright Gavin Shan, IBM Corporation 2016.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>

#include <net/ncsi.h>
#include <net/net_namespace.h>
#include <net/sock.h>
#include <net/addrconf.h>
#include <net/ipv6.h>
#include <net/if_inet6.h>

#include "internal.h"
#include "ncsi-pkt.h"
#include "ncsi-netlink.h"

LIST_HEAD(ncsi_dev_list);
DEFINE_SPINLOCK(ncsi_dev_lock);

static inline int ncsi_filter_size(int table)
{
	int sizes[] = { 2, 6, 6, 6 };

	BUILD_BUG_ON(ARRAY_SIZE(sizes) != NCSI_FILTER_MAX);
	if (table < NCSI_FILTER_BASE || table >= NCSI_FILTER_MAX)
		return -EINVAL;

	return sizes[table];
}

u32 *ncsi_get_filter(struct ncsi_channel *nc, int table, int index)
{
	struct ncsi_channel_filter *ncf;
	int size;

	ncf = nc->filters[table];
	if (!ncf)
		return NULL;

	size = ncsi_filter_size(table);
	if (size < 0)
		return NULL;

	return ncf->data + size * index;
}

/* Find the first active filter in a filter table that matches the given
 * data parameter. If data is NULL, this returns the first active filter.
 */
int ncsi_find_filter(struct ncsi_channel *nc, int table, void *data)
{
	struct ncsi_channel_filter *ncf;
	void *bitmap;
	int index, size;
	unsigned long flags;

	ncf = nc->filters[table];
	if (!ncf)
		return -ENXIO;

	size = ncsi_filter_size(table);
	if (size < 0)
		return size;

	spin_lock_irqsave(&nc->lock, flags);
	bitmap = (void *)&ncf->bitmap;
	index = -1;
	while ((index = find_next_bit(bitmap, ncf->total, index + 1))
	       < ncf->total) {
		if (!data || !memcmp(ncf->data + size * index, data, size)) {
			spin_unlock_irqrestore(&nc->lock, flags);
			return index;
		}
	}
	spin_unlock_irqrestore(&nc->lock, flags);

	return -ENOENT;
}

int ncsi_add_filter(struct ncsi_channel *nc, int table, void *data)
{
	struct ncsi_channel_filter *ncf;
	int index, size;
	void *bitmap;
	unsigned long flags;

	size = ncsi_filter_size(table);
	if (size < 0)
		return size;

	index = ncsi_find_filter(nc, table, data);
	if (index >= 0)
		return index;

	ncf = nc->filters[table];
	if (!ncf)
		return -ENODEV;

	spin_lock_irqsave(&nc->lock, flags);
	bitmap = (void *)&ncf->bitmap;
	do {
		index = find_next_zero_bit(bitmap, ncf->total, 0);
		if (index >= ncf->total) {
			spin_unlock_irqrestore(&nc->lock, flags);
			return -ENOSPC;
		}
	} while (test_and_set_bit(index, bitmap));

	memcpy(ncf->data + size * index, data, size);
	spin_unlock_irqrestore(&nc->lock, flags);

	return index;
}

int ncsi_remove_filter(struct ncsi_channel *nc, int table, int index)
{
	struct ncsi_channel_filter *ncf;
	int size;
	void *bitmap;
	unsigned long flags;

	size = ncsi_filter_size(table);
	if (size < 0)
		return size;

	ncf = nc->filters[table];
	if (!ncf || index >= ncf->total)
		return -ENODEV;

	spin_lock_irqsave(&nc->lock, flags);
	bitmap = (void *)&ncf->bitmap;
	if (test_and_clear_bit(index, bitmap))
		memset(ncf->data + size * index, 0, size);
	spin_unlock_irqrestore(&nc->lock, flags);

	return 0;
}

static void ncsi_report_link(struct ncsi_dev_priv *ndp, bool force_down)
{
	struct ncsi_dev *nd = &ndp->ndev;
	struct ncsi_package *np;
	struct ncsi_channel *nc;
	unsigned long flags;

	nd->state = ncsi_dev_state_functional;
	if (force_down) {
		nd->link_up = 0;
		goto report;
	}

	nd->link_up = 0;
	NCSI_FOR_EACH_PACKAGE(ndp, np) {
		NCSI_FOR_EACH_CHANNEL(np, nc) {
			spin_lock_irqsave(&nc->lock, flags);

			if (!list_empty(&nc->link) ||
			    nc->state != NCSI_CHANNEL_ACTIVE) {
				spin_unlock_irqrestore(&nc->lock, flags);
				continue;
			}

			if (nc->modes[NCSI_MODE_LINK].data[2] & 0x1) {
				spin_unlock_irqrestore(&nc->lock, flags);
				nd->link_up = 1;
				goto report;
			}

			spin_unlock_irqrestore(&nc->lock, flags);
		}
	}

report:
	nd->handler(nd);
}

static void ncsi_channel_monitor(struct timer_list *t)
{
	struct ncsi_channel *nc = from_timer(nc, t, monitor.timer);
	struct ncsi_package *np = nc->package;
	struct ncsi_dev_priv *ndp = np->ndp;
	struct ncsi_channel_mode *ncm;
	struct ncsi_cmd_arg nca;
	bool enabled, chained;
	unsigned int monitor_state;
	unsigned long flags;
	int state, ret;

	spin_lock_irqsave(&nc->lock, flags);
	state = nc->state;
	chained = !list_empty(&nc->link);
	enabled = nc->monitor.enabled;
	monitor_state = nc->monitor.state;
	spin_unlock_irqrestore(&nc->lock, flags);

	if (!enabled || chained) {
		ncsi_stop_channel_monitor(nc);
		return;
	}
	if (state != NCSI_CHANNEL_INACTIVE &&
	    state != NCSI_CHANNEL_ACTIVE) {
		ncsi_stop_channel_monitor(nc);
		return;
	}

	switch (monitor_state) {
	case NCSI_CHANNEL_MONITOR_START:
	case NCSI_CHANNEL_MONITOR_RETRY:
		nca.ndp = ndp;
		nca.package = np->id;
		nca.channel = nc->id;
		nca.type = NCSI_PKT_CMD_GLS;
		nca.req_flags = 0;
		ret = ncsi_xmit_cmd(&nca);
		if (ret)
			netdev_err(ndp->ndev.dev, "Error %d sending GLS\n",
				   ret);
		break;
	case NCSI_CHANNEL_MONITOR_WAIT ... NCSI_CHANNEL_MONITOR_WAIT_MAX:
		break;
	default:
		netdev_err(ndp->ndev.dev, "NCSI Channel %d timed out!\n",
			   nc->id);
		if (!(ndp->flags & NCSI_DEV_HWA)) {
			ncsi_report_link(ndp, true);
			ndp->flags |= NCSI_DEV_RESHUFFLE;
		}

		ncsi_stop_channel_monitor(nc);

		ncm = &nc->modes[NCSI_MODE_LINK];
		spin_lock_irqsave(&nc->lock, flags);
		nc->state = NCSI_CHANNEL_INVISIBLE;
		ncm->data[2] &= ~0x1;
		spin_unlock_irqrestore(&nc->lock, flags);

		spin_lock_irqsave(&ndp->lock, flags);
		nc->state = NCSI_CHANNEL_ACTIVE;
		list_add_tail_rcu(&nc->link, &ndp->channel_queue);
		spin_unlock_irqrestore(&ndp->lock, flags);
		ncsi_process_next_channel(ndp);
		return;
	}

	spin_lock_irqsave(&nc->lock, flags);
	nc->monitor.state++;
	spin_unlock_irqrestore(&nc->lock, flags);
	mod_timer(&nc->monitor.timer, jiffies + HZ);
}

void ncsi_start_channel_monitor(struct ncsi_channel *nc)
{
	unsigned long flags;

	spin_lock_irqsave(&nc->lock, flags);
	WARN_ON_ONCE(nc->monitor.enabled);
	nc->monitor.enabled = true;
	nc->monitor.state = NCSI_CHANNEL_MONITOR_START;
	spin_unlock_irqrestore(&nc->lock, flags);

	mod_timer(&nc->monitor.timer, jiffies + HZ);
}

void ncsi_stop_channel_monitor(struct ncsi_channel *nc)
{
	unsigned long flags;

	spin_lock_irqsave(&nc->lock, flags);
	if (!nc->monitor.enabled) {
		spin_unlock_irqrestore(&nc->lock, flags);
		return;
	}
	nc->monitor.enabled = false;
	spin_unlock_irqrestore(&nc->lock, flags);

	del_timer_sync(&nc->monitor.timer);
}

struct ncsi_channel *ncsi_find_channel(struct ncsi_package *np,
				       unsigned char id)
{
	struct ncsi_channel *nc;

	NCSI_FOR_EACH_CHANNEL(np, nc) {
		if (nc->id == id)
			return nc;
	}

	return NULL;
}

struct ncsi_channel *ncsi_add_channel(struct ncsi_package *np, unsigned char id)
{
	struct ncsi_channel *nc, *tmp;
	int index;
	unsigned long flags;

	nc = kzalloc(sizeof(*nc), GFP_ATOMIC);
	if (!nc)
		return NULL;

	nc->id = id;
	nc->package = np;
	nc->state = NCSI_CHANNEL_INACTIVE;
	nc->monitor.enabled = false;
	timer_setup(&nc->monitor.timer, ncsi_channel_monitor, 0);
	spin_lock_init(&nc->lock);
	INIT_LIST_HEAD(&nc->link);
	for (index = 0; index < NCSI_CAP_MAX; index++)
		nc->caps[index].index = index;
	for (index = 0; index < NCSI_MODE_MAX; index++)
		nc->modes[index].index = index;

	spin_lock_irqsave(&np->lock, flags);
	tmp = ncsi_find_channel(np, id);
	if (tmp) {
		spin_unlock_irqrestore(&np->lock, flags);
		kfree(nc);
		return tmp;
	}

	list_add_tail_rcu(&nc->node, &np->channels);
	np->channel_num++;
	spin_unlock_irqrestore(&np->lock, flags);

	return nc;
}

static void ncsi_remove_channel(struct ncsi_channel *nc)
{
	struct ncsi_package *np = nc->package;
	struct ncsi_channel_filter *ncf;
	unsigned long flags;
	int i;

	/* Release filters */
	spin_lock_irqsave(&nc->lock, flags);
	for (i = 0; i < NCSI_FILTER_MAX; i++) {
		ncf = nc->filters[i];
		if (!ncf)
			continue;

		nc->filters[i] = NULL;
		kfree(ncf);
	}

	nc->state = NCSI_CHANNEL_INACTIVE;
	spin_unlock_irqrestore(&nc->lock, flags);
	ncsi_stop_channel_monitor(nc);

	/* Remove and free channel */
	spin_lock_irqsave(&np->lock, flags);
	list_del_rcu(&nc->node);
	np->channel_num--;
	spin_unlock_irqrestore(&np->lock, flags);

	kfree(nc);
}

struct ncsi_package *ncsi_find_package(struct ncsi_dev_priv *ndp,
				       unsigned char id)
{
	struct ncsi_package *np;

	NCSI_FOR_EACH_PACKAGE(ndp, np) {
		if (np->id == id)
			return np;
	}

	return NULL;
}

struct ncsi_package *ncsi_add_package(struct ncsi_dev_priv *ndp,
				      unsigned char id)
{
	struct ncsi_package *np, *tmp;
	unsigned long flags;

	np = kzalloc(sizeof(*np), GFP_ATOMIC);
	if (!np)
		return NULL;

	np->id = id;
	np->ndp = ndp;
	spin_lock_init(&np->lock);
	INIT_LIST_HEAD(&np->channels);

	spin_lock_irqsave(&ndp->lock, flags);
	tmp = ncsi_find_package(ndp, id);
	if (tmp) {
		spin_unlock_irqrestore(&ndp->lock, flags);
		kfree(np);
		return tmp;
	}

	list_add_tail_rcu(&np->node, &ndp->packages);
	ndp->package_num++;
	spin_unlock_irqrestore(&ndp->lock, flags);

	return np;
}

void ncsi_remove_package(struct ncsi_package *np)
{
	struct ncsi_dev_priv *ndp = np->ndp;
	struct ncsi_channel *nc, *tmp;
	unsigned long flags;

	/* Release all child channels */
	list_for_each_entry_safe(nc, tmp, &np->channels, node)
		ncsi_remove_channel(nc);

	/* Remove and free package */
	spin_lock_irqsave(&ndp->lock, flags);
	list_del_rcu(&np->node);
	ndp->package_num--;
	spin_unlock_irqrestore(&ndp->lock, flags);

	kfree(np);
}

void ncsi_find_package_and_channel(struct ncsi_dev_priv *ndp,
				   unsigned char id,
				   struct ncsi_package **np,
				   struct ncsi_channel **nc)
{
	struct ncsi_package *p;
	struct ncsi_channel *c;

	p = ncsi_find_package(ndp, NCSI_PACKAGE_INDEX(id));
	c = p ? ncsi_find_channel(p, NCSI_CHANNEL_INDEX(id)) : NULL;

	if (np)
		*np = p;
	if (nc)
		*nc = c;
}

/* For two consecutive NCSI commands, the packet IDs shouldn't
 * be same. Otherwise, the bogus response might be replied. So
 * the available IDs are allocated in round-robin fashion.
 */
struct ncsi_request *ncsi_alloc_request(struct ncsi_dev_priv *ndp,
					unsigned int req_flags)
{
	struct ncsi_request *nr = NULL;
	int i, limit = ARRAY_SIZE(ndp->requests);
	unsigned long flags;

	/* Check if there is one available request until the ceiling */
	spin_lock_irqsave(&ndp->lock, flags);
	for (i = ndp->request_id; i < limit; i++) {
		if (ndp->requests[i].used)
			continue;

		nr = &ndp->requests[i];
		nr->used = true;
		nr->flags = req_flags;
		ndp->request_id = i + 1;
		goto found;
	}

	/* Fail back to check from the starting cursor */
	for (i = NCSI_REQ_START_IDX; i < ndp->request_id; i++) {
		if (ndp->requests[i].used)
			continue;

		nr = &ndp->requests[i];
		nr->used = true;
		nr->flags = req_flags;
		ndp->request_id = i + 1;
		goto found;
	}

found:
	spin_unlock_irqrestore(&ndp->lock, flags);
	return nr;
}

void ncsi_free_request(struct ncsi_request *nr)
{
	struct ncsi_dev_priv *ndp = nr->ndp;
	struct sk_buff *cmd, *rsp;
	unsigned long flags;
	bool driven;

	if (nr->enabled) {
		nr->enabled = false;
		del_timer_sync(&nr->timer);
	}

	spin_lock_irqsave(&ndp->lock, flags);
	cmd = nr->cmd;
	rsp = nr->rsp;
	nr->cmd = NULL;
	nr->rsp = NULL;
	nr->used = false;
	driven = !!(nr->flags & NCSI_REQ_FLAG_EVENT_DRIVEN);
	spin_unlock_irqrestore(&ndp->lock, flags);

	if (driven && cmd && --ndp->pending_req_num == 0)
		schedule_work(&ndp->work);

	/* Release command and response */
	consume_skb(cmd);
	consume_skb(rsp);
}

struct ncsi_dev *ncsi_find_dev(struct net_device *dev)
{
	struct ncsi_dev_priv *ndp;

	NCSI_FOR_EACH_DEV(ndp) {
		if (ndp->ndev.dev == dev)
			return &ndp->ndev;
	}

	return NULL;
}

static void ncsi_request_timeout(struct timer_list *t)
{
	struct ncsi_request *nr = from_timer(nr, t, timer);
	struct ncsi_dev_priv *ndp = nr->ndp;
	unsigned long flags;

	/* If the request already had associated response,
	 * let the response handler to release it.
	 */
	spin_lock_irqsave(&ndp->lock, flags);
	nr->enabled = false;
	if (nr->rsp || !nr->cmd) {
		spin_unlock_irqrestore(&ndp->lock, flags);
		return;
	}
	spin_unlock_irqrestore(&ndp->lock, flags);

	/* Release the request */
	ncsi_free_request(nr);
}

static void ncsi_suspend_channel(struct ncsi_dev_priv *ndp)
{
	struct ncsi_dev *nd = &ndp->ndev;
	struct ncsi_package *np = ndp->active_package;
	struct ncsi_channel *nc = ndp->active_channel;
	struct ncsi_cmd_arg nca;
	unsigned long flags;
	int ret;

	nca.ndp = ndp;
	nca.req_flags = NCSI_REQ_FLAG_EVENT_DRIVEN;
	switch (nd->state) {
	case ncsi_dev_state_suspend:
		nd->state = ncsi_dev_state_suspend_select;
		/* Fall through */
	case ncsi_dev_state_suspend_select:
		ndp->pending_req_num = 1;

		nca.type = NCSI_PKT_CMD_SP;
		nca.package = np->id;
		nca.channel = NCSI_RESERVED_CHANNEL;
		if (ndp->flags & NCSI_DEV_HWA)
			nca.bytes[0] = 0;
		else
			nca.bytes[0] = 1;

		/* To retrieve the last link states of channels in current
		 * package when current active channel needs fail over to
		 * another one. It means we will possibly select another
		 * channel as next active one. The link states of channels
		 * are most important factor of the selection. So we need
		 * accurate link states. Unfortunately, the link states on
		 * inactive channels can't be updated with LSC AEN in time.
		 */
		if (ndp->flags & NCSI_DEV_RESHUFFLE)
			nd->state = ncsi_dev_state_suspend_gls;
		else
			nd->state = ncsi_dev_state_suspend_dcnt;
		ret = ncsi_xmit_cmd(&nca);
		if (ret)
			goto error;

		break;
	case ncsi_dev_state_suspend_gls:
		ndp->pending_req_num = np->channel_num;

		nca.type = NCSI_PKT_CMD_GLS;
		nca.package = np->id;

		nd->state = ncsi_dev_state_suspend_dcnt;
		NCSI_FOR_EACH_CHANNEL(np, nc) {
			nca.channel = nc->id;
			ret = ncsi_xmit_cmd(&nca);
			if (ret)
				goto error;
		}

		break;
	case ncsi_dev_state_suspend_dcnt:
		ndp->pending_req_num = 1;

		nca.type = NCSI_PKT_CMD_DCNT;
		nca.package = np->id;
		nca.channel = nc->id;

		nd->state = ncsi_dev_state_suspend_dc;
		ret = ncsi_xmit_cmd(&nca);
		if (ret)
			goto error;

		break;
	case ncsi_dev_state_suspend_dc:
		ndp->pending_req_num = 1;

		nca.type = NCSI_PKT_CMD_DC;
		nca.package = np->id;
		nca.channel = nc->id;
		nca.bytes[0] = 1;

		nd->state = ncsi_dev_state_suspend_deselect;
		ret = ncsi_xmit_cmd(&nca);
		if (ret)
			goto error;

		break;
	case ncsi_dev_state_suspend_deselect:
		ndp->pending_req_num = 1;

		nca.type = NCSI_PKT_CMD_DP;
		nca.package = np->id;
		nca.channel = NCSI_RESERVED_CHANNEL;

		nd->state = ncsi_dev_state_suspend_done;
		ret = ncsi_xmit_cmd(&nca);
		if (ret)
			goto error;

		break;
	case ncsi_dev_state_suspend_done:
		spin_lock_irqsave(&nc->lock, flags);
		nc->state = NCSI_CHANNEL_INACTIVE;
		spin_unlock_irqrestore(&nc->lock, flags);
		ncsi_process_next_channel(ndp);

		break;
	default:
		netdev_warn(nd->dev, "Wrong NCSI state 0x%x in suspend\n",
			    nd->state);
	}

	return;
error:
	nd->state = ncsi_dev_state_functional;
}

/* Check the VLAN filter bitmap for a set filter, and construct a
 * "Set VLAN Filter - Disable" packet if found.
 */
static int clear_one_vid(struct ncsi_dev_priv *ndp, struct ncsi_channel *nc,
			 struct ncsi_cmd_arg *nca)
{
	int index;
	u32 *data;
	u16 vid;

	index = ncsi_find_filter(nc, NCSI_FILTER_VLAN, NULL);
	if (index < 0) {
		/* Filter table empty */
		return -1;
	}

	data = ncsi_get_filter(nc, NCSI_FILTER_VLAN, index);
	if (!data) {
		netdev_err(ndp->ndev.dev,
			   "NCSI: failed to retrieve filter %d\n", index);
		/* Set the VLAN id to 0 - this will still disable the entry in
		 * the filter table, but we won't know what it was.
		 */
		vid = 0;
	} else {
		vid = *(u16 *)data;
	}

	netdev_printk(KERN_DEBUG, ndp->ndev.dev,
		      "NCSI: removed vlan tag %u at index %d\n",
		      vid, index + 1);
	ncsi_remove_filter(nc, NCSI_FILTER_VLAN, index);

	nca->type = NCSI_PKT_CMD_SVF;
	nca->words[1] = vid;
	/* HW filter index starts at 1 */
	nca->bytes[6] = index + 1;
	nca->bytes[7] = 0x00;
	return 0;
}

/* Find an outstanding VLAN tag and constuct a "Set VLAN Filter - Enable"
 * packet.
 */
static int set_one_vid(struct ncsi_dev_priv *ndp, struct ncsi_channel *nc,
		       struct ncsi_cmd_arg *nca)
{
	struct vlan_vid *vlan = NULL;
	int index = 0;

	list_for_each_entry_rcu(vlan, &ndp->vlan_vids, list) {
		index = ncsi_find_filter(nc, NCSI_FILTER_VLAN, &vlan->vid);
		if (index < 0) {
			/* New tag to add */
			netdev_printk(KERN_DEBUG, ndp->ndev.dev,
				      "NCSI: new vlan id to set: %u\n",
				      vlan->vid);
			break;
		}
		netdev_printk(KERN_DEBUG, ndp->ndev.dev,
			      "vid %u already at filter pos %d\n",
			      vlan->vid, index);
	}

	if (!vlan || index >= 0) {
		netdev_printk(KERN_DEBUG, ndp->ndev.dev,
			      "no vlan ids left to set\n");
		return -1;
	}

	index = ncsi_add_filter(nc, NCSI_FILTER_VLAN, &vlan->vid);
	if (index < 0) {
		netdev_err(ndp->ndev.dev,
			   "Failed to add new VLAN tag, error %d\n", index);
		if (index == -ENOSPC)
			netdev_err(ndp->ndev.dev,
				   "Channel %u already has all VLAN filters set\n",
				   nc->id);
		return -1;
	}

	netdev_printk(KERN_DEBUG, ndp->ndev.dev,
		      "NCSI: set vid %u in packet, index %u\n",
		      vlan->vid, index + 1);
	nca->type = NCSI_PKT_CMD_SVF;
	nca->words[1] = vlan->vid;
	/* HW filter index starts at 1 */
	nca->bytes[6] = index + 1;
	nca->bytes[7] = 0x01;

	return 0;
}

static void ncsi_configure_channel(struct ncsi_dev_priv *ndp)
{
	struct ncsi_dev *nd = &ndp->ndev;
	struct net_device *dev = nd->dev;
	struct ncsi_package *np = ndp->active_package;
	struct ncsi_channel *nc = ndp->active_channel;
	struct ncsi_channel *hot_nc = NULL;
	struct ncsi_cmd_arg nca;
	unsigned char index;
	unsigned long flags;
	int ret;

	nca.ndp = ndp;
	nca.req_flags = NCSI_REQ_FLAG_EVENT_DRIVEN;
	switch (nd->state) {
	case ncsi_dev_state_config:
	case ncsi_dev_state_config_sp:
		ndp->pending_req_num = 1;

		/* Select the specific package */
		nca.type = NCSI_PKT_CMD_SP;
		if (ndp->flags & NCSI_DEV_HWA)
			nca.bytes[0] = 0;
		else
			nca.bytes[0] = 1;
		nca.package = np->id;
		nca.channel = NCSI_RESERVED_CHANNEL;
		ret = ncsi_xmit_cmd(&nca);
		if (ret) {
			netdev_err(ndp->ndev.dev,
				   "NCSI: Failed to transmit CMD_SP\n");
			goto error;
		}

		nd->state = ncsi_dev_state_config_cis;
		break;
	case ncsi_dev_state_config_cis:
		ndp->pending_req_num = 1;

		/* Clear initial state */
		nca.type = NCSI_PKT_CMD_CIS;
		nca.package = np->id;
		nca.channel = nc->id;
		ret = ncsi_xmit_cmd(&nca);
		if (ret) {
			netdev_err(ndp->ndev.dev,
				   "NCSI: Failed to transmit CMD_CIS\n");
			goto error;
		}

		nd->state = ncsi_dev_state_config_clear_vids;
		break;
	case ncsi_dev_state_config_clear_vids:
	case ncsi_dev_state_config_svf:
	case ncsi_dev_state_config_ev:
	case ncsi_dev_state_config_sma:
	case ncsi_dev_state_config_ebf:
#if IS_ENABLED(CONFIG_IPV6)
	case ncsi_dev_state_config_egmf:
#endif
	case ncsi_dev_state_config_ecnt:
	case ncsi_dev_state_config_ec:
	case ncsi_dev_state_config_ae:
	case ncsi_dev_state_config_gls:
		ndp->pending_req_num = 1;

		nca.package = np->id;
		nca.channel = nc->id;

		/* Clear any active filters on the channel before setting */
		if (nd->state == ncsi_dev_state_config_clear_vids) {
			ret = clear_one_vid(ndp, nc, &nca);
			if (ret) {
				nd->state = ncsi_dev_state_config_svf;
				schedule_work(&ndp->work);
				break;
			}
			/* Repeat */
			nd->state = ncsi_dev_state_config_clear_vids;
		/* Add known VLAN tags to the filter */
		} else if (nd->state == ncsi_dev_state_config_svf) {
			ret = set_one_vid(ndp, nc, &nca);
			if (ret) {
				nd->state = ncsi_dev_state_config_ev;
				schedule_work(&ndp->work);
				break;
			}
			/* Repeat */
			nd->state = ncsi_dev_state_config_svf;
		/* Enable/Disable the VLAN filter */
		} else if (nd->state == ncsi_dev_state_config_ev) {
			if (list_empty(&ndp->vlan_vids)) {
				nca.type = NCSI_PKT_CMD_DV;
			} else {
				nca.type = NCSI_PKT_CMD_EV;
				nca.bytes[3] = NCSI_CAP_VLAN_NO;
			}
			nd->state = ncsi_dev_state_config_sma;
		} else if (nd->state == ncsi_dev_state_config_sma) {
		/* Use first entry in unicast filter table. Note that
		 * the MAC filter table starts from entry 1 instead of
		 * 0.
		 */
			nca.type = NCSI_PKT_CMD_SMA;
			for (index = 0; index < 6; index++)
				nca.bytes[index] = dev->dev_addr[index];
			nca.bytes[6] = 0x1;
			nca.bytes[7] = 0x1;
			nd->state = ncsi_dev_state_config_ebf;
		} else if (nd->state == ncsi_dev_state_config_ebf) {
			nca.type = NCSI_PKT_CMD_EBF;
			nca.dwords[0] = nc->caps[NCSI_CAP_BC].cap;
			nd->state = ncsi_dev_state_config_ecnt;
#if IS_ENABLED(CONFIG_IPV6)
			if (ndp->inet6_addr_num > 0 &&
			    (nc->caps[NCSI_CAP_GENERIC].cap &
			     NCSI_CAP_GENERIC_MC))
				nd->state = ncsi_dev_state_config_egmf;
			else
				nd->state = ncsi_dev_state_config_ecnt;
		} else if (nd->state == ncsi_dev_state_config_egmf) {
			nca.type = NCSI_PKT_CMD_EGMF;
			nca.dwords[0] = nc->caps[NCSI_CAP_MC].cap;
			nd->state = ncsi_dev_state_config_ecnt;
#endif /* CONFIG_IPV6 */
		} else if (nd->state == ncsi_dev_state_config_ecnt) {
			nca.type = NCSI_PKT_CMD_ECNT;
			nd->state = ncsi_dev_state_config_ec;
		} else if (nd->state == ncsi_dev_state_config_ec) {
			/* Enable AEN if it's supported */
			nca.type = NCSI_PKT_CMD_EC;
			nd->state = ncsi_dev_state_config_ae;
			if (!(nc->caps[NCSI_CAP_AEN].cap & NCSI_CAP_AEN_MASK))
				nd->state = ncsi_dev_state_config_gls;
		} else if (nd->state == ncsi_dev_state_config_ae) {
			nca.type = NCSI_PKT_CMD_AE;
			nca.bytes[0] = 0;
			nca.dwords[1] = nc->caps[NCSI_CAP_AEN].cap;
			nd->state = ncsi_dev_state_config_gls;
		} else if (nd->state == ncsi_dev_state_config_gls) {
			nca.type = NCSI_PKT_CMD_GLS;
			nd->state = ncsi_dev_state_config_done;
		}

		ret = ncsi_xmit_cmd(&nca);
		if (ret) {
			netdev_err(ndp->ndev.dev,
				   "NCSI: Failed to transmit CMD %x\n",
				   nca.type);
			goto error;
		}
		break;
	case ncsi_dev_state_config_done:
		netdev_printk(KERN_DEBUG, ndp->ndev.dev,
			      "NCSI: channel %u config done\n", nc->id);
		spin_lock_irqsave(&nc->lock, flags);
		if (nc->reconfigure_needed) {
			/* This channel's configuration has been updated
			 * part-way during the config state - start the
			 * channel configuration over
			 */
			nc->reconfigure_needed = false;
			nc->state = NCSI_CHANNEL_INACTIVE;
			spin_unlock_irqrestore(&nc->lock, flags);

			spin_lock_irqsave(&ndp->lock, flags);
			list_add_tail_rcu(&nc->link, &ndp->channel_queue);
			spin_unlock_irqrestore(&ndp->lock, flags);

			netdev_printk(KERN_DEBUG, dev,
				      "Dirty NCSI channel state reset\n");
			ncsi_process_next_channel(ndp);
			break;
		}

		if (nc->modes[NCSI_MODE_LINK].data[2] & 0x1) {
			hot_nc = nc;
			nc->state = NCSI_CHANNEL_ACTIVE;
		} else {
			hot_nc = NULL;
			nc->state = NCSI_CHANNEL_INACTIVE;
			netdev_warn(ndp->ndev.dev,
				    "NCSI: channel %u link down after config\n",
				    nc->id);
		}
		spin_unlock_irqrestore(&nc->lock, flags);

		/* Update the hot channel */
		spin_lock_irqsave(&ndp->lock, flags);
		ndp->hot_channel = hot_nc;
		spin_unlock_irqrestore(&ndp->lock, flags);

		ncsi_start_channel_monitor(nc);
		ncsi_process_next_channel(ndp);
		break;
	default:
		netdev_alert(dev, "Wrong NCSI state 0x%x in config\n",
			     nd->state);
	}

	return;

error:
	ncsi_report_link(ndp, true);
}

static int ncsi_choose_active_channel(struct ncsi_dev_priv *ndp)
{
	struct ncsi_package *np, *force_package;
	struct ncsi_channel *nc, *found, *hot_nc, *force_channel;
	struct ncsi_channel_mode *ncm;
	unsigned long flags;

	spin_lock_irqsave(&ndp->lock, flags);
	hot_nc = ndp->hot_channel;
	force_channel = ndp->force_channel;
	force_package = ndp->force_package;
	spin_unlock_irqrestore(&ndp->lock, flags);

	/* Force a specific channel whether or not it has link if we have been
	 * configured to do so
	 */
	if (force_package && force_channel) {
		found = force_channel;
		ncm = &found->modes[NCSI_MODE_LINK];
		if (!(ncm->data[2] & 0x1))
			netdev_info(ndp->ndev.dev,
				    "NCSI: Channel %u forced, but it is link down\n",
				    found->id);
		goto out;
	}

	/* The search is done once an inactive channel with up
	 * link is found.
	 */
	found = NULL;
	NCSI_FOR_EACH_PACKAGE(ndp, np) {
		if (ndp->force_package && np != ndp->force_package)
			continue;
		NCSI_FOR_EACH_CHANNEL(np, nc) {
			spin_lock_irqsave(&nc->lock, flags);

			if (!list_empty(&nc->link) ||
			    nc->state != NCSI_CHANNEL_INACTIVE) {
				spin_unlock_irqrestore(&nc->lock, flags);
				continue;
			}

			if (!found)
				found = nc;

			if (nc == hot_nc)
				found = nc;

			ncm = &nc->modes[NCSI_MODE_LINK];
			if (ncm->data[2] & 0x1) {
				spin_unlock_irqrestore(&nc->lock, flags);
				found = nc;
				goto out;
			}

			spin_unlock_irqrestore(&nc->lock, flags);
		}
	}

	if (!found) {
		netdev_warn(ndp->ndev.dev,
			    "NCSI: No channel found with link\n");
		ncsi_report_link(ndp, true);
		return -ENODEV;
	}

	ncm = &found->modes[NCSI_MODE_LINK];
	netdev_printk(KERN_DEBUG, ndp->ndev.dev,
		      "NCSI: Channel %u added to queue (link %s)\n",
		      found->id, ncm->data[2] & 0x1 ? "up" : "down");

out:
	spin_lock_irqsave(&ndp->lock, flags);
	list_add_tail_rcu(&found->link, &ndp->channel_queue);
	spin_unlock_irqrestore(&ndp->lock, flags);

	return ncsi_process_next_channel(ndp);
}

static bool ncsi_check_hwa(struct ncsi_dev_priv *ndp)
{
	struct ncsi_package *np;
	struct ncsi_channel *nc;
	unsigned int cap;
	bool has_channel = false;

	/* The hardware arbitration is disabled if any one channel
	 * doesn't support explicitly.
	 */
	NCSI_FOR_EACH_PACKAGE(ndp, np) {
		NCSI_FOR_EACH_CHANNEL(np, nc) {
			has_channel = true;

			cap = nc->caps[NCSI_CAP_GENERIC].cap;
			if (!(cap & NCSI_CAP_GENERIC_HWA) ||
			    (cap & NCSI_CAP_GENERIC_HWA_MASK) !=
			    NCSI_CAP_GENERIC_HWA_SUPPORT) {
				ndp->flags &= ~NCSI_DEV_HWA;
				return false;
			}
		}
	}

	if (has_channel) {
		ndp->flags |= NCSI_DEV_HWA;
		return true;
	}

	ndp->flags &= ~NCSI_DEV_HWA;
	return false;
}

static int ncsi_enable_hwa(struct ncsi_dev_priv *ndp)
{
	struct ncsi_package *np;
	struct ncsi_channel *nc;
	unsigned long flags;

	/* Move all available channels to processing queue */
	spin_lock_irqsave(&ndp->lock, flags);
	NCSI_FOR_EACH_PACKAGE(ndp, np) {
		NCSI_FOR_EACH_CHANNEL(np, nc) {
			WARN_ON_ONCE(nc->state != NCSI_CHANNEL_INACTIVE ||
				     !list_empty(&nc->link));
			ncsi_stop_channel_monitor(nc);
			list_add_tail_rcu(&nc->link, &ndp->channel_queue);
		}
	}
	spin_unlock_irqrestore(&ndp->lock, flags);

	/* We can have no channels in extremely case */
	if (list_empty(&ndp->channel_queue)) {
		netdev_err(ndp->ndev.dev,
			   "NCSI: No available channels for HWA\n");
		ncsi_report_link(ndp, false);
		return -ENOENT;
	}

	return ncsi_process_next_channel(ndp);
}

static void ncsi_probe_channel(struct ncsi_dev_priv *ndp)
{
	struct ncsi_dev *nd = &ndp->ndev;
	struct ncsi_package *np;
	struct ncsi_channel *nc;
	struct ncsi_cmd_arg nca;
	unsigned char index;
	int ret;

	nca.ndp = ndp;
	nca.req_flags = NCSI_REQ_FLAG_EVENT_DRIVEN;
	switch (nd->state) {
	case ncsi_dev_state_probe:
		nd->state = ncsi_dev_state_probe_deselect;
		/* Fall through */
	case ncsi_dev_state_probe_deselect:
		ndp->pending_req_num = 8;

		/* Deselect all possible packages */
		nca.type = NCSI_PKT_CMD_DP;
		nca.channel = NCSI_RESERVED_CHANNEL;
		for (index = 0; index < 8; index++) {
			nca.package = index;
			ret = ncsi_xmit_cmd(&nca);
			if (ret)
				goto error;
		}

		nd->state = ncsi_dev_state_probe_package;
		break;
	case ncsi_dev_state_probe_package:
		ndp->pending_req_num = 16;

		/* Select all possible packages */
		nca.type = NCSI_PKT_CMD_SP;
		nca.bytes[0] = 1;
		nca.channel = NCSI_RESERVED_CHANNEL;
		for (index = 0; index < 8; index++) {
			nca.package = index;
			ret = ncsi_xmit_cmd(&nca);
			if (ret)
				goto error;
		}

		/* Disable all possible packages */
		nca.type = NCSI_PKT_CMD_DP;
		for (index = 0; index < 8; index++) {
			nca.package = index;
			ret = ncsi_xmit_cmd(&nca);
			if (ret)
				goto error;
		}

		nd->state = ncsi_dev_state_probe_channel;
		break;
	case ncsi_dev_state_probe_channel:
		if (!ndp->active_package)
			ndp->active_package = list_first_or_null_rcu(
				&ndp->packages, struct ncsi_package, node);
		else if (list_is_last(&ndp->active_package->node,
				      &ndp->packages))
			ndp->active_package = NULL;
		else
			ndp->active_package = list_next_entry(
				ndp->active_package, node);

		/* All available packages and channels are enumerated. The
		 * enumeration happens for once when the NCSI interface is
		 * started. So we need continue to start the interface after
		 * the enumeration.
		 *
		 * We have to choose an active channel before configuring it.
		 * Note that we possibly don't have active channel in extreme
		 * situation.
		 */
		if (!ndp->active_package) {
			ndp->flags |= NCSI_DEV_PROBED;
			if (ncsi_check_hwa(ndp))
				ncsi_enable_hwa(ndp);
			else
				ncsi_choose_active_channel(ndp);
			return;
		}

		/* Select the active package */
		ndp->pending_req_num = 1;
		nca.type = NCSI_PKT_CMD_SP;
		nca.bytes[0] = 1;
		nca.package = ndp->active_package->id;
		nca.channel = NCSI_RESERVED_CHANNEL;
		ret = ncsi_xmit_cmd(&nca);
		if (ret)
			goto error;

		nd->state = ncsi_dev_state_probe_cis;
		break;
	case ncsi_dev_state_probe_cis:
		ndp->pending_req_num = NCSI_RESERVED_CHANNEL;

		/* Clear initial state */
		nca.type = NCSI_PKT_CMD_CIS;
		nca.package = ndp->active_package->id;
		for (index = 0; index < NCSI_RESERVED_CHANNEL; index++) {
			nca.channel = index;
			ret = ncsi_xmit_cmd(&nca);
			if (ret)
				goto error;
		}

		nd->state = ncsi_dev_state_probe_gvi;
		break;
	case ncsi_dev_state_probe_gvi:
	case ncsi_dev_state_probe_gc:
	case ncsi_dev_state_probe_gls:
		np = ndp->active_package;
		ndp->pending_req_num = np->channel_num;

		/* Retrieve version, capability or link status */
		if (nd->state == ncsi_dev_state_probe_gvi)
			nca.type = NCSI_PKT_CMD_GVI;
		else if (nd->state == ncsi_dev_state_probe_gc)
			nca.type = NCSI_PKT_CMD_GC;
		else
			nca.type = NCSI_PKT_CMD_GLS;

		nca.package = np->id;
		NCSI_FOR_EACH_CHANNEL(np, nc) {
			nca.channel = nc->id;
			ret = ncsi_xmit_cmd(&nca);
			if (ret)
				goto error;
		}

		if (nd->state == ncsi_dev_state_probe_gvi)
			nd->state = ncsi_dev_state_probe_gc;
		else if (nd->state == ncsi_dev_state_probe_gc)
			nd->state = ncsi_dev_state_probe_gls;
		else
			nd->state = ncsi_dev_state_probe_dp;
		break;
	case ncsi_dev_state_probe_dp:
		ndp->pending_req_num = 1;

		/* Deselect the active package */
		nca.type = NCSI_PKT_CMD_DP;
		nca.package = ndp->active_package->id;
		nca.channel = NCSI_RESERVED_CHANNEL;
		ret = ncsi_xmit_cmd(&nca);
		if (ret)
			goto error;

		/* Scan channels in next package */
		nd->state = ncsi_dev_state_probe_channel;
		break;
	default:
		netdev_warn(nd->dev, "Wrong NCSI state 0x%0x in enumeration\n",
			    nd->state);
	}

	return;
error:
	netdev_err(ndp->ndev.dev,
		   "NCSI: Failed to transmit cmd 0x%x during probe\n",
		   nca.type);
	ncsi_report_link(ndp, true);
}

static void ncsi_dev_work(struct work_struct *work)
{
	struct ncsi_dev_priv *ndp = container_of(work,
			struct ncsi_dev_priv, work);
	struct ncsi_dev *nd = &ndp->ndev;

	switch (nd->state & ncsi_dev_state_major) {
	case ncsi_dev_state_probe:
		ncsi_probe_channel(ndp);
		break;
	case ncsi_dev_state_suspend:
		ncsi_suspend_channel(ndp);
		break;
	case ncsi_dev_state_config:
		ncsi_configure_channel(ndp);
		break;
	default:
		netdev_warn(nd->dev, "Wrong NCSI state 0x%x in workqueue\n",
			    nd->state);
	}
}

int ncsi_process_next_channel(struct ncsi_dev_priv *ndp)
{
	struct ncsi_channel *nc;
	int old_state;
	unsigned long flags;

	spin_lock_irqsave(&ndp->lock, flags);
	nc = list_first_or_null_rcu(&ndp->channel_queue,
				    struct ncsi_channel, link);
	if (!nc) {
		spin_unlock_irqrestore(&ndp->lock, flags);
		goto out;
	}

	list_del_init(&nc->link);
	spin_unlock_irqrestore(&ndp->lock, flags);

	spin_lock_irqsave(&nc->lock, flags);
	old_state = nc->state;
	nc->state = NCSI_CHANNEL_INVISIBLE;
	spin_unlock_irqrestore(&nc->lock, flags);

	ndp->active_channel = nc;
	ndp->active_package = nc->package;

	switch (old_state) {
	case NCSI_CHANNEL_INACTIVE:
		ndp->ndev.state = ncsi_dev_state_config;
		netdev_info(ndp->ndev.dev, "NCSI: configuring channel %u\n",
			    nc->id);
		ncsi_configure_channel(ndp);
		break;
	case NCSI_CHANNEL_ACTIVE:
		ndp->ndev.state = ncsi_dev_state_suspend;
		netdev_info(ndp->ndev.dev, "NCSI: suspending channel %u\n",
			    nc->id);
		ncsi_suspend_channel(ndp);
		break;
	default:
		netdev_err(ndp->ndev.dev, "Invalid state 0x%x on %d:%d\n",
			   old_state, nc->package->id, nc->id);
		ncsi_report_link(ndp, false);
		return -EINVAL;
	}

	return 0;

out:
	ndp->active_channel = NULL;
	ndp->active_package = NULL;
	if (ndp->flags & NCSI_DEV_RESHUFFLE) {
		ndp->flags &= ~NCSI_DEV_RESHUFFLE;
		return ncsi_choose_active_channel(ndp);
	}

	netdev_printk(KERN_DEBUG, ndp->ndev.dev,
		      "NCSI: No more channels to process\n");
	ncsi_report_link(ndp, false);
	return -ENODEV;
}

#if IS_ENABLED(CONFIG_IPV6)
static int ncsi_inet6addr_event(struct notifier_block *this,
				unsigned long event, void *data)
{
	struct inet6_ifaddr *ifa = data;
	struct net_device *dev = ifa->idev->dev;
	struct ncsi_dev *nd = ncsi_find_dev(dev);
	struct ncsi_dev_priv *ndp = nd ? TO_NCSI_DEV_PRIV(nd) : NULL;
	struct ncsi_package *np;
	struct ncsi_channel *nc;
	struct ncsi_cmd_arg nca;
	bool action;
	int ret;

	if (!ndp || (ipv6_addr_type(&ifa->addr) &
	    (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK)))
		return NOTIFY_OK;

	switch (event) {
	case NETDEV_UP:
		action = (++ndp->inet6_addr_num) == 1;
		nca.type = NCSI_PKT_CMD_EGMF;
		break;
	case NETDEV_DOWN:
		action = (--ndp->inet6_addr_num == 0);
		nca.type = NCSI_PKT_CMD_DGMF;
		break;
	default:
		return NOTIFY_OK;
	}

	/* We might not have active channel or packages. The IPv6
	 * required multicast will be enabled when active channel
	 * or packages are chosen.
	 */
	np = ndp->active_package;
	nc = ndp->active_channel;
	if (!action || !np || !nc)
		return NOTIFY_OK;

	/* We needn't enable or disable it if the function isn't supported */
	if (!(nc->caps[NCSI_CAP_GENERIC].cap & NCSI_CAP_GENERIC_MC))
		return NOTIFY_OK;

	nca.ndp = ndp;
	nca.req_flags = 0;
	nca.package = np->id;
	nca.channel = nc->id;
	nca.dwords[0] = nc->caps[NCSI_CAP_MC].cap;
	ret = ncsi_xmit_cmd(&nca);
	if (ret) {
		netdev_warn(dev, "Fail to %s global multicast filter (%d)\n",
			    (event == NETDEV_UP) ? "enable" : "disable", ret);
		return NOTIFY_DONE;
	}

	return NOTIFY_OK;
}

static struct notifier_block ncsi_inet6addr_notifier = {
	.notifier_call = ncsi_inet6addr_event,
};
#endif /* CONFIG_IPV6 */

static int ncsi_kick_channels(struct ncsi_dev_priv *ndp)
{
	struct ncsi_dev *nd = &ndp->ndev;
	struct ncsi_channel *nc;
	struct ncsi_package *np;
	unsigned long flags;
	unsigned int n = 0;

	NCSI_FOR_EACH_PACKAGE(ndp, np) {
		NCSI_FOR_EACH_CHANNEL(np, nc) {
			spin_lock_irqsave(&nc->lock, flags);

			/* Channels may be busy, mark dirty instead of
			 * kicking if;
			 * a) not ACTIVE (configured)
			 * b) in the channel_queue (to be configured)
			 * c) it's ndev is in the config state
			 */
			if (nc->state != NCSI_CHANNEL_ACTIVE) {
				if ((ndp->ndev.state & 0xff00) ==
						ncsi_dev_state_config ||
						!list_empty(&nc->link)) {
					netdev_printk(KERN_DEBUG, nd->dev,
						      "NCSI: channel %p marked dirty\n",
						      nc);
					nc->reconfigure_needed = true;
				}
				spin_unlock_irqrestore(&nc->lock, flags);
				continue;
			}

			spin_unlock_irqrestore(&nc->lock, flags);

			ncsi_stop_channel_monitor(nc);
			spin_lock_irqsave(&nc->lock, flags);
			nc->state = NCSI_CHANNEL_INACTIVE;
			spin_unlock_irqrestore(&nc->lock, flags);

			spin_lock_irqsave(&ndp->lock, flags);
			list_add_tail_rcu(&nc->link, &ndp->channel_queue);
			spin_unlock_irqrestore(&ndp->lock, flags);

			netdev_printk(KERN_DEBUG, nd->dev,
				      "NCSI: kicked channel %p\n", nc);
			n++;
		}
	}

	return n;
}

int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)
{
	struct ncsi_dev_priv *ndp;
	unsigned int n_vids = 0;
	struct vlan_vid *vlan;
	struct ncsi_dev *nd;
	bool found = false;

	if (vid == 0)
		return 0;

	nd = ncsi_find_dev(dev);
	if (!nd) {
		netdev_warn(dev, "NCSI: No net_device?\n");
		return 0;
	}

	ndp = TO_NCSI_DEV_PRIV(nd);

	/* Add the VLAN id to our internal list */
	list_for_each_entry_rcu(vlan, &ndp->vlan_vids, list) {
		n_vids++;
		if (vlan->vid == vid) {
			netdev_printk(KERN_DEBUG, dev,
				      "NCSI: vid %u already registered\n", vid);
			return 0;
		}
	}
	if (n_vids >= NCSI_MAX_VLAN_VIDS) {
		netdev_warn(dev,
			    "tried to add vlan id %u but NCSI max already registered (%u)\n",
			    vid, NCSI_MAX_VLAN_VIDS);
		return -ENOSPC;
	}

	vlan = kzalloc(sizeof(*vlan), GFP_KERNEL);
	if (!vlan)
		return -ENOMEM;

	vlan->proto = proto;
	vlan->vid = vid;
	list_add_rcu(&vlan->list, &ndp->vlan_vids);

	netdev_printk(KERN_DEBUG, dev, "NCSI: Added new vid %u\n", vid);

	found = ncsi_kick_channels(ndp) != 0;

	return found ? ncsi_process_next_channel(ndp) : 0;
}
EXPORT_SYMBOL_GPL(ncsi_vlan_rx_add_vid);

int ncsi_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid)
{
	struct vlan_vid *vlan, *tmp;
	struct ncsi_dev_priv *ndp;
	struct ncsi_dev *nd;
	bool found = false;

	if (vid == 0)
		return 0;

	nd = ncsi_find_dev(dev);
	if (!nd) {
		netdev_warn(dev, "NCSI: no net_device?\n");
		return 0;
	}

	ndp = TO_NCSI_DEV_PRIV(nd);

	/* Remove the VLAN id from our internal list */
	list_for_each_entry_safe(vlan, tmp, &ndp->vlan_vids, list)
		if (vlan->vid == vid) {
			netdev_printk(KERN_DEBUG, dev,
				      "NCSI: vid %u found, removing\n", vid);
			list_del_rcu(&vlan->list);
			found = true;
			kfree(vlan);
		}

	if (!found) {
		netdev_err(dev, "NCSI: vid %u wasn't registered!\n", vid);
		return -EINVAL;
	}

	found = ncsi_kick_channels(ndp) != 0;

	return found ? ncsi_process_next_channel(ndp) : 0;
}
EXPORT_SYMBOL_GPL(ncsi_vlan_rx_kill_vid);

struct ncsi_dev *ncsi_register_dev(struct net_device *dev,
				   void (*handler)(struct ncsi_dev *ndev))
{
	struct ncsi_dev_priv *ndp;
	struct ncsi_dev *nd;
	unsigned long flags;
	int i;

	/* Check if the device has been registered or not */
	nd = ncsi_find_dev(dev);
	if (nd)
		return nd;

	/* Create NCSI device */
	ndp = kzalloc(sizeof(*ndp), GFP_ATOMIC);
	if (!ndp)
		return NULL;

	nd = &ndp->ndev;
	nd->state = ncsi_dev_state_registered;
	nd->dev = dev;
	nd->handler = handler;
	ndp->pending_req_num = 0;
	INIT_LIST_HEAD(&ndp->channel_queue);
	INIT_LIST_HEAD(&ndp->vlan_vids);
	INIT_WORK(&ndp->work, ncsi_dev_work);

	/* Initialize private NCSI device */
	spin_lock_init(&ndp->lock);
	INIT_LIST_HEAD(&ndp->packages);
	ndp->request_id = NCSI_REQ_START_IDX;
	for (i = 0; i < ARRAY_SIZE(ndp->requests); i++) {
		ndp->requests[i].id = i;
		ndp->requests[i].ndp = ndp;
		timer_setup(&ndp->requests[i].timer, ncsi_request_timeout, 0);
	}

	spin_lock_irqsave(&ncsi_dev_lock, flags);
#if IS_ENABLED(CONFIG_IPV6)
	ndp->inet6_addr_num = 0;
	if (list_empty(&ncsi_dev_list))
		register_inet6addr_notifier(&ncsi_inet6addr_notifier);
#endif
	list_add_tail_rcu(&ndp->node, &ncsi_dev_list);
	spin_unlock_irqrestore(&ncsi_dev_lock, flags);

	/* Register NCSI packet Rx handler */
	ndp->ptype.type = cpu_to_be16(ETH_P_NCSI);
	ndp->ptype.func = ncsi_rcv_rsp;
	ndp->ptype.dev = dev;
	dev_add_pack(&ndp->ptype);

	/* Set up generic netlink interface */
	ncsi_init_netlink(dev);

	return nd;
}
EXPORT_SYMBOL_GPL(ncsi_register_dev);

int ncsi_start_dev(struct ncsi_dev *nd)
{
	struct ncsi_dev_priv *ndp = TO_NCSI_DEV_PRIV(nd);
	int ret;

	if (nd->state != ncsi_dev_state_registered &&
	    nd->state != ncsi_dev_state_functional)
		return -ENOTTY;

	if (!(ndp->flags & NCSI_DEV_PROBED)) {
		nd->state = ncsi_dev_state_probe;
		schedule_work(&ndp->work);
		return 0;
	}

	if (ndp->flags & NCSI_DEV_HWA) {
		netdev_info(ndp->ndev.dev, "NCSI: Enabling HWA mode\n");
		ret = ncsi_enable_hwa(ndp);
	} else {
		ret = ncsi_choose_active_channel(ndp);
	}

	return ret;
}
EXPORT_SYMBOL_GPL(ncsi_start_dev);

void ncsi_stop_dev(struct ncsi_dev *nd)
{
	struct ncsi_dev_priv *ndp = TO_NCSI_DEV_PRIV(nd);
	struct ncsi_package *np;
	struct ncsi_channel *nc;
	bool chained;
	int old_state;
	unsigned long flags;

	/* Stop the channel monitor and reset channel's state */
	NCSI_FOR_EACH_PACKAGE(ndp, np) {
		NCSI_FOR_EACH_CHANNEL(np, nc) {
			ncsi_stop_channel_monitor(nc);

			spin_lock_irqsave(&nc->lock, flags);
			chained = !list_empty(&nc->link);
			old_state = nc->state;
			nc->state = NCSI_CHANNEL_INACTIVE;
			spin_unlock_irqrestore(&nc->lock, flags);

			WARN_ON_ONCE(chained ||
				     old_state == NCSI_CHANNEL_INVISIBLE);
		}
	}

	netdev_printk(KERN_DEBUG, ndp->ndev.dev, "NCSI: Stopping device\n");
	ncsi_report_link(ndp, true);
}
EXPORT_SYMBOL_GPL(ncsi_stop_dev);

void ncsi_unregister_dev(struct ncsi_dev *nd)
{
	struct ncsi_dev_priv *ndp = TO_NCSI_DEV_PRIV(nd);
	struct ncsi_package *np, *tmp;
	unsigned long flags;

	dev_remove_pack(&ndp->ptype);

	list_for_each_entry_safe(np, tmp, &ndp->packages, node)
		ncsi_remove_package(np);

	spin_lock_irqsave(&ncsi_dev_lock, flags);
	list_del_rcu(&ndp->node);
#if IS_ENABLED(CONFIG_IPV6)
	if (list_empty(&ncsi_dev_list))
		unregister_inet6addr_notifier(&ncsi_inet6addr_notifier);
#endif
	spin_unlock_irqrestore(&ncsi_dev_lock, flags);

	ncsi_unregister_netlink(nd->dev);

	kfree(ndp);
}
EXPORT_SYMBOL_GPL(ncsi_unregister_dev);
