// SPDX-License-Identifier: GPL-2.0
/*
 * Management Controller Transport Protocol (MCTP)
 * Implements DMTF specification
 * "DSP0237 Management Component Transport Protocol (MCTP) SMBus/I2C
 * Transport Binding"
 * https://www.dmtf.org/sites/default/files/standards/documents/DSP0237_1.2.0.pdf
 *
 * A netdev is created for each I2C bus that handles MCTP. In the case of an I2C
 * mux topology a single I2C client is attached to the root of the mux topology,
 * shared between all mux I2C busses underneath. For non-mux cases an I2C client
 * is attached per netdev.
 *
 * mctp-i2c-controller.yml devicetree binding has further details.
 *
 * Copyright (c) 2022 Code Construct
 * Copyright (c) 2022 Google
 */

#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/if_arp.h>
#include <net/mctp.h>
#include <net/mctpdevice.h>

/* byte_count is limited to u8 */
#define MCTP_I2C_MAXBLOCK 255
/* One byte is taken by source_slave */
#define MCTP_I2C_MAXMTU (MCTP_I2C_MAXBLOCK - 1)
#define MCTP_I2C_MINMTU (64 + 4)
/* Allow space for dest_address, command, byte_count, data, PEC */
#define MCTP_I2C_BUFSZ (3 + MCTP_I2C_MAXBLOCK + 1)
#define MCTP_I2C_MINLEN 8
#define MCTP_I2C_COMMANDCODE 0x0f
#define MCTP_I2C_TX_WORK_LEN 100
/* Sufficient for 64kB at min mtu */
#define MCTP_I2C_TX_QUEUE_LEN 1100

#define MCTP_I2C_OF_PROP "mctp-controller"

enum {
	MCTP_I2C_FLOW_STATE_NEW = 0,
	MCTP_I2C_FLOW_STATE_ACTIVE,
	MCTP_I2C_FLOW_STATE_INVALID,
};

/* List of all struct mctp_i2c_client
 * Lock protects driver_clients and also prevents adding/removing adapters
 * during mctp_i2c_client probe/remove.
 */
static DEFINE_MUTEX(driver_clients_lock);
static LIST_HEAD(driver_clients);

struct mctp_i2c_client;

/* The netdev structure. One of these per I2C adapter. */
struct mctp_i2c_dev {
	struct net_device *ndev;
	struct i2c_adapter *adapter;
	struct mctp_i2c_client *client;
	struct list_head list; /* For mctp_i2c_client.devs */

	size_t rx_pos;
	u8 rx_buffer[MCTP_I2C_BUFSZ];
	struct completion rx_done;

	struct task_struct *tx_thread;
	wait_queue_head_t tx_wq;
	struct sk_buff_head tx_queue;
	u8 tx_scratch[MCTP_I2C_BUFSZ];

	/* A fake entry in our tx queue to perform an unlock operation */
	struct sk_buff unlock_marker;

	/* Spinlock protects i2c_lock_count, release_count, allow_rx */
	spinlock_t lock;
	int i2c_lock_count;
	int release_count;
	/* Indicates that the netif is ready to receive incoming packets */
	bool allow_rx;

};

/* The i2c client structure. One per hardware i2c bus at the top of the
 * mux tree, shared by multiple netdevs
 */
struct mctp_i2c_client {
	struct i2c_client *client;
	u8 lladdr;

	struct mctp_i2c_dev *sel;
	struct list_head devs;
	spinlock_t sel_lock; /* Protects sel and devs */

	struct list_head list; /* For driver_clients */
};

/* Header on the wire. */
struct mctp_i2c_hdr {
	u8 dest_slave;
	u8 command;
	/* Count of bytes following byte_count, excluding PEC */
	u8 byte_count;
	u8 source_slave;
};

static int mctp_i2c_recv(struct mctp_i2c_dev *midev);
static int mctp_i2c_slave_cb(struct i2c_client *client,
			     enum i2c_slave_event event, u8 *val);
static void mctp_i2c_ndo_uninit(struct net_device *dev);
static int mctp_i2c_ndo_open(struct net_device *dev);

static struct i2c_adapter *mux_root_adapter(struct i2c_adapter *adap)
{
#if IS_ENABLED(CONFIG_I2C_MUX)
	return i2c_root_adapter(&adap->dev);
#else
	/* In non-mux config all i2c adapters are root adapters */
	return adap;
#endif
}

/* Creates a new i2c slave device attached to the root adapter.
 * Sets up the slave callback.
 * Must be called with a client on a root adapter.
 */
static struct mctp_i2c_client *mctp_i2c_new_client(struct i2c_client *client)
{
	struct mctp_i2c_client *mcli = NULL;
	struct i2c_adapter *root = NULL;
	int rc;

