// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2017 - 2019 Pensando Systems, Inc */

#include <linux/netdevice.h>
#include <linux/dynamic_debug.h>
#include <linux/etherdevice.h>
#include <linux/list.h>

#include "ionic.h"
#include "ionic_lif.h"
#include "ionic_rx_filter.h"

void ionic_rx_filter_free(struct ionic_lif *lif, struct ionic_rx_filter *f)
{
	struct device *dev = lif->ionic->dev;

	hlist_del(&f->by_id);
	hlist_del(&f->by_hash);
	devm_kfree(dev, f);
}

void ionic_rx_filter_replay(struct ionic_lif *lif)
{
	struct ionic_rx_filter_add_cmd *ac;
	struct hlist_head new_id_list;
	struct ionic_admin_ctx ctx;
	struct ionic_rx_filter *f;
	struct hlist_head *head;
	struct hlist_node *tmp;
	unsigned int key;
	unsigned int i;
	int err;

	INIT_HLIST_HEAD(&new_id_list);
	ac = &ctx.cmd.rx_filter_add;

	for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) {
		head = &lif->rx_filters.by_id[i];
		hlist_for_each_entry_safe(f, tmp, head, by_id) {
			ctx.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work);
			memcpy(ac, &f->cmd, sizeof(f->cmd));
			dev_dbg(&lif->netdev->dev, "replay filter command:\n");
			dynamic_hex_dump("cmd ", DUMP_PREFIX_OFFSET, 16, 1,
					 &ctx.cmd, sizeof(ctx.cmd), true);

			err = ionic_adminq_post_wait(lif, &ctx);
			if (err) {
				switch (le16_to_cpu(ac->match)) {
				case IONIC_RX_FILTER_MATCH_VLAN:
					netdev_info(lif->netdev, "Replay failed - %d: vlan %d\n",
						    err,
						    le16_to_cpu(ac->vlan.vlan));
					break;
				case IONIC_RX_FILTER_MATCH_MAC:
					netdev_info(lif->netdev, "Replay failed - %d: mac %pM\n",
						    err, ac->mac.addr);
					break;
				case IONIC_RX_FILTER_MATCH_MAC_VLAN:
					netdev_info(lif->netdev, "Replay failed - %d: vlan %d mac %pM\n",
						    err,
						    le16_to_cpu(ac->vlan.vlan),
						    ac->mac.addr);
					break;
				}
				spin_lock_bh(&lif->rx_filters.lock);
				ionic_rx_filter_free(lif, f);
				spin_unlock_bh(&lif->rx_filters.lock);

				continue;
			}

			/* remove from old id list, save new id in tmp list */
			spin_lock_bh(&lif->rx_filters.lock);
			hlist_del(&f->by_id);
			spin_unlock_bh(&lif->rx_filters.lock);
			f->filter_id = le32_to_cpu(ctx.comp.rx_filter_add.filter_id);
			hlist_add_head(&f->by_id, &new_id_list);
		}
	}

	/* rebuild the by_id hash lists with the new filter ids */
	spin_lock_bh(&lif->rx_filters.lock);
	hlist_for_each_entry_safe(f, tmp, &new_id_list, by_id) {
		key = f->filter_id & IONIC_RX_FILTER_HLISTS_MASK;
		head = &lif->rx_filters.by_id[key];
		hlist_add_head(&f->by_id, head);
	}
	spin_unlock_bh(&lif->rx_filters.lock);
}

int ionic_rx_filters_init(struct ionic_lif *lif)
{
	unsigned int i;

	spin_lock_init(&lif->rx_filters.lock);

	spin_lock_bh(&lif->rx_filters.lock);
	for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) {
		INIT_HLIST_HEAD(&lif->rx_filters.by_hash[i]);
		INIT_HLIST_HEAD(&lif->rx_filters.by_id[i]);
	}
	spin_unlock_bh(&lif->rx_filters.lock);

	return 0;
}

void ionic_rx_filters_deinit(struct ionic_lif *lif)
{
	struct ionic_rx_filter *f;
	struct hlist_head *head;
	struct hlist_node *tmp;
	unsigned int i;

	spin_lock_bh(&lif->rx_filters.lock);
	for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) {
		head = &lif->rx_filters.by_id[i];
		hlist_for_each_entry_safe(f, tmp, head, by_id)
			ionic_rx_filter_free(lif, f);
	}
	spin_unlock_bh(&lif->rx_filters.lock);
}

