// SPDX-License-Identifier: GPL-2.0+

#include <net/switchdev.h>

#include "lan966x_main.h"

struct lan966x_fdb_event_work {
	struct work_struct work;
	struct switchdev_notifier_fdb_info fdb_info;
	struct net_device *dev;
	struct net_device *orig_dev;
	struct lan966x *lan966x;
	unsigned long event;
};

struct lan966x_fdb_entry {
	struct list_head list;
	unsigned char mac[ETH_ALEN] __aligned(2);
	u16 vid;
	u32 references;
};

static struct lan966x_fdb_entry *
lan966x_fdb_find_entry(struct lan966x *lan966x,
		       struct switchdev_notifier_fdb_info *fdb_info)
{
	struct lan966x_fdb_entry *fdb_entry;

	list_for_each_entry(fdb_entry, &lan966x->fdb_entries, list) {
		if (fdb_entry->vid == fdb_info->vid &&
		    ether_addr_equal(fdb_entry->mac, fdb_info->addr))
			return fdb_entry;
	}

	return NULL;
}

static void lan966x_fdb_add_entry(struct lan966x *lan966x,
				  struct switchdev_notifier_fdb_info *fdb_info)
{
	struct lan966x_fdb_entry *fdb_entry;

	fdb_entry = lan966x_fdb_find_entry(lan966x, fdb_info);
	if (fdb_entry) {
		fdb_entry->references++;
		return;
	}

	fdb_entry = kzalloc(sizeof(*fdb_entry), GFP_KERNEL);
	if (!fdb_entry)
		return;

	ether_addr_copy(fdb_entry->mac, fdb_info->addr);
	fdb_entry->vid = fdb_info->vid;
	fdb_entry->references = 1;
	list_add_tail(&fdb_entry->list, &lan966x->fdb_entries);
}

static bool lan966x_fdb_del_entry(struct lan966x *lan966x,
				  struct switchdev_notifier_fdb_info *fdb_info)
{
	struct lan966x_fdb_entry *fdb_entry, *tmp;

	list_for_each_entry_safe(fdb_entry, tmp, &lan966x->fdb_entries,
				 list) {
		if (fdb_entry->vid == fdb_info->vid &&
		    ether_addr_equal(fdb_entry->mac, fdb_info->addr)) {
			fdb_entry->references--;
			if (!fdb_entry->references) {
				list_del(&fdb_entry->list);
				kfree(fdb_entry);
				return true;
			}
			break;
		}
	}

	return false;
}

void lan966x_fdb_write_entries(struct lan966x *lan966x, u16 vid)
{
	struct lan966x_fdb_entry *fdb_entry;

	list_for_each_entry(fdb_entry, &lan966x->fdb_entries, list) {
		if (fdb_entry->vid != vid)
			continue;

		lan966x_mac_cpu_learn(lan966x, fdb_entry->mac, fdb_entry->vid);
	}
}

void lan966x_fdb_erase_entries(struct lan966x *lan966x, u16 vid)
{
	struct lan966x_fdb_entry *fdb_entry;

	list_for_each_entry(fdb_entry, &lan966x->fdb_entries, list) {
		if (fdb_entry->vid != vid)
			continue;

		lan966x_mac_cpu_forget(lan966x, fdb_entry->mac, fdb_entry->vid);
	}
}

static void lan966x_fdb_purge_entries(struct lan966x *lan966x)
{
	struct lan966x_fdb_entry *fdb_entry, *tmp;

	list_for_each_entry_safe(fdb_entry, tmp, &lan966x->fdb_entries, list) {
		list_del(&fdb_entry->list);
		kfree(fdb_entry);
	}
}

int lan966x_fdb_init(struct lan966x *lan966x)
{
	INIT_LIST_HEAD(&lan966x->fdb_entries);
	lan966x->fdb_work = alloc_ordered_workqueue("lan966x_order", 0);
	if (!lan966x->fdb_work)
		return -ENOMEM;

	return 0;
}

void lan966x_fdb_deinit(struct lan966x *lan966x)
{
	destroy_workqueue(lan966x->fdb_work);
	lan966x_fdb_purge_entries(lan966x);
}

void lan966x_fdb_flush_workqueue(struct lan966x *lan966x)
{
	flush_workqueue(lan966x->fdb_work);
}

static void lan966x_fdb_port_event_work(struct lan966x_fdb_event_work *fdb_work)
{
	struct switchdev_notifier_fdb_info *fdb_info;
	struct lan966x_port *port;
	struct lan966x *lan966x;

	lan966x = fdb_work->lan966x;
	port = netdev_priv(fdb_work->orig_dev);
	fdb_info = &fdb_work->fdb_info;

	switch (fdb_work->event) {
	case SWITCHDEV_FDB_ADD_TO_DEVICE:
		if (!fdb_info->added_by_user)
			break;
		lan966x_mac_add_entry(lan966x, port, fdb_info->addr,
				      fdb_info->vid);
		break;
	case SWITCHDEV_FDB_DEL_TO_DEVICE:
		if (!fdb_info->added_by_user)
			break;
		lan966x_mac_del_entry(lan966x, fdb_info->addr,
				      fdb_info->vid);
		break;
	}
}