	if (client->flags & I2C_CLIENT_TEN) {
		dev_err(&client->dev, "failed, MCTP requires a 7-bit I2C address, addr=0x%x\n",
			client->addr);
		rc = -EINVAL;
		goto err;
	}

	root = mux_root_adapter(client->adapter);
	if (!root) {
		dev_err(&client->dev, "failed to find root adapter\n");
		rc = -ENOENT;
		goto err;
	}
	if (root != client->adapter) {
		dev_err(&client->dev,
			"A mctp-i2c-controller client cannot be placed on an I2C mux adapter.\n"
			" It should be placed on the mux tree root adapter\n"
			" then set mctp-controller property on adapters to attach\n");
		rc = -EINVAL;
		goto err;
	}

	mcli = kzalloc(sizeof(*mcli), GFP_KERNEL);
	if (!mcli) {
		rc = -ENOMEM;
		goto err;
	}
	spin_lock_init(&mcli->sel_lock);
	INIT_LIST_HEAD(&mcli->devs);
	INIT_LIST_HEAD(&mcli->list);
	mcli->lladdr = client->addr & 0xff;
	mcli->client = client;
	i2c_set_clientdata(client, mcli);

	rc = i2c_slave_register(mcli->client, mctp_i2c_slave_cb);
	if (rc < 0) {
		dev_err(&client->dev, "i2c register failed %d\n", rc);
		mcli->client = NULL;
		i2c_set_clientdata(client, NULL);
		goto err;
	}

	return mcli;
err:
	if (mcli) {
		if (mcli->client)
			i2c_unregister_device(mcli->client);
		kfree(mcli);
	}
	return ERR_PTR(rc);
}

static void mctp_i2c_free_client(struct mctp_i2c_client *mcli)
{
	int rc;

	WARN_ON(!mutex_is_locked(&driver_clients_lock));
	WARN_ON(!list_empty(&mcli->devs));
	WARN_ON(mcli->sel); /* sanity check, no locking */

	rc = i2c_slave_unregister(mcli->client);
	/* Leak if it fails, we can't propagate errors upwards */
	if (rc < 0)
		dev_err(&mcli->client->dev, "i2c unregister failed %d\n", rc);
	else
		kfree(mcli);
}

/* Switch the mctp i2c device to receive responses.
 * Call with sel_lock held
 */
static void __mctp_i2c_device_select(struct mctp_i2c_client *mcli,
				     struct mctp_i2c_dev *midev)
{
	assert_spin_locked(&mcli->sel_lock);
	if (midev)
		dev_hold(midev->ndev);
	if (mcli->sel)
		dev_put(mcli->sel->ndev);
	mcli->sel = midev;
}

/* Switch the mctp i2c device to receive responses */
static void mctp_i2c_device_select(struct mctp_i2c_client *mcli,
				   struct mctp_i2c_dev *midev)
{
	unsigned long flags;

	spin_lock_irqsave(&mcli->sel_lock, flags);
	__mctp_i2c_device_select(mcli, midev);
	spin_unlock_irqrestore(&mcli->sel_lock, flags);
}

static int mctp_i2c_slave_cb(struct i2c_client *client,
			     enum i2c_slave_event event, u8 *val)
{
	struct mctp_i2c_client *mcli = i2c_get_clientdata(client);
	struct mctp_i2c_dev *midev = NULL;
	unsigned long flags;
	int rc = 0;

	spin_lock_irqsave(&mcli->sel_lock, flags);
	midev = mcli->sel;
	if (midev)
		dev_hold(midev->ndev);
	spin_unlock_irqrestore(&mcli->sel_lock, flags);

	if (!midev)
		return 0;

	switch (event) {
	case I2C_SLAVE_WRITE_RECEIVED:
		if (midev->rx_pos < MCTP_I2C_BUFSZ) {
			midev->rx_buffer[midev->rx_pos] = *val;
			midev->rx_pos++;
		} else {
			midev->ndev->stats.rx_over_errors++;
		}

		break;
	case I2C_SLAVE_WRITE_REQUESTED:
		/* dest_slave as first byte */
		midev->rx_buffer[0] = mcli->lladdr << 1;
		midev->rx_pos = 1;
		break;
	case I2C_SLAVE_STOP:
		rc = mctp_i2c_recv(midev);
		break;
	default:
		break;
	}

	dev_put(midev->ndev);
	return rc;
}