int ionic_rx_filter_save(struct ionic_lif *lif, u32 flow_id, u16 rxq_index,
			 u32 hash, struct ionic_admin_ctx *ctx,
			 enum ionic_filter_state state)
{
	struct device *dev = lif->ionic->dev;
	struct ionic_rx_filter_add_cmd *ac;
	struct ionic_rx_filter *f = NULL;
	struct hlist_head *head;
	unsigned int key;

	ac = &ctx->cmd.rx_filter_add;

	switch (le16_to_cpu(ac->match)) {
	case IONIC_RX_FILTER_MATCH_VLAN:
		key = le16_to_cpu(ac->vlan.vlan);
		f = ionic_rx_filter_by_vlan(lif, le16_to_cpu(ac->vlan.vlan));
		break;
	case IONIC_RX_FILTER_MATCH_MAC:
		key = *(u32 *)ac->mac.addr;
		f = ionic_rx_filter_by_addr(lif, ac->mac.addr);
		break;
	case IONIC_RX_FILTER_MATCH_MAC_VLAN:
		key = le16_to_cpu(ac->mac_vlan.vlan);
		break;
	case IONIC_RX_FILTER_STEER_PKTCLASS:
		key = 0;
		break;
	default:
		return -EINVAL;
	}

	if (f) {
		/* remove from current linking so we can refresh it */
		hlist_del(&f->by_id);
		hlist_del(&f->by_hash);
	} else {
		f = devm_kzalloc(dev, sizeof(*f), GFP_ATOMIC);
		if (!f)
			return -ENOMEM;
	}

	f->flow_id = flow_id;
	f->filter_id = le32_to_cpu(ctx->comp.rx_filter_add.filter_id);
	f->state = state;
	f->rxq_index = rxq_index;
	memcpy(&f->cmd, ac, sizeof(f->cmd));
	netdev_dbg(lif->netdev, "rx_filter add filter_id %d\n", f->filter_id);

	INIT_HLIST_NODE(&f->by_hash);
	INIT_HLIST_NODE(&f->by_id);

	key = hash_32(key, IONIC_RX_FILTER_HASH_BITS);
	head = &lif->rx_filters.by_hash[key];
	hlist_add_head(&f->by_hash, head);

	key = f->filter_id & IONIC_RX_FILTER_HLISTS_MASK;
	head = &lif->rx_filters.by_id[key];
	hlist_add_head(&f->by_id, head);

	return 0;
}

struct ionic_rx_filter *ionic_rx_filter_by_vlan(struct ionic_lif *lif, u16 vid)
{
	struct ionic_rx_filter *f;
	struct hlist_head *head;
	unsigned int key;

	key = hash_32(vid, IONIC_RX_FILTER_HASH_BITS);
	head = &lif->rx_filters.by_hash[key];

	hlist_for_each_entry(f, head, by_hash) {
		if (le16_to_cpu(f->cmd.match) != IONIC_RX_FILTER_MATCH_VLAN)
			continue;
		if (le16_to_cpu(f->cmd.vlan.vlan) == vid)
			return f;
	}

	return NULL;
}

struct ionic_rx_filter *ionic_rx_filter_by_addr(struct ionic_lif *lif,
						const u8 *addr)
{
	struct ionic_rx_filter *f;
	struct hlist_head *head;
	unsigned int key;

	key = hash_32(*(u32 *)addr, IONIC_RX_FILTER_HASH_BITS);
	head = &lif->rx_filters.by_hash[key];

	hlist_for_each_entry(f, head, by_hash) {
		if (le16_to_cpu(f->cmd.match) != IONIC_RX_FILTER_MATCH_MAC)
			continue;
		if (memcmp(addr, f->cmd.mac.addr, ETH_ALEN) == 0)
			return f;
	}

	return NULL;
}

struct ionic_rx_filter *ionic_rx_filter_rxsteer(struct ionic_lif *lif)
{
	struct ionic_rx_filter *f;
	struct hlist_head *head;
	unsigned int key;

	key = hash_32(0, IONIC_RX_FILTER_HASH_BITS);
	head = &lif->rx_filters.by_hash[key];

	hlist_for_each_entry(f, head, by_hash) {
		if (le16_to_cpu(f->cmd.match) != IONIC_RX_FILTER_STEER_PKTCLASS)
			continue;
		return f;
	}

