// SPDX-License-Identifier: GPL-2.0+
/* Microchip Sparx5 Switch driver
 *
 * Copyright (c) 2021 Microchip Technology Inc. and its subsidiaries.
 */

#include <net/switchdev.h>
#include <linux/if_bridge.h>
#include <linux/iopoll.h>

#include "sparx5_main_regs.h"
#include "sparx5_main.h"

/* Commands for Mac Table Command register */
#define MAC_CMD_LEARN         0 /* Insert (Learn) 1 entry */
#define MAC_CMD_UNLEARN       1 /* Unlearn (Forget) 1 entry */
#define MAC_CMD_LOOKUP        2 /* Look up 1 entry */
#define MAC_CMD_READ          3 /* Read entry at Mac Table Index */
#define MAC_CMD_WRITE         4 /* Write entry at Mac Table Index */
#define MAC_CMD_SCAN          5 /* Scan (Age or find next) */
#define MAC_CMD_FIND_SMALLEST 6 /* Get next entry */
#define MAC_CMD_CLEAR_ALL     7 /* Delete all entries in table */

/* Commands for MAC_ENTRY_ADDR_TYPE */
#define  MAC_ENTRY_ADDR_TYPE_UPSID_PN         0
#define  MAC_ENTRY_ADDR_TYPE_UPSID_CPU_OR_INT 1
#define  MAC_ENTRY_ADDR_TYPE_GLAG             2
#define  MAC_ENTRY_ADDR_TYPE_MC_IDX           3

#define TABLE_UPDATE_SLEEP_US 10
#define TABLE_UPDATE_TIMEOUT_US 100000

struct sparx5_mact_entry {
	struct list_head list;
	unsigned char mac[ETH_ALEN];
	u32 flags;
#define MAC_ENT_ALIVE	BIT(0)
#define MAC_ENT_MOVED	BIT(1)
#define MAC_ENT_LOCK	BIT(2)
	u16 vid;
	u16 port;
};

static int sparx5_mact_get_status(struct sparx5 *sparx5)
{
	return spx5_rd(sparx5, LRN_COMMON_ACCESS_CTRL);
}

static int sparx5_mact_wait_for_completion(struct sparx5 *sparx5)
{
	u32 val;

	return readx_poll_timeout(sparx5_mact_get_status,
		sparx5, val,
		LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT_GET(val) == 0,
		TABLE_UPDATE_SLEEP_US, TABLE_UPDATE_TIMEOUT_US);
}

static void sparx5_mact_select(struct sparx5 *sparx5,
			       const unsigned char mac[ETH_ALEN],
			       u16 vid)
{
	u32 macl = 0, mach = 0;

	/* Set the MAC address to handle and the vlan associated in a format
	 * understood by the hardware.
	 */
	mach |= vid    << 16;
	mach |= mac[0] << 8;
	mach |= mac[1] << 0;
	macl |= mac[2] << 24;
	macl |= mac[3] << 16;
	macl |= mac[4] << 8;
	macl |= mac[5] << 0;

	spx5_wr(mach, sparx5, LRN_MAC_ACCESS_CFG_0);
	spx5_wr(macl, sparx5, LRN_MAC_ACCESS_CFG_1);
}