/* Processes incoming data that has been accumulated by the slave cb */
static int mctp_i2c_recv(struct mctp_i2c_dev *midev)
{
	struct net_device *ndev = midev->ndev;
	struct mctp_i2c_hdr *hdr;
	struct mctp_skb_cb *cb;
	struct sk_buff *skb;
	unsigned long flags;
	u8 pec, calc_pec;
	size_t recvlen;
	int status;

	/* + 1 for the PEC */
	if (midev->rx_pos < MCTP_I2C_MINLEN + 1) {
		ndev->stats.rx_length_errors++;
		return -EINVAL;
	}
	/* recvlen excludes PEC */
	recvlen = midev->rx_pos - 1;

	hdr = (void *)midev->rx_buffer;
	if (hdr->command != MCTP_I2C_COMMANDCODE) {
		ndev->stats.rx_dropped++;
		return -EINVAL;
	}

	if (hdr->byte_count + offsetof(struct mctp_i2c_hdr, source_slave) != recvlen) {
		ndev->stats.rx_length_errors++;
		return -EINVAL;
	}

	pec = midev->rx_buffer[midev->rx_pos - 1];
	calc_pec = i2c_smbus_pec(0, midev->rx_buffer, recvlen);
	if (pec != calc_pec) {
		ndev->stats.rx_crc_errors++;
		return -EINVAL;
	}

	skb = netdev_alloc_skb(ndev, recvlen);
	if (!skb) {
		ndev->stats.rx_dropped++;
		return -ENOMEM;
	}

	skb->protocol = htons(ETH_P_MCTP);
	skb_put_data(skb, midev->rx_buffer, recvlen);
	skb_reset_mac_header(skb);
	skb_pull(skb, sizeof(struct mctp_i2c_hdr));
	skb_reset_network_header(skb);

	cb = __mctp_cb(skb);
	cb->halen = 1;
	cb->haddr[0] = hdr->source_slave >> 1;

	/* We need to ensure that the netif is not used once netdev
	 * unregister occurs
	 */
	spin_lock_irqsave(&midev->lock, flags);
	if (midev->allow_rx) {
		reinit_completion(&midev->rx_done);
		spin_unlock_irqrestore(&midev->lock, flags);

		status = netif_rx(skb);
		complete(&midev->rx_done);
	} else {
		status = NET_RX_DROP;
		spin_unlock_irqrestore(&midev->lock, flags);
	}

	if (status == NET_RX_SUCCESS) {
		ndev->stats.rx_packets++;
		ndev->stats.rx_bytes += recvlen;
	} else {
		ndev->stats.rx_dropped++;
	}
	return 0;
}

enum mctp_i2c_flow_state {
	MCTP_I2C_TX_FLOW_INVALID,
	MCTP_I2C_TX_FLOW_NONE,
	MCTP_I2C_TX_FLOW_NEW,
	MCTP_I2C_TX_FLOW_EXISTING,
};

static enum mctp_i2c_flow_state
mctp_i2c_get_tx_flow_state(struct mctp_i2c_dev *midev, struct sk_buff *skb)
{
	enum mctp_i2c_flow_state state;
	struct mctp_sk_key *key;
	struct mctp_flow *flow;
	unsigned long flags;

	flow = skb_ext_find(skb, SKB_EXT_MCTP);
	if (!flow)
		return MCTP_I2C_TX_FLOW_NONE;

	key = flow->key;
	if (!key)
		return MCTP_I2C_TX_FLOW_NONE;

	spin_lock_irqsave(&key->lock, flags);
	/* If the key is present but invalid, we're unlikely to be able
	 * to handle the flow at all; just drop now
	 */
	if (!key->valid) {
		state = MCTP_I2C_TX_FLOW_INVALID;
	} else {
		switch (key->dev_flow_state) {
		case MCTP_I2C_FLOW_STATE_NEW:
			key->dev_flow_state = MCTP_I2C_FLOW_STATE_ACTIVE;
			state = MCTP_I2C_TX_FLOW_NEW;
			break;
		case MCTP_I2C_FLOW_STATE_ACTIVE:
			state = MCTP_I2C_TX_FLOW_EXISTING;
			break;
		default:
			state = MCTP_I2C_TX_FLOW_INVALID;
		}
	}

	spin_unlock_irqrestore(&key->lock, flags);

	return state;
}

/* We're not contending with ourselves here; we only need to exclude other
 * i2c clients from using the bus. refcounts are simply to prevent
 * recursive locking.
 */
static void mctp_i2c_lock_nest(struct mctp_i2c_dev *midev)
{
	unsigned long flags;
	bool lock;

	spin_lock_irqsave(&midev->lock, flags);
	lock = midev->i2c_lock_count == 0;
	midev->i2c_lock_count++;
	spin_unlock_irqrestore(&midev->lock, flags);

	if (lock)
		i2c_lock_bus(midev->adapter, I2C_LOCK_SEGMENT);
}