	return NULL;
}

static struct ionic_rx_filter *ionic_rx_filter_find(struct ionic_lif *lif,
						    struct ionic_rx_filter_add_cmd *ac)
{
	switch (le16_to_cpu(ac->match)) {
	case IONIC_RX_FILTER_MATCH_VLAN:
		return ionic_rx_filter_by_vlan(lif, le16_to_cpu(ac->vlan.vlan));
	case IONIC_RX_FILTER_MATCH_MAC:
		return ionic_rx_filter_by_addr(lif, ac->mac.addr);
	default:
		netdev_err(lif->netdev, "unsupported filter match %d",
			   le16_to_cpu(ac->match));
		return NULL;
	}
}

int ionic_lif_list_addr(struct ionic_lif *lif, const u8 *addr, bool mode)
{
	struct ionic_rx_filter *f;
	int err;

	spin_lock_bh(&lif->rx_filters.lock);

	f = ionic_rx_filter_by_addr(lif, addr);
	if (mode == ADD_ADDR && !f) {
		struct ionic_admin_ctx ctx = {
			.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
			.cmd.rx_filter_add = {
				.opcode = IONIC_CMD_RX_FILTER_ADD,
				.lif_index = cpu_to_le16(lif->index),
				.match = cpu_to_le16(IONIC_RX_FILTER_MATCH_MAC),
			},
		};

		memcpy(ctx.cmd.rx_filter_add.mac.addr, addr, ETH_ALEN);
		err = ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx,
					   IONIC_FILTER_STATE_NEW);
		if (err) {
			spin_unlock_bh(&lif->rx_filters.lock);
			return err;
		}

	} else if (mode == ADD_ADDR && f) {
		if (f->state == IONIC_FILTER_STATE_OLD)
			f->state = IONIC_FILTER_STATE_SYNCED;

	} else if (mode == DEL_ADDR && f) {
		if (f->state == IONIC_FILTER_STATE_NEW)
			ionic_rx_filter_free(lif, f);
		else if (f->state == IONIC_FILTER_STATE_SYNCED)
			f->state = IONIC_FILTER_STATE_OLD;
	} else if (mode == DEL_ADDR && !f) {
		spin_unlock_bh(&lif->rx_filters.lock);
		return -ENOENT;
	}

	spin_unlock_bh(&lif->rx_filters.lock);

	set_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state);

	return 0;
}

static int ionic_lif_filter_add(struct ionic_lif *lif,
				struct ionic_rx_filter_add_cmd *ac)
{
	struct ionic_admin_ctx ctx = {
		.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
	};
	struct ionic_rx_filter *f;
	int nfilters;
	int err = 0;

	ctx.cmd.rx_filter_add = *ac;
	ctx.cmd.rx_filter_add.opcode = IONIC_CMD_RX_FILTER_ADD,
	ctx.cmd.rx_filter_add.lif_index = cpu_to_le16(lif->index),