static void lan966x_fdb_bridge_event_work(struct lan966x_fdb_event_work *fdb_work)
{
	struct switchdev_notifier_fdb_info *fdb_info;
	struct lan966x *lan966x;
	int ret;

	lan966x = fdb_work->lan966x;
	fdb_info = &fdb_work->fdb_info;

	/* In case the bridge is called */
	switch (fdb_work->event) {
	case SWITCHDEV_FDB_ADD_TO_DEVICE:
		/* If there is no front port in this vlan, there is no
		 * point to copy the frame to CPU because it would be
		 * just dropped at later point. So add it only if
		 * there is a port but it is required to store the fdb
		 * entry for later point when a port actually gets in
		 * the vlan.
		 */
		lan966x_fdb_add_entry(lan966x, fdb_info);
		if (!lan966x_vlan_cpu_member_cpu_vlan_mask(lan966x,
							   fdb_info->vid))
			break;

		lan966x_mac_cpu_learn(lan966x, fdb_info->addr,
				      fdb_info->vid);
		break;
	case SWITCHDEV_FDB_DEL_TO_DEVICE:
		ret = lan966x_fdb_del_entry(lan966x, fdb_info);
		if (!lan966x_vlan_cpu_member_cpu_vlan_mask(lan966x,
							   fdb_info->vid))
			break;

		if (ret)
			lan966x_mac_cpu_forget(lan966x, fdb_info->addr,
					       fdb_info->vid);
		break;
	}
}

static void lan966x_fdb_lag_event_work(struct lan966x_fdb_event_work *fdb_work)
{
	struct switchdev_notifier_fdb_info *fdb_info;
	struct lan966x_port *port;
	struct lan966x *lan966x;

	if (!lan966x_lag_first_port(fdb_work->orig_dev, fdb_work->dev))
		return;

	lan966x = fdb_work->lan966x;
	port = netdev_priv(fdb_work->dev);
	fdb_info = &fdb_work->fdb_info;

	switch (fdb_work->event) {
	case SWITCHDEV_FDB_ADD_TO_DEVICE:
		if (!fdb_info->added_by_user)
			break;
		lan966x_mac_add_entry(lan966x, port, fdb_info->addr,
				      fdb_info->vid);
		break;
	case SWITCHDEV_FDB_DEL_TO_DEVICE:
		if (!fdb_info->added_by_user)
			break;
		lan966x_mac_del_entry(lan966x, fdb_info->addr, fdb_info->vid);
		break;
	}
}

static void lan966x_fdb_event_work(struct work_struct *work)
{
	struct lan966x_fdb_event_work *fdb_work =
		container_of(work, struct lan966x_fdb_event_work, work);

	if (lan966x_netdevice_check(fdb_work->orig_dev))
		lan966x_fdb_port_event_work(fdb_work);
	else if (netif_is_bridge_master(fdb_work->orig_dev))
		lan966x_fdb_bridge_event_work(fdb_work);
	else if (netif_is_lag_master(fdb_work->orig_dev))
		lan966x_fdb_lag_event_work(fdb_work);

	kfree(fdb_work->fdb_info.addr);
	kfree(fdb_work);
}

int lan966x_handle_fdb(struct net_device *dev,
		       struct net_device *orig_dev,
		       unsigned long event, const void *ctx,
		       const struct switchdev_notifier_fdb_info *fdb_info)
{
	struct lan966x_port *port = netdev_priv(dev);
	struct lan966x *lan966x = port->lan966x;
	struct lan966x_fdb_event_work *fdb_work;

	if (ctx && ctx != port)
		return 0;

	switch (event) {
	case SWITCHDEV_FDB_ADD_TO_DEVICE:
	case SWITCHDEV_FDB_DEL_TO_DEVICE:
		if (lan966x_netdevice_check(orig_dev) &&
		    !fdb_info->added_by_user)
			break;

		fdb_work = kzalloc(sizeof(*fdb_work), GFP_ATOMIC);
		if (!fdb_work)
			return -ENOMEM;

		fdb_work->dev = dev;
		fdb_work->orig_dev = orig_dev;
		fdb_work->lan966x = lan966x;
		fdb_work->event = event;
		INIT_WORK(&fdb_work->work, lan966x_fdb_event_work);
		memcpy(&fdb_work->fdb_info, fdb_info, sizeof(fdb_work->fdb_info));
		fdb_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC);
		if (!fdb_work->fdb_info.addr)
			goto err_addr_alloc;

		ether_addr_copy((u8 *)fdb_work->fdb_info.addr, fdb_info->addr);

		queue_work(lan966x->fdb_work, &fdb_work->work);
		break;
	}

	return 0;
err_addr_alloc:
	kfree(fdb_work);
	return -ENOMEM;
}