static void mctp_i2c_unlock_nest(struct mctp_i2c_dev *midev)
{
	unsigned long flags;
	bool unlock;

	spin_lock_irqsave(&midev->lock, flags);
	if (!WARN_ONCE(midev->i2c_lock_count == 0, "lock count underflow!"))
		midev->i2c_lock_count--;
	unlock = midev->i2c_lock_count == 0;
	spin_unlock_irqrestore(&midev->lock, flags);

	if (unlock)
		i2c_unlock_bus(midev->adapter, I2C_LOCK_SEGMENT);
}

/* Unlocks the bus if was previously locked, used for cleanup */
static void mctp_i2c_unlock_reset(struct mctp_i2c_dev *midev)
{
	unsigned long flags;
	bool unlock;

	spin_lock_irqsave(&midev->lock, flags);
	unlock = midev->i2c_lock_count > 0;
	midev->i2c_lock_count = 0;
	spin_unlock_irqrestore(&midev->lock, flags);

	if (unlock)
		i2c_unlock_bus(midev->adapter, I2C_LOCK_SEGMENT);
}

static void mctp_i2c_xmit(struct mctp_i2c_dev *midev, struct sk_buff *skb)
{
	struct net_device_stats *stats = &midev->ndev->stats;
	enum mctp_i2c_flow_state fs;
	struct mctp_i2c_hdr *hdr;
	struct i2c_msg msg = {0};
	u8 *pecp;
	int rc;

	fs = mctp_i2c_get_tx_flow_state(midev, skb);

	hdr = (void *)skb_mac_header(skb);
	/* Sanity check that packet contents matches skb length,
	 * and can't exceed MCTP_I2C_BUFSZ
	 */
	if (skb->len != hdr->byte_count + 3) {
		dev_warn_ratelimited(&midev->adapter->dev,
				     "Bad tx length %d vs skb %u\n",
				     hdr->byte_count + 3, skb->len);
		return;
	}

	if (skb_tailroom(skb) >= 1) {
		/* Linear case with space, we can just append the PEC */
		skb_put(skb, 1);
	} else {
		/* Otherwise need to copy the buffer */
		skb_copy_bits(skb, 0, midev->tx_scratch, skb->len);
		hdr = (void *)midev->tx_scratch;
	}

	pecp = (void *)&hdr->source_slave + hdr->byte_count;
	*pecp = i2c_smbus_pec(0, (u8 *)hdr, hdr->byte_count + 3);
	msg.buf = (void *)&hdr->command;
	/* command, bytecount, data, pec */
	msg.len = 2 + hdr->byte_count + 1;
	msg.addr = hdr->dest_slave >> 1;

	switch (fs) {
	case MCTP_I2C_TX_FLOW_NONE:
		/* no flow: full lock & unlock */
		mctp_i2c_lock_nest(midev);
		mctp_i2c_device_select(midev->client, midev);
		rc = __i2c_transfer(midev->adapter, &msg, 1);
		mctp_i2c_unlock_nest(midev);
		break;

	case MCTP_I2C_TX_FLOW_NEW:
		/* new flow: lock, tx, but don't unlock; that will happen
		 * on flow release
		 */
		mctp_i2c_lock_nest(midev);
		mctp_i2c_device_select(midev->client, midev);
		fallthrough;

	case MCTP_I2C_TX_FLOW_EXISTING:
		/* existing flow: we already have the lock; just tx */
		rc = __i2c_transfer(midev->adapter, &msg, 1);
		break;

	case MCTP_I2C_TX_FLOW_INVALID:
		return;
	}

	if (rc < 0) {
		dev_warn_ratelimited(&midev->adapter->dev,
				     "__i2c_transfer failed %d\n", rc);
		stats->tx_errors++;
	} else {
		stats->tx_bytes += skb->len;
		stats->tx_packets++;
	}
}

static void mctp_i2c_flow_release(struct mctp_i2c_dev *midev)
{
	unsigned long flags;
	bool unlock;

	spin_lock_irqsave(&midev->lock, flags);
	if (midev->release_count > midev->i2c_lock_count) {
		WARN_ONCE(1, "release count overflow");
		midev->release_count = midev->i2c_lock_count;
	}

	midev->i2c_lock_count -= midev->release_count;
	unlock = midev->i2c_lock_count == 0 && midev->release_count > 0;
	midev->release_count = 0;
	spin_unlock_irqrestore(&midev->lock, flags);

	if (unlock)
		i2c_unlock_bus(midev->adapter, I2C_LOCK_SEGMENT);
}

