/*
 * 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 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;
	unsigned long flags;

	spin_lock_irqsave(&nc->lock, flags);

	/* Release filters */
	kfree(nc->mac_filter.addrs);
	kfree(nc->vlan_filter.vids);

	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)
{
	struct ncsi_channel_vlan_filter *ncf;
	unsigned long flags;
	void *bitmap;
	int index;
	u16 vid;

	ncf = &nc->vlan_filter;
	bitmap = &ncf->bitmap;

	spin_lock_irqsave(&nc->lock, flags);
	index = find_next_bit(bitmap, ncf->n_vids, 0);
	if (index >= ncf->n_vids) {
		spin_unlock_irqrestore(&nc->lock, flags);
		return -1;
	}
	vid = ncf->vids[index];

	clear_bit(index, bitmap);
	ncf->vids[index] = 0;
	spin_unlock_irqrestore(&nc->lock, flags);

	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 ncsi_channel_vlan_filter *ncf;
	struct vlan_vid *vlan = NULL;
	unsigned long flags;
	int i, index;
	void *bitmap;
	u16 vid;

	if (list_empty(&ndp->vlan_vids))
		return -1;

	ncf = &nc->vlan_filter;
	bitmap = &ncf->bitmap;

	spin_lock_irqsave(&nc->lock, flags);

	rcu_read_lock();
	list_for_each_entry_rcu(vlan, &ndp->vlan_vids, list) {
		vid = vlan->vid;
		for (i = 0; i < ncf->n_vids; i++)
			if (ncf->vids[i] == vid) {
				vid = 0;
				break;
			}
		if (vid)
			break;
	}
	rcu_read_unlock();

	if (!vid) {
		/* No VLAN ID is not set */
		spin_unlock_irqrestore(&nc->lock, flags);
		return -1;
	}

	index = find_next_zero_bit(bitmap, ncf->n_vids, 0);
	if (index < 0 || index >= ncf->n_vids) {
		netdev_err(ndp->ndev.dev,
			   "Channel %u already has all VLAN filters set\n",
			   nc->id);
		spin_unlock_irqrestore(&nc->lock, flags);
		return -1;
	}

	ncf->vids[index] = vid;
	set_bit(index, bitmap);
	spin_unlock_irqrestore(&nc->lock, flags);

	nca->type = NCSI_PKT_CMD_SVF;
	nca->words[1] = 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_dbg(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_dbg(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_dbg(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_dbg(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_dbg(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_dbg(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);
	}

	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_dbg(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_dbg(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_dbg(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_dbg(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_dbg(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_dbg(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);