	spin_lock_bh(&lif->rx_filters.lock);
	f = ionic_rx_filter_find(lif, &ctx.cmd.rx_filter_add);
	if (f) {
		/* don't bother if we already have it and it is sync'd */
		if (f->state == IONIC_FILTER_STATE_SYNCED) {
			spin_unlock_bh(&lif->rx_filters.lock);
			return 0;
		}

		/* mark preemptively as sync'd to block any parallel attempts */
		f->state = IONIC_FILTER_STATE_SYNCED;
	} else {
		/* save as SYNCED to catch any DEL requests while processing */
		err = ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx,
					   IONIC_FILTER_STATE_SYNCED);
	}
	spin_unlock_bh(&lif->rx_filters.lock);
	if (err)
		return err;

	/* Don't bother with the write to FW if we know there's no room,
	 * we can try again on the next sync attempt.
	 * Since the FW doesn't have a way to tell us the vlan limit,
	 * we start max_vlans at 0 until we hit the ENOSPC error.
	 */
	switch (le16_to_cpu(ctx.cmd.rx_filter_add.match)) {
	case IONIC_RX_FILTER_MATCH_VLAN:
		netdev_dbg(lif->netdev, "%s: rx_filter add VLAN %d\n",
			   __func__, ctx.cmd.rx_filter_add.vlan.vlan);
		if (lif->max_vlans && lif->nvlans >= lif->max_vlans)
			err = -ENOSPC;
		break;
	case IONIC_RX_FILTER_MATCH_MAC:
		netdev_dbg(lif->netdev, "%s: rx_filter add ADDR %pM\n",
			   __func__, ctx.cmd.rx_filter_add.mac.addr);
		nfilters = le32_to_cpu(lif->identity->eth.max_ucast_filters);
		if ((lif->nucast + lif->nmcast) >= nfilters)
			err = -ENOSPC;
		break;
	}

	if (err != -ENOSPC)
		err = ionic_adminq_post_wait_nomsg(lif, &ctx);

	spin_lock_bh(&lif->rx_filters.lock);

	if (err && err != -EEXIST) {
		/* set the state back to NEW so we can try again later */
		f = ionic_rx_filter_find(lif, &ctx.cmd.rx_filter_add);
		if (f && f->state == IONIC_FILTER_STATE_SYNCED) {
			f->state = IONIC_FILTER_STATE_NEW;

			/* If -ENOSPC we won't waste time trying to sync again
			 * until there is a delete that might make room
			 */
			if (err != -ENOSPC)
				set_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state);
		}

		spin_unlock_bh(&lif->rx_filters.lock);

		if (err == -ENOSPC) {
			if (le16_to_cpu(ctx.cmd.rx_filter_add.match) == IONIC_RX_FILTER_MATCH_VLAN)
				lif->max_vlans = lif->nvlans;
			return 0;
		}

		ionic_adminq_netdev_err_print(lif, ctx.cmd.cmd.opcode,
					      ctx.comp.comp.status, err);
		switch (le16_to_cpu(ctx.cmd.rx_filter_add.match)) {
		case IONIC_RX_FILTER_MATCH_VLAN:
			netdev_info(lif->netdev, "rx_filter add failed: VLAN %d\n",
				    ctx.cmd.rx_filter_add.vlan.vlan);
			break;
		case IONIC_RX_FILTER_MATCH_MAC:
			netdev_info(lif->netdev, "rx_filter add failed: ADDR %pM\n",
				    ctx.cmd.rx_filter_add.mac.addr);
			break;
		}

		return err;
	}

	switch (le16_to_cpu(ctx.cmd.rx_filter_add.match)) {
	case IONIC_RX_FILTER_MATCH_VLAN:
		lif->nvlans++;
		break;
	case IONIC_RX_FILTER_MATCH_MAC:
		if (is_multicast_ether_addr(ctx.cmd.rx_filter_add.mac.addr))
			lif->nmcast++;
		else
			lif->nucast++;
		break;
	}

	f = ionic_rx_filter_find(lif, &ctx.cmd.rx_filter_add);
	if (f && f->state == IONIC_FILTER_STATE_OLD) {
		/* Someone requested a delete while we were adding
		 * so update the filter info with the results from the add
		 * and the data will be there for the delete on the next
		 * sync cycle.
		 */
		err = ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx,
					   IONIC_FILTER_STATE_OLD);
	} else {
		err = ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx,
					   IONIC_FILTER_STATE_SYNCED);
	}

	spin_unlock_bh(&lif->rx_filters.lock);

	return err;
}

int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr)
{
	struct ionic_rx_filter_add_cmd ac = {
		.match = cpu_to_le16(IONIC_RX_FILTER_MATCH_MAC),
	};

	memcpy(&ac.mac.addr, addr, ETH_ALEN);

	return ionic_lif_filter_add(lif, &ac);
}

int ionic_lif_vlan_add(struct ionic_lif *lif, const u16 vid)
{
	struct ionic_rx_filter_add_cmd ac = {
		.match = cpu_to_le16(IONIC_RX_FILTER_MATCH_VLAN),
		.vlan.vlan = cpu_to_le16(vid),
	};

	return ionic_lif_filter_add(lif, &ac);
}

static int ionic_lif_filter_del(struct ionic_lif *lif,
				struct ionic_rx_filter_add_cmd *ac)
{
	struct ionic_admin_ctx ctx = {
		.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
		.cmd.rx_filter_del = {
			.opcode = IONIC_CMD_RX_FILTER_DEL,
			.lif_index = cpu_to_le16(lif->index),
		},
	};
	struct ionic_rx_filter *f;
	int state;
	int err;