static int mctp_i2c_header_create(struct sk_buff *skb, struct net_device *dev,
				  unsigned short type, const void *daddr,
	   const void *saddr, unsigned int len)
{
	struct mctp_i2c_hdr *hdr;
	struct mctp_hdr *mhdr;
	u8 lldst, llsrc;

	if (len > MCTP_I2C_MAXMTU)
		return -EMSGSIZE;

	lldst = *((u8 *)daddr);
	llsrc = *((u8 *)saddr);

	skb_push(skb, sizeof(struct mctp_i2c_hdr));
	skb_reset_mac_header(skb);
	hdr = (void *)skb_mac_header(skb);
	mhdr = mctp_hdr(skb);
	hdr->dest_slave = (lldst << 1) & 0xff;
	hdr->command = MCTP_I2C_COMMANDCODE;
	hdr->byte_count = len + 1;
	hdr->source_slave = ((llsrc << 1) & 0xff) | 0x01;
	mhdr->ver = 0x01;

	return sizeof(struct mctp_i2c_hdr);
}

static int mctp_i2c_tx_thread(void *data)
{
	struct mctp_i2c_dev *midev = data;
	struct sk_buff *skb;
	unsigned long flags;

	for (;;) {
		if (kthread_should_stop())
			break;

		spin_lock_irqsave(&midev->tx_queue.lock, flags);
		skb = __skb_dequeue(&midev->tx_queue);
		if (netif_queue_stopped(midev->ndev))
			netif_wake_queue(midev->ndev);
		spin_unlock_irqrestore(&midev->tx_queue.lock, flags);

		if (skb == &midev->unlock_marker) {
			mctp_i2c_flow_release(midev);

		} else if (skb) {
			mctp_i2c_xmit(midev, skb);
			kfree_skb(skb);

		} else {
			wait_event_idle(midev->tx_wq,
					!skb_queue_empty(&midev->tx_queue) ||
				   kthread_should_stop());
		}
	}

	return 0;
}

static netdev_tx_t mctp_i2c_start_xmit(struct sk_buff *skb,
				       struct net_device *dev)
{
	struct mctp_i2c_dev *midev = netdev_priv(dev);
	unsigned long flags;

	spin_lock_irqsave(&midev->tx_queue.lock, flags);
	if (skb_queue_len(&midev->tx_queue) >= MCTP_I2C_TX_WORK_LEN) {
		netif_stop_queue(dev);
		spin_unlock_irqrestore(&midev->tx_queue.lock, flags);
		netdev_err(dev, "BUG! Tx Ring full when queue awake!\n");
		return NETDEV_TX_BUSY;
	}

	__skb_queue_tail(&midev->tx_queue, skb);
	if (skb_queue_len(&midev->tx_queue) == MCTP_I2C_TX_WORK_LEN)
		netif_stop_queue(dev);
	spin_unlock_irqrestore(&midev->tx_queue.lock, flags);

	wake_up(&midev->tx_wq);
	return NETDEV_TX_OK;
}

static void mctp_i2c_release_flow(struct mctp_dev *mdev,
				  struct mctp_sk_key *key)

{
	struct mctp_i2c_dev *midev = netdev_priv(mdev->dev);
	bool queue_release = false;
	unsigned long flags;

	spin_lock_irqsave(&midev->lock, flags);
	/* if we have seen the flow/key previously, we need to pair the
	 * original lock with a release
	 */
	if (key->dev_flow_state == MCTP_I2C_FLOW_STATE_ACTIVE) {
		midev->release_count++;
		queue_release = true;
	}
	key->dev_flow_state = MCTP_I2C_FLOW_STATE_INVALID;
	spin_unlock_irqrestore(&midev->lock, flags);

	if (queue_release) {
		/* Ensure we have a release operation queued, through the fake
		 * marker skb
		 */
		spin_lock(&midev->tx_queue.lock);
		if (!midev->unlock_marker.next)
			__skb_queue_tail(&midev->tx_queue,
					 &midev->unlock_marker);
		spin_unlock(&midev->tx_queue.lock);
		wake_up(&midev->tx_wq);
	}
}

static const struct net_device_ops mctp_i2c_ops = {
	.ndo_start_xmit = mctp_i2c_start_xmit,
	.ndo_uninit = mctp_i2c_ndo_uninit,
	.ndo_open = mctp_i2c_ndo_open,
};

static const struct header_ops mctp_i2c_headops = {
	.create = mctp_i2c_header_create,
};

static const struct mctp_netdev_ops mctp_i2c_mctp_ops = {
	.release_flow = mctp_i2c_release_flow,
};

static void mctp_i2c_net_setup(struct net_device *dev)
{
	dev->type = ARPHRD_MCTP;

	dev->mtu = MCTP_I2C_MAXMTU;
	dev->min_mtu = MCTP_I2C_MINMTU;
	dev->max_mtu = MCTP_I2C_MAXMTU;
	dev->tx_queue_len = MCTP_I2C_TX_QUEUE_LEN;

	dev->hard_header_len = sizeof(struct mctp_i2c_hdr);
	dev->addr_len = 1;

	dev->netdev_ops		= &mctp_i2c_ops;
	dev->header_ops		= &mctp_i2c_headops;
}