int sparx5_mact_learn(struct sparx5 *sparx5, int pgid,
		      const unsigned char mac[ETH_ALEN], u16 vid)
{
	int addr, type, ret;

	if (pgid < SPX5_PORTS) {
		type = MAC_ENTRY_ADDR_TYPE_UPSID_PN;
		addr = pgid % 32;
		addr += (pgid / 32) << 5; /* Add upsid */
	} else {
		type = MAC_ENTRY_ADDR_TYPE_MC_IDX;
		addr = pgid - SPX5_PORTS;
	}

	mutex_lock(&sparx5->lock);

	sparx5_mact_select(sparx5, mac, vid);

	/* MAC entry properties */
	spx5_wr(LRN_MAC_ACCESS_CFG_2_MAC_ENTRY_ADDR_SET(addr) |
		LRN_MAC_ACCESS_CFG_2_MAC_ENTRY_ADDR_TYPE_SET(type) |
		LRN_MAC_ACCESS_CFG_2_MAC_ENTRY_VLD_SET(1) |
		LRN_MAC_ACCESS_CFG_2_MAC_ENTRY_LOCKED_SET(1),
		sparx5, LRN_MAC_ACCESS_CFG_2);
	spx5_wr(0, sparx5, LRN_MAC_ACCESS_CFG_3);

	/*  Insert/learn new entry */
	spx5_wr(LRN_COMMON_ACCESS_CTRL_CPU_ACCESS_CMD_SET(MAC_CMD_LEARN) |
		LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT_SET(1),
		sparx5, LRN_COMMON_ACCESS_CTRL);

	ret = sparx5_mact_wait_for_completion(sparx5);

	mutex_unlock(&sparx5->lock);

	return ret;
}

int sparx5_mc_unsync(struct net_device *dev, const unsigned char *addr)
{
	struct sparx5_port *port = netdev_priv(dev);
	struct sparx5 *sparx5 = port->sparx5;

	return sparx5_mact_forget(sparx5, addr, port->pvid);
}

int sparx5_mc_sync(struct net_device *dev, const unsigned char *addr)
{
	struct sparx5_port *port = netdev_priv(dev);
	struct sparx5 *sparx5 = port->sparx5;

	return sparx5_mact_learn(sparx5, PGID_CPU, addr, port->pvid);
}

static int sparx5_mact_get(struct sparx5 *sparx5,
			   unsigned char mac[ETH_ALEN],
			   u16 *vid, u32 *pcfg2)
{
	u32 mach, macl, cfg2;
	int ret = -ENOENT;

	cfg2 = spx5_rd(sparx5, LRN_MAC_ACCESS_CFG_2);
	if (LRN_MAC_ACCESS_CFG_2_MAC_ENTRY_VLD_GET(cfg2)) {
		mach = spx5_rd(sparx5, LRN_MAC_ACCESS_CFG_0);
		macl = spx5_rd(sparx5, LRN_MAC_ACCESS_CFG_1);
		mac[0] = ((mach >> 8)  & 0xff);
		mac[1] = ((mach >> 0)  & 0xff);
		mac[2] = ((macl >> 24) & 0xff);
		mac[3] = ((macl >> 16) & 0xff);
		mac[4] = ((macl >> 8)  & 0xff);
		mac[5] = ((macl >> 0)  & 0xff);
		*vid = mach >> 16;
		*pcfg2 = cfg2;
		ret = 0;
	}

	return ret;
}

bool sparx5_mact_getnext(struct sparx5 *sparx5,
			 unsigned char mac[ETH_ALEN], u16 *vid, u32 *pcfg2)
{
	u32 cfg2;
	int ret;

	mutex_lock(&sparx5->lock);

	sparx5_mact_select(sparx5, mac, *vid);

	spx5_wr(LRN_SCAN_NEXT_CFG_SCAN_NEXT_IGNORE_LOCKED_ENA_SET(1) |
		LRN_SCAN_NEXT_CFG_SCAN_NEXT_UNTIL_FOUND_ENA_SET(1),
		sparx5, LRN_SCAN_NEXT_CFG);
	spx5_wr(LRN_COMMON_ACCESS_CTRL_CPU_ACCESS_CMD_SET
		(MAC_CMD_FIND_SMALLEST) |
		LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT_SET(1),
		sparx5, LRN_COMMON_ACCESS_CTRL);

	ret = sparx5_mact_wait_for_completion(sparx5);
	if (ret == 0) {
		ret = sparx5_mact_get(sparx5, mac, vid, &cfg2);
		if (ret == 0)
			*pcfg2 = cfg2;
	}

	mutex_unlock(&sparx5->lock);

	return ret == 0;
}