	spin_lock_bh(&lif->rx_filters.lock);
	f = ionic_rx_filter_find(lif, ac);
	if (!f) {
		spin_unlock_bh(&lif->rx_filters.lock);
		return -ENOENT;
	}

	switch (le16_to_cpu(ac->match)) {
	case IONIC_RX_FILTER_MATCH_VLAN:
		netdev_dbg(lif->netdev, "%s: rx_filter del VLAN %d id %d\n",
			   __func__, ac->vlan.vlan, f->filter_id);
		lif->nvlans--;
		break;
	case IONIC_RX_FILTER_MATCH_MAC:
		netdev_dbg(lif->netdev, "%s: rx_filter del ADDR %pM id %d\n",
			   __func__, ac->mac.addr, f->filter_id);
		if (is_multicast_ether_addr(ac->mac.addr) && lif->nmcast)
			lif->nmcast--;
		else if (!is_multicast_ether_addr(ac->mac.addr) && lif->nucast)
			lif->nucast--;
		break;
	}

	state = f->state;
	ctx.cmd.rx_filter_del.filter_id = cpu_to_le32(f->filter_id);
	ionic_rx_filter_free(lif, f);

	spin_unlock_bh(&lif->rx_filters.lock);

	if (state != IONIC_FILTER_STATE_NEW) {
		err = ionic_adminq_post_wait(lif, &ctx);
		if (err && err != -EEXIST)
			return err;
	}

	return 0;
}

int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr)
{
	struct ionic_rx_filter_add_cmd ac = {
		.match = cpu_to_le16(IONIC_RX_FILTER_MATCH_MAC),
	};

	memcpy(&ac.mac.addr, addr, ETH_ALEN);

	return ionic_lif_filter_del(lif, &ac);
}

int ionic_lif_vlan_del(struct ionic_lif *lif, const u16 vid)
{
	struct ionic_rx_filter_add_cmd ac = {
		.match = cpu_to_le16(IONIC_RX_FILTER_MATCH_VLAN),
		.vlan.vlan = cpu_to_le16(vid),
	};

	return ionic_lif_filter_del(lif, &ac);
}

struct sync_item {
	struct list_head list;
	struct ionic_rx_filter f;
};

void ionic_rx_filter_sync(struct ionic_lif *lif)
{
	struct device *dev = lif->ionic->dev;
	struct list_head sync_add_list;
	struct list_head sync_del_list;
	struct sync_item *sync_item;
	struct ionic_rx_filter *f;
	struct hlist_head *head;
	struct hlist_node *tmp;
	struct sync_item *spos;
	unsigned int i;

	INIT_LIST_HEAD(&sync_add_list);
	INIT_LIST_HEAD(&sync_del_list);

	clear_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state);

	/* Copy the filters to be added and deleted
	 * into a separate local list that needs no locking.
	 */
	spin_lock_bh(&lif->rx_filters.lock);
	for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) {
		head = &lif->rx_filters.by_id[i];
		hlist_for_each_entry_safe(f, tmp, head, by_id) {
			if (f->state == IONIC_FILTER_STATE_NEW ||
			    f->state == IONIC_FILTER_STATE_OLD) {
				sync_item = devm_kzalloc(dev, sizeof(*sync_item),
							 GFP_ATOMIC);
				if (!sync_item)
					goto loop_out;

				sync_item->f = *f;

				if (f->state == IONIC_FILTER_STATE_NEW)
					list_add(&sync_item->list, &sync_add_list);
				else
					list_add(&sync_item->list, &sync_del_list);
			}
		}
	}
loop_out:
	spin_unlock_bh(&lif->rx_filters.lock);

	/* If the add or delete fails, it won't get marked as sync'd
	 * and will be tried again in the next sync action.
	 * Do the deletes first in case we're in an overflow state and
	 * they can clear room for some new filters
	 */
	list_for_each_entry_safe(sync_item, spos, &sync_del_list, list) {
		(void)ionic_lif_filter_del(lif, &sync_item->f.cmd);

		list_del(&sync_item->list);
		devm_kfree(dev, sync_item);
	}

	list_for_each_entry_safe(sync_item, spos, &sync_add_list, list) {
		(void)ionic_lif_filter_add(lif, &sync_item->f.cmd);

		list_del(&sync_item->list);
		devm_kfree(dev, sync_item);
	}
}