/* Populates the mctp_i2c_dev priv struct for a netdev.
 * Returns an error pointer on failure.
 */
static struct mctp_i2c_dev *mctp_i2c_midev_init(struct net_device *dev,
						struct mctp_i2c_client *mcli,
						struct i2c_adapter *adap)
{
	struct mctp_i2c_dev *midev = netdev_priv(dev);
	unsigned long flags;

	midev->tx_thread = kthread_create(mctp_i2c_tx_thread, midev,
					  "%s/tx", dev->name);
	if (IS_ERR(midev->tx_thread))
		return ERR_CAST(midev->tx_thread);

	midev->ndev = dev;
	get_device(&adap->dev);
	midev->adapter = adap;
	get_device(&mcli->client->dev);
	midev->client = mcli;
	INIT_LIST_HEAD(&midev->list);
	spin_lock_init(&midev->lock);
	midev->i2c_lock_count = 0;
	midev->release_count = 0;
	init_completion(&midev->rx_done);
	complete(&midev->rx_done);
	init_waitqueue_head(&midev->tx_wq);
	skb_queue_head_init(&midev->tx_queue);

	/* Add to the parent mcli */
	spin_lock_irqsave(&mcli->sel_lock, flags);
	list_add(&midev->list, &mcli->devs);
	/* Select a device by default */
	if (!mcli->sel)
		__mctp_i2c_device_select(mcli, midev);
	spin_unlock_irqrestore(&mcli->sel_lock, flags);

	/* Start the worker thread */
	wake_up_process(midev->tx_thread);

	return midev;
}

/* Counterpart of mctp_i2c_midev_init */
static void mctp_i2c_midev_free(struct mctp_i2c_dev *midev)
{
	struct mctp_i2c_client *mcli = midev->client;
	unsigned long flags;

	if (midev->tx_thread) {
		kthread_stop(midev->tx_thread);
		midev->tx_thread = NULL;
	}

	/* Unconditionally unlock on close */
	mctp_i2c_unlock_reset(midev);

	/* Remove the netdev from the parent i2c client. */
	spin_lock_irqsave(&mcli->sel_lock, flags);
	list_del(&midev->list);
	if (mcli->sel == midev) {
		struct mctp_i2c_dev *first;

		first = list_first_entry_or_null(&mcli->devs, struct mctp_i2c_dev, list);
		__mctp_i2c_device_select(mcli, first);
	}
	spin_unlock_irqrestore(&mcli->sel_lock, flags);

	skb_queue_purge(&midev->tx_queue);
	put_device(&midev->adapter->dev);
	put_device(&mcli->client->dev);
}

/* Stops, unregisters, and frees midev */
static void mctp_i2c_unregister(struct mctp_i2c_dev *midev)
{
	unsigned long flags;

	/* Stop tx thread prior to unregister, it uses netif_() functions */
	kthread_stop(midev->tx_thread);
	midev->tx_thread = NULL;

	/* Prevent any new rx in mctp_i2c_recv(), let any pending work finish */
	spin_lock_irqsave(&midev->lock, flags);
	midev->allow_rx = false;
	spin_unlock_irqrestore(&midev->lock, flags);
	wait_for_completion(&midev->rx_done);

	mctp_unregister_netdev(midev->ndev);
	/* midev has been freed now by mctp_i2c_ndo_uninit callback */

	free_netdev(midev->ndev);
}

static void mctp_i2c_ndo_uninit(struct net_device *dev)
{
	struct mctp_i2c_dev *midev = netdev_priv(dev);

	/* Perform cleanup here to ensure that mcli->sel isn't holding
	 * a reference that would prevent unregister_netdevice()
	 * from completing.
	 */
	mctp_i2c_midev_free(midev);
}

static int mctp_i2c_ndo_open(struct net_device *dev)
{
	struct mctp_i2c_dev *midev = netdev_priv(dev);
	unsigned long flags;

	/* i2c rx handler can only pass packets once the netdev is registered */
	spin_lock_irqsave(&midev->lock, flags);
	midev->allow_rx = true;
	spin_unlock_irqrestore(&midev->lock, flags);

	return 0;
}

static int mctp_i2c_add_netdev(struct mctp_i2c_client *mcli,
			       struct i2c_adapter *adap)
{
	struct mctp_i2c_dev *midev = NULL;
	struct net_device *ndev = NULL;
	struct i2c_adapter *root;
	unsigned long flags;
	char namebuf[30];
	int rc;