static int sparx5_mact_lookup(struct sparx5 *sparx5,
			      const unsigned char mac[ETH_ALEN],
			      u16 vid)
{
	int ret;

	mutex_lock(&sparx5->lock);

	sparx5_mact_select(sparx5, mac, vid);

	/* Issue a lookup command */
	spx5_wr(LRN_COMMON_ACCESS_CTRL_CPU_ACCESS_CMD_SET(MAC_CMD_LOOKUP) |
		LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT_SET(1),
		sparx5, LRN_COMMON_ACCESS_CTRL);

	ret = sparx5_mact_wait_for_completion(sparx5);
	if (ret)
		goto out;

	ret = LRN_MAC_ACCESS_CFG_2_MAC_ENTRY_VLD_GET
		(spx5_rd(sparx5, LRN_MAC_ACCESS_CFG_2));

out:
	mutex_unlock(&sparx5->lock);

	return ret;
}

int sparx5_mact_forget(struct sparx5 *sparx5,
		       const unsigned char mac[ETH_ALEN], u16 vid)
{
	int ret;

	mutex_lock(&sparx5->lock);

	sparx5_mact_select(sparx5, mac, vid);

	/* Issue an unlearn command */
	spx5_wr(LRN_COMMON_ACCESS_CTRL_CPU_ACCESS_CMD_SET(MAC_CMD_UNLEARN) |
		LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT_SET(1),
		sparx5, LRN_COMMON_ACCESS_CTRL);

	ret = sparx5_mact_wait_for_completion(sparx5);

	mutex_unlock(&sparx5->lock);

	return ret;
}

static struct sparx5_mact_entry *alloc_mact_entry(struct sparx5 *sparx5,
						  const unsigned char *mac,
						  u16 vid, u16 port_index)
{
	struct sparx5_mact_entry *mact_entry;

	mact_entry = devm_kzalloc(sparx5->dev,
				  sizeof(*mact_entry), GFP_ATOMIC);
	if (!mact_entry)
		return NULL;

	memcpy(mact_entry->mac, mac, ETH_ALEN);
	mact_entry->vid = vid;
	mact_entry->port = port_index;
	return mact_entry;
}

static struct sparx5_mact_entry *find_mact_entry(struct sparx5 *sparx5,
						 const unsigned char *mac,
						 u16 vid, u16 port_index)
{
	struct sparx5_mact_entry *mact_entry;
	struct sparx5_mact_entry *res = NULL;

	mutex_lock(&sparx5->mact_lock);
	list_for_each_entry(mact_entry, &sparx5->mact_entries, list) {
		if (mact_entry->vid == vid &&
		    ether_addr_equal(mac, mact_entry->mac) &&
		    mact_entry->port == port_index) {
			res = mact_entry;
			break;
		}
	}
	mutex_unlock(&sparx5->mact_lock);

	return res;
}

static void sparx5_fdb_call_notifiers(enum switchdev_notifier_type type,
				      const char *mac, u16 vid,
				      struct net_device *dev, bool offloaded)
{
	struct switchdev_notifier_fdb_info info;

	info.addr = mac;
	info.vid = vid;
	info.offloaded = offloaded;
	call_switchdev_notifiers(type, dev, &info.info, NULL);
}