	root = mux_root_adapter(adap);
	if (root != mcli->client->adapter) {
		dev_err(&mcli->client->dev,
			"I2C adapter %s is not a child bus of %s\n",
			mcli->client->adapter->name, root->name);
		return -EINVAL;
	}

	WARN_ON(!mutex_is_locked(&driver_clients_lock));
	snprintf(namebuf, sizeof(namebuf), "mctpi2c%d", adap->nr);
	ndev = alloc_netdev(sizeof(*midev), namebuf, NET_NAME_ENUM, mctp_i2c_net_setup);
	if (!ndev) {
		dev_err(&mcli->client->dev, "alloc netdev failed\n");
		rc = -ENOMEM;
		goto err;
	}
	dev_net_set(ndev, current->nsproxy->net_ns);
	SET_NETDEV_DEV(ndev, &adap->dev);
	dev_addr_set(ndev, &mcli->lladdr);

	midev = mctp_i2c_midev_init(ndev, mcli, adap);
	if (IS_ERR(midev)) {
		rc = PTR_ERR(midev);
		midev = NULL;
		goto err;
	}

	rc = mctp_register_netdev(ndev, &mctp_i2c_mctp_ops);
	if (rc < 0) {
		dev_err(&mcli->client->dev,
			"register netdev \"%s\" failed %d\n",
			ndev->name, rc);
		goto err;
	}

	spin_lock_irqsave(&midev->lock, flags);
	midev->allow_rx = false;
	spin_unlock_irqrestore(&midev->lock, flags);

	return 0;
err:
	if (midev)
		mctp_i2c_midev_free(midev);
	if (ndev)
		free_netdev(ndev);
	return rc;
}

/* Removes any netdev for adap. mcli is the parent root i2c client */
static void mctp_i2c_remove_netdev(struct mctp_i2c_client *mcli,
				   struct i2c_adapter *adap)
{
	struct mctp_i2c_dev *midev = NULL, *m = NULL;
	unsigned long flags;

	WARN_ON(!mutex_is_locked(&driver_clients_lock));
	spin_lock_irqsave(&mcli->sel_lock, flags);
	/* List size is limited by number of MCTP netdevs on a single hardware bus */
	list_for_each_entry(m, &mcli->devs, list)
		if (m->adapter == adap) {
			midev = m;
			break;
		}
	spin_unlock_irqrestore(&mcli->sel_lock, flags);

	if (midev)
		mctp_i2c_unregister(midev);
}

/* Determines whether a device is an i2c adapter.
 * Optionally returns the root i2c_adapter
 */
static struct i2c_adapter *mctp_i2c_get_adapter(struct device *dev,
						struct i2c_adapter **ret_root)
{
	struct i2c_adapter *root, *adap;

	if (dev->type != &i2c_adapter_type)
		return NULL;
	adap = to_i2c_adapter(dev);
	root = mux_root_adapter(adap);
	WARN_ONCE(!root, "MCTP I2C failed to find root adapter for %s\n",
		  dev_name(dev));
	if (!root)
		return NULL;
	if (ret_root)
		*ret_root = root;
	return adap;
}

/* Determines whether a device is an i2c adapter with the "mctp-controller"
 * devicetree property set. If adap is not an OF node, returns match_no_of
 */
static bool mctp_i2c_adapter_match(struct i2c_adapter *adap, bool match_no_of)
{
	if (!adap->dev.of_node)
		return match_no_of;
	return of_property_read_bool(adap->dev.of_node, MCTP_I2C_OF_PROP);
}

/* Called for each existing i2c device (adapter or client) when a
 * new mctp-i2c client is probed.
 */
static int mctp_i2c_client_try_attach(struct device *dev, void *data)
{
	struct i2c_adapter *adap = NULL, *root = NULL;
	struct mctp_i2c_client *mcli = data;

	adap = mctp_i2c_get_adapter(dev, &root);
	if (!adap)
		return 0;
	if (mcli->client->adapter != root)
		return 0;
	/* Must either have mctp-controller property on the adapter, or
	 * be a root adapter if it's non-devicetree
	 */
	if (!mctp_i2c_adapter_match(adap, adap == root))
		return 0;

	return mctp_i2c_add_netdev(mcli, adap);
}

static void mctp_i2c_notify_add(struct device *dev)
{
	struct mctp_i2c_client *mcli = NULL, *m = NULL;
	struct i2c_adapter *root = NULL, *adap = NULL;
	int rc;

	adap = mctp_i2c_get_adapter(dev, &root);
	if (!adap)
		return;
	/* Check for mctp-controller property on the adapter */
	if (!mctp_i2c_adapter_match(adap, false))
		return;

	/* Find an existing mcli for adap's root */
	mutex_lock(&driver_clients_lock);
	list_for_each_entry(m, &driver_clients, list) {
		if (m->client->adapter == root) {
			mcli = m;
			break;
		}
	}

	if (mcli) {
		rc = mctp_i2c_add_netdev(mcli, adap);
		if (rc < 0)
			dev_warn(dev, "Failed adding mctp-i2c net device\n");
	}
	mutex_unlock(&driver_clients_lock);
}

static void mctp_i2c_notify_del(struct device *dev)
{
	struct i2c_adapter *root = NULL, *adap = NULL;
	struct mctp_i2c_client *mcli = NULL;

	adap = mctp_i2c_get_adapter(dev, &root);
	if (!adap)
		return;

	mutex_lock(&driver_clients_lock);
	list_for_each_entry(mcli, &driver_clients, list) {
		if (mcli->client->adapter == root) {
			mctp_i2c_remove_netdev(mcli, adap);
			break;
		}
	}
	mutex_unlock(&driver_clients_lock);
}

static int mctp_i2c_probe(struct i2c_client *client)
{
	struct mctp_i2c_client *mcli = NULL;
	int rc;

	mutex_lock(&driver_clients_lock);
	mcli = mctp_i2c_new_client(client);
	if (IS_ERR(mcli)) {
		rc = PTR_ERR(mcli);
		mcli = NULL;
		goto out;
	} else {
		list_add(&mcli->list, &driver_clients);
	}

	/* Add a netdev for adapters that have a 'mctp-controller' property */
	i2c_for_each_dev(mcli, mctp_i2c_client_try_attach);
	rc = 0;
out:
	mutex_unlock(&driver_clients_lock);
	return rc;
}

static void mctp_i2c_remove(struct i2c_client *client)
{
	struct mctp_i2c_client *mcli = i2c_get_clientdata(client);
	struct mctp_i2c_dev *midev = NULL, *tmp = NULL;

	mutex_lock(&driver_clients_lock);
	list_del(&mcli->list);
	/* Remove all child adapter netdevs */
	list_for_each_entry_safe(midev, tmp, &mcli->devs, list)
		mctp_i2c_unregister(midev);

	mctp_i2c_free_client(mcli);
	mutex_unlock(&driver_clients_lock);
}

/* We look for a 'mctp-controller' property on I2C busses as they are
 * added/deleted, creating/removing netdevs as required.
 */
static int mctp_i2c_notifier_call(struct notifier_block *nb,
				  unsigned long action, void *data)
{
	struct device *dev = data;

	switch (action) {
	case BUS_NOTIFY_ADD_DEVICE:
		mctp_i2c_notify_add(dev);
		break;
	case BUS_NOTIFY_DEL_DEVICE:
		mctp_i2c_notify_del(dev);
		break;
	}
	return NOTIFY_DONE;
}

static struct notifier_block mctp_i2c_notifier = {
	.notifier_call = mctp_i2c_notifier_call,
};

static const struct i2c_device_id mctp_i2c_id[] = {
	{ "mctp-i2c-interface", 0 },
	{},
};
MODULE_DEVICE_TABLE(i2c, mctp_i2c_id);

static const struct of_device_id mctp_i2c_of_match[] = {
	{ .compatible = "mctp-i2c-controller" },
	{},
};
MODULE_DEVICE_TABLE(of, mctp_i2c_of_match);

static struct i2c_driver mctp_i2c_driver = {
	.driver = {
		.name = "mctp-i2c-interface",
		.of_match_table = mctp_i2c_of_match,
	},
	.probe = mctp_i2c_probe,
	.remove = mctp_i2c_remove,
	.id_table = mctp_i2c_id,
};

static __init int mctp_i2c_mod_init(void)
{
	int rc;

	pr_info("MCTP I2C interface driver\n");
	rc = i2c_add_driver(&mctp_i2c_driver);
	if (rc < 0)
		return rc;
	rc = bus_register_notifier(&i2c_bus_type, &mctp_i2c_notifier);
	if (rc < 0) {
		i2c_del_driver(&mctp_i2c_driver);
		return rc;
	}
	return 0;
}

static __exit void mctp_i2c_mod_exit(void)
{
	int rc;

	rc = bus_unregister_notifier(&i2c_bus_type, &mctp_i2c_notifier);
	if (rc < 0)
		pr_warn("MCTP I2C could not unregister notifier, %d\n", rc);
	i2c_del_driver(&mctp_i2c_driver);
}

module_init(mctp_i2c_mod_init);
module_exit(mctp_i2c_mod_exit);

MODULE_DESCRIPTION("MCTP I2C device");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Matt Johnston <matt@codeconstruct.com.au>");