int sparx5_add_mact_entry(struct sparx5 *sparx5,
			  struct sparx5_port *port,
			  const unsigned char *addr, u16 vid)
{
	struct sparx5_mact_entry *mact_entry;
	int ret;

	ret = sparx5_mact_lookup(sparx5, addr, vid);
	if (ret)
		return 0;

	/* In case the entry already exists, don't add it again to SW,
	 * just update HW, but we need to look in the actual HW because
	 * it is possible for an entry to be learn by HW and before the
	 * mact thread to start the frame will reach CPU and the CPU will
	 * add the entry but without the extern_learn flag.
	 */
	mact_entry = find_mact_entry(sparx5, addr, vid, port->portno);
	if (mact_entry)
		goto update_hw;

	/* Add the entry in SW MAC table not to get the notification when
	 * SW is pulling again
	 */
	mact_entry = alloc_mact_entry(sparx5, addr, vid, port->portno);
	if (!mact_entry)
		return -ENOMEM;

	mutex_lock(&sparx5->mact_lock);
	list_add_tail(&mact_entry->list, &sparx5->mact_entries);
	mutex_unlock(&sparx5->mact_lock);

update_hw:
	ret = sparx5_mact_learn(sparx5, port->portno, addr, vid);

	/* New entry? */
	if (mact_entry->flags == 0) {
		mact_entry->flags |= MAC_ENT_LOCK; /* Don't age this */
		sparx5_fdb_call_notifiers(SWITCHDEV_FDB_ADD_TO_BRIDGE, addr, vid,
					  port->ndev, true);
	}

	return ret;
}

int sparx5_del_mact_entry(struct sparx5 *sparx5,
			  const unsigned char *addr,
			  u16 vid)
{
	struct sparx5_mact_entry *mact_entry, *tmp;

	/* Delete the entry in SW MAC table not to get the notification when
	 * SW is pulling again
	 */
	mutex_lock(&sparx5->mact_lock);
	list_for_each_entry_safe(mact_entry, tmp, &sparx5->mact_entries,
				 list) {
		if ((vid == 0 || mact_entry->vid == vid) &&
		    ether_addr_equal(addr, mact_entry->mac)) {
			list_del(&mact_entry->list);
			devm_kfree(sparx5->dev, mact_entry);

			sparx5_mact_forget(sparx5, addr, mact_entry->vid);
		}
	}
	mutex_unlock(&sparx5->mact_lock);

	return 0;
}

static void sparx5_mact_handle_entry(struct sparx5 *sparx5,
				     unsigned char mac[ETH_ALEN],
				     u16 vid, u32 cfg2)
{
	struct sparx5_mact_entry *mact_entry;
	bool found = false;
	u16 port;

	if (LRN_MAC_ACCESS_CFG_2_MAC_ENTRY_ADDR_TYPE_GET(cfg2) !=
	    MAC_ENTRY_ADDR_TYPE_UPSID_PN)
		return;

	port = LRN_MAC_ACCESS_CFG_2_MAC_ENTRY_ADDR_GET(cfg2);
	if (port >= SPX5_PORTS)
		return;

	if (!test_bit(port, sparx5->bridge_mask))
		return;

	mutex_lock(&sparx5->mact_lock);
	list_for_each_entry(mact_entry, &sparx5->mact_entries, list) {
		if (mact_entry->vid == vid &&
		    ether_addr_equal(mac, mact_entry->mac)) {
			found = true;
			mact_entry->flags |= MAC_ENT_ALIVE;
			if (mact_entry->port != port) {
				dev_warn(sparx5->dev, "Entry move: %d -> %d\n",
					 mact_entry->port, port);
				mact_entry->port = port;
				mact_entry->flags |= MAC_ENT_MOVED;
			}
			/* Entry handled */
			break;
		}
	}
	mutex_unlock(&sparx5->mact_lock);

	if (found && !(mact_entry->flags & MAC_ENT_MOVED))
		/* Present, not moved */
		return;

	if (!found) {
		/* Entry not found - now add */
		mact_entry = alloc_mact_entry(sparx5, mac, vid, port);
		if (!mact_entry)
			return;

		mact_entry->flags |= MAC_ENT_ALIVE;
		mutex_lock(&sparx5->mact_lock);
		list_add_tail(&mact_entry->list, &sparx5->mact_entries);
		mutex_unlock(&sparx5->mact_lock);
	}

	/* New or moved entry - notify bridge */
	sparx5_fdb_call_notifiers(SWITCHDEV_FDB_ADD_TO_BRIDGE,
				  mac, vid, sparx5->ports[port]->ndev,
				  true);
}

void sparx5_mact_pull_work(struct work_struct *work)
{
	struct delayed_work *del_work = to_delayed_work(work);
	struct sparx5 *sparx5 = container_of(del_work, struct sparx5,
					     mact_work);
	struct sparx5_mact_entry *mact_entry, *tmp;
	unsigned char mac[ETH_ALEN];
	u32 cfg2;
	u16 vid;
	int ret;

	/* Reset MAC entry flags */
	mutex_lock(&sparx5->mact_lock);
	list_for_each_entry(mact_entry, &sparx5->mact_entries, list)
		mact_entry->flags &= MAC_ENT_LOCK;
	mutex_unlock(&sparx5->mact_lock);

	/* MAIN mac address processing loop */
	vid = 0;
	memset(mac, 0, sizeof(mac));
	do {
		mutex_lock(&sparx5->lock);
		sparx5_mact_select(sparx5, mac, vid);
		spx5_wr(LRN_SCAN_NEXT_CFG_SCAN_NEXT_UNTIL_FOUND_ENA_SET(1),
			sparx5, LRN_SCAN_NEXT_CFG);
		spx5_wr(LRN_COMMON_ACCESS_CTRL_CPU_ACCESS_CMD_SET
			(MAC_CMD_FIND_SMALLEST) |
			LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT_SET(1),
			sparx5, LRN_COMMON_ACCESS_CTRL);
		ret = sparx5_mact_wait_for_completion(sparx5);
		if (ret == 0)
			ret = sparx5_mact_get(sparx5, mac, &vid, &cfg2);
		mutex_unlock(&sparx5->lock);
		if (ret == 0)
			sparx5_mact_handle_entry(sparx5, mac, vid, cfg2);
	} while (ret == 0);

	mutex_lock(&sparx5->mact_lock);
	list_for_each_entry_safe(mact_entry, tmp, &sparx5->mact_entries,
				 list) {
		/* If the entry is in HW or permanent, then skip */
		if (mact_entry->flags & (MAC_ENT_ALIVE | MAC_ENT_LOCK))
			continue;

		sparx5_fdb_call_notifiers(SWITCHDEV_FDB_DEL_TO_BRIDGE,
					  mact_entry->mac, mact_entry->vid,
					  sparx5->ports[mact_entry->port]->ndev,
					  true);

		list_del(&mact_entry->list);
		devm_kfree(sparx5->dev, mact_entry);
	}
	mutex_unlock(&sparx5->mact_lock);

	queue_delayed_work(sparx5->mact_queue, &sparx5->mact_work,
			   SPX5_MACT_PULL_DELAY);
}

void sparx5_set_ageing(struct sparx5 *sparx5, int msecs)
{
	int value = max(1, msecs / 10); /* unit 10 ms */

	spx5_rmw(LRN_AUTOAGE_CFG_UNIT_SIZE_SET(2) | /* 10 ms */
		 LRN_AUTOAGE_CFG_PERIOD_VAL_SET(value / 2), /* one bit ageing */
		 LRN_AUTOAGE_CFG_UNIT_SIZE |
		 LRN_AUTOAGE_CFG_PERIOD_VAL,
		 sparx5,
		 LRN_AUTOAGE_CFG(0));
}

void sparx5_mact_init(struct sparx5 *sparx5)
{
	mutex_init(&sparx5->lock);

	/*  Flush MAC table */
	spx5_wr(LRN_COMMON_ACCESS_CTRL_CPU_ACCESS_CMD_SET(MAC_CMD_CLEAR_ALL) |
		LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT_SET(1),
		sparx5, LRN_COMMON_ACCESS_CTRL);

	if (sparx5_mact_wait_for_completion(sparx5) != 0)
		dev_warn(sparx5->dev, "MAC flush error\n");

	sparx5_set_ageing(sparx5, BR_DEFAULT_AGEING_TIME / HZ * 1000);
}
