// SPDX-License-Identifier: GPL-2.0
/* Copyright Sunplus Technology Co., Ltd.
 *       All rights reserved.
 */

#include <linux/platform_device.h>
#include <linux/nvmem-consumer.h>
#include <linux/etherdevice.h>
#include <linux/netdevice.h>
#include <linux/spinlock.h>
#include <linux/of_net.h>
#include <linux/reset.h>
#include <linux/clk.h>
#include <linux/of.h>

#include "spl2sw_register.h"
#include "spl2sw_define.h"
#include "spl2sw_desc.h"
#include "spl2sw_mdio.h"
#include "spl2sw_phy.h"
#include "spl2sw_int.h"
#include "spl2sw_mac.h"

/* net device operations */
static int spl2sw_ethernet_open(struct net_device *ndev)
{
	struct spl2sw_mac *mac = netdev_priv(ndev);
	struct spl2sw_common *comm = mac->comm;
	u32 mask;

	netdev_dbg(ndev, "Open port = %x\n", mac->lan_port);

	comm->enable |= mac->lan_port;

	spl2sw_mac_hw_start(comm);

	/* Enable TX and RX interrupts */
	mask = readl(comm->l2sw_reg_base + L2SW_SW_INT_MASK_0);
	mask &= ~(MAC_INT_TX | MAC_INT_RX);
	writel(mask, comm->l2sw_reg_base + L2SW_SW_INT_MASK_0);

	phy_start(ndev->phydev);

	netif_start_queue(ndev);

	return 0;
}

static int spl2sw_ethernet_stop(struct net_device *ndev)
{
	struct spl2sw_mac *mac = netdev_priv(ndev);
	struct spl2sw_common *comm = mac->comm;

	netif_stop_queue(ndev);

	comm->enable &= ~mac->lan_port;

	phy_stop(ndev->phydev);

	spl2sw_mac_hw_stop(comm);

	return 0;
}

static netdev_tx_t spl2sw_ethernet_start_xmit(struct sk_buff *skb,
					      struct net_device *ndev)
{
	struct spl2sw_mac *mac = netdev_priv(ndev);
	struct spl2sw_common *comm = mac->comm;
	struct spl2sw_skb_info *skbinfo;
	struct spl2sw_mac_desc *txdesc;
	unsigned long flags;
	u32 mapping;
	u32 tx_pos;
	u32 cmd1;
	u32 cmd2;

	if (unlikely(comm->tx_desc_full == 1)) {
		/* No TX descriptors left. Wait for tx interrupt. */
		netdev_dbg(ndev, "TX descriptor queue full when xmit!\n");
		return NETDEV_TX_BUSY;
	}

	/* If skb size is shorter than ETH_ZLEN (60), pad it with 0. */
	if (unlikely(skb->len < ETH_ZLEN)) {
		if (skb_padto(skb, ETH_ZLEN))
			return NETDEV_TX_OK;

		skb_put(skb, ETH_ZLEN - skb->len);
	}

	mapping = dma_map_single(&comm->pdev->dev, skb->data,
				 skb->len, DMA_TO_DEVICE);
	if (dma_mapping_error(&comm->pdev->dev, mapping)) {
		ndev->stats.tx_errors++;
		dev_kfree_skb(skb);
		return NETDEV_TX_OK;
	}

	spin_lock_irqsave(&comm->tx_lock, flags);

	tx_pos = comm->tx_pos;
	txdesc = &comm->tx_desc[tx_pos];
	skbinfo = &comm->tx_temp_skb_info[tx_pos];
	skbinfo->mapping = mapping;
	skbinfo->len = skb->len;
	skbinfo->skb = skb;

	/* Set up a TX descriptor */
	cmd1 = TXD_OWN | TXD_SOP | TXD_EOP | (mac->to_vlan << 12) |
	       (skb->len & TXD_PKT_LEN);
	cmd2 = skb->len & TXD_BUF_LEN1;

	if (tx_pos == (TX_DESC_NUM - 1))
		cmd2 |= TXD_EOR;

	txdesc->addr1 = skbinfo->mapping;
	txdesc->cmd2 = cmd2;
	wmb();	/* Set TXD_OWN after other fields are effective. */
	txdesc->cmd1 = cmd1;

	/* Move tx_pos to next position */
	tx_pos = ((tx_pos + 1) == TX_DESC_NUM) ? 0 : tx_pos + 1;

	if (unlikely(tx_pos == comm->tx_done_pos)) {
		netif_stop_queue(ndev);
		comm->tx_desc_full = 1;
	}
	comm->tx_pos = tx_pos;
	wmb();		/* make sure settings are effective. */

	/* Trigger mac to transmit */
	writel(MAC_TRIG_L_SOC0, comm->l2sw_reg_base + L2SW_CPU_TX_TRIG);

	spin_unlock_irqrestore(&comm->tx_lock, flags);
	return NETDEV_TX_OK;
}

static void spl2sw_ethernet_set_rx_mode(struct net_device *ndev)
{
	struct spl2sw_mac *mac = netdev_priv(ndev);

	spl2sw_mac_rx_mode_set(mac);
}

static int spl2sw_ethernet_set_mac_address(struct net_device *ndev, void *addr)
{
	struct spl2sw_mac *mac = netdev_priv(ndev);
	int err;

	err = eth_mac_addr(ndev, addr);
	if (err)
		return err;

	/* Delete the old MAC address */
	netdev_dbg(ndev, "Old Ethernet (MAC) address = %pM\n", mac->mac_addr);
	if (is_valid_ether_addr(mac->mac_addr)) {
		err = spl2sw_mac_addr_del(mac);
		if (err)
			return err;
	}

	/* Set the MAC address */
	ether_addr_copy(mac->mac_addr, ndev->dev_addr);
	return spl2sw_mac_addr_add(mac);
}

static void spl2sw_ethernet_tx_timeout(struct net_device *ndev, unsigned int txqueue)
{
	struct spl2sw_mac *mac = netdev_priv(ndev);
	struct spl2sw_common *comm = mac->comm;
	unsigned long flags;
	int i;

	netdev_err(ndev, "TX timed out!\n");
	ndev->stats.tx_errors++;

	spin_lock_irqsave(&comm->tx_lock, flags);

	for (i = 0; i < MAX_NETDEV_NUM; i++)
		if (comm->ndev[i])
			netif_stop_queue(comm->ndev[i]);

	spl2sw_mac_soft_reset(comm);

	/* Accept TX packets again. */
	for (i = 0; i < MAX_NETDEV_NUM; i++)
		if (comm->ndev[i]) {
			netif_trans_update(comm->ndev[i]);
			netif_wake_queue(comm->ndev[i]);
		}

	spin_unlock_irqrestore(&comm->tx_lock, flags);
}

static const struct net_device_ops netdev_ops = {
	.ndo_open = spl2sw_ethernet_open,
	.ndo_stop = spl2sw_ethernet_stop,
	.ndo_start_xmit = spl2sw_ethernet_start_xmit,
	.ndo_set_rx_mode = spl2sw_ethernet_set_rx_mode,
	.ndo_set_mac_address = spl2sw_ethernet_set_mac_address,
	.ndo_do_ioctl = phy_do_ioctl,
	.ndo_tx_timeout = spl2sw_ethernet_tx_timeout,
};

static void spl2sw_check_mac_vendor_id_and_convert(u8 *mac_addr)
{
	/* Byte order of MAC address of some samples are reversed.
	 * Check vendor id and convert byte order if it is wrong.
	 * OUI of Sunplus: fc:4b:bc
	 */
	if (mac_addr[5] == 0xfc && mac_addr[4] == 0x4b && mac_addr[3] == 0xbc &&
	    (mac_addr[0] != 0xfc || mac_addr[1] != 0x4b || mac_addr[2] != 0xbc)) {

		swap(mac_addr[0], mac_addr[5]);
		swap(mac_addr[1], mac_addr[4]);
		swap(mac_addr[2], mac_addr[3]);
	}
}

static int spl2sw_nvmem_get_mac_address(struct device *dev, struct device_node *np,
					void *addrbuf)
{
	struct nvmem_cell *cell;
	ssize_t len;
	u8 *mac;

	/* Get nvmem cell of mac-address from dts. */
	cell = of_nvmem_cell_get(np, "mac-address");
	if (IS_ERR(cell))
		return PTR_ERR(cell);

	/* Read mac address from nvmem cell. */
	mac = nvmem_cell_read(cell, &len);
	nvmem_cell_put(cell);
	if (IS_ERR(mac))
		return PTR_ERR(mac);

	if (len != ETH_ALEN) {
		kfree(mac);
		dev_info(dev, "Invalid length of mac address in nvmem!\n");
		return -EINVAL;
	}

	/* Byte order of some samples are reversed.
	 * Convert byte order here.
	 */
	spl2sw_check_mac_vendor_id_and_convert(mac);

	/* Check if mac address is valid */
	if (!is_valid_ether_addr(mac)) {
		dev_info(dev, "Invalid mac address in nvmem (%pM)!\n", mac);
		kfree(mac);
		return -EINVAL;
	}

	ether_addr_copy(addrbuf, mac);
	kfree(mac);
	return 0;
}

static u32 spl2sw_init_netdev(struct platform_device *pdev, u8 *mac_addr,
			      struct net_device **r_ndev)
{
	struct net_device *ndev;
	struct spl2sw_mac *mac;
	int ret;

	/* Allocate the devices, and also allocate spl2sw_mac,
	 * we can get it by netdev_priv().
	 */
	ndev = devm_alloc_etherdev(&pdev->dev, sizeof(*mac));
	if (!ndev) {
		*r_ndev = NULL;
		return -ENOMEM;
	}
	SET_NETDEV_DEV(ndev, &pdev->dev);
	ndev->netdev_ops = &netdev_ops;
	mac = netdev_priv(ndev);
	mac->ndev = ndev;
	ether_addr_copy(mac->mac_addr, mac_addr);

	eth_hw_addr_set(ndev, mac_addr);
	dev_info(&pdev->dev, "Ethernet (MAC) address = %pM\n", mac_addr);

	ret = register_netdev(ndev);
	if (ret) {
		dev_err(&pdev->dev, "Failed to register net device \"%s\"!\n",
			ndev->name);
		*r_ndev = NULL;
		return ret;
	}
	netdev_dbg(ndev, "Registered net device \"%s\" successfully.\n", ndev->name);

	*r_ndev = ndev;
	return 0;
}

static struct device_node *spl2sw_get_eth_child_node(struct device_node *ether_np, int id)
{
	struct device_node *port_np;
	int port_id;

	for_each_child_of_node(ether_np, port_np) {
		/* It is not a 'port' node, continue. */
		if (strcmp(port_np->name, "port"))
			continue;

		if (of_property_read_u32(port_np, "reg", &port_id) < 0)
			continue;

		if (port_id == id)
			return port_np;
	}

	/* Not found! */
	return NULL;
}

static int spl2sw_probe(struct platform_device *pdev)
{
	struct device_node *eth_ports_np;
	struct device_node *port_np;
	struct spl2sw_common *comm;
	struct device_node *phy_np;
	phy_interface_t phy_mode;
	struct net_device *ndev;
	struct spl2sw_mac *mac;
	u8 mac_addr[ETH_ALEN];
	int irq, i, ret;

	if (platform_get_drvdata(pdev))
		return -ENODEV;

	/* Allocate memory for 'spl2sw_common' area. */
	comm = devm_kzalloc(&pdev->dev, sizeof(*comm), GFP_KERNEL);
	if (!comm)
		return -ENOMEM;

	comm->pdev = pdev;
	platform_set_drvdata(pdev, comm);

	spin_lock_init(&comm->tx_lock);
	spin_lock_init(&comm->mdio_lock);
	spin_lock_init(&comm->int_mask_lock);

	/* Get memory resource 0 from dts. */
	comm->l2sw_reg_base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(comm->l2sw_reg_base))
		return PTR_ERR(comm->l2sw_reg_base);

	/* Get irq resource from dts. */
	ret = platform_get_irq(pdev, 0);
	if (ret < 0)
		return ret;
	irq = ret;

	/* Get clock controller. */
	comm->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(comm->clk)) {
		dev_err_probe(&pdev->dev, PTR_ERR(comm->clk),
			      "Failed to retrieve clock controller!\n");
		return PTR_ERR(comm->clk);
	}

	/* Get reset controller. */
	comm->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
	if (IS_ERR(comm->rstc)) {
		dev_err_probe(&pdev->dev, PTR_ERR(comm->rstc),
			      "Failed to retrieve reset controller!\n");
		return PTR_ERR(comm->rstc);
	}

	/* Enable clock. */
	ret = clk_prepare_enable(comm->clk);
	if (ret)
		return ret;
	udelay(1);

	/* Reset MAC */
	reset_control_assert(comm->rstc);
	udelay(1);
	reset_control_deassert(comm->rstc);
	usleep_range(1000, 2000);

	/* Request irq. */
	ret = devm_request_irq(&pdev->dev, irq, spl2sw_ethernet_interrupt, 0,
			       dev_name(&pdev->dev), comm);
	if (ret) {
		dev_err(&pdev->dev, "Failed to request irq #%d!\n", irq);
		goto out_clk_disable;
	}

	/* Initialize TX and RX descriptors. */
	ret = spl2sw_descs_init(comm);
	if (ret) {
		dev_err(&pdev->dev, "Fail to initialize mac descriptors!\n");
		spl2sw_descs_free(comm);
		goto out_clk_disable;
	}

	/* Initialize MAC. */
	spl2sw_mac_init(comm);

	/* Initialize mdio bus */
	ret = spl2sw_mdio_init(comm);
	if (ret) {
		dev_err(&pdev->dev, "Failed to initialize mdio bus!\n");
		goto out_clk_disable;
	}

	/* Get child node ethernet-ports. */
	eth_ports_np = of_get_child_by_name(pdev->dev.of_node, "ethernet-ports");
	if (!eth_ports_np) {
		dev_err(&pdev->dev, "No ethernet-ports child node found!\n");
		ret = -ENODEV;
		goto out_free_mdio;
	}

	for (i = 0; i < MAX_NETDEV_NUM; i++) {
		/* Get port@i of node ethernet-ports. */
		port_np = spl2sw_get_eth_child_node(eth_ports_np, i);
		if (!port_np)
			continue;

		/* Get phy-mode. */
		if (of_get_phy_mode(port_np, &phy_mode)) {
			dev_err(&pdev->dev, "Failed to get phy-mode property of port@%d!\n",
				i);
			continue;
		}

		/* Get phy-handle. */
		phy_np = of_parse_phandle(port_np, "phy-handle", 0);
		if (!phy_np) {
			dev_err(&pdev->dev, "Failed to get phy-handle property of port@%d!\n",
				i);
			continue;
		}

		/* Get mac-address from nvmem. */
		ret = spl2sw_nvmem_get_mac_address(&pdev->dev, port_np, mac_addr);
		if (ret == -EPROBE_DEFER) {
			goto out_unregister_dev;
		} else if (ret) {
			dev_info(&pdev->dev, "Generate a random mac address!\n");
			eth_random_addr(mac_addr);
		}

		/* Initialize the net device. */
		ret = spl2sw_init_netdev(pdev, mac_addr, &ndev);
		if (ret)
			goto out_unregister_dev;

		ndev->irq = irq;
		comm->ndev[i] = ndev;
		mac = netdev_priv(ndev);
		mac->phy_node = phy_np;
		mac->phy_mode = phy_mode;
		mac->comm = comm;

		mac->lan_port = 0x1 << i;	/* forward to port i */
		mac->to_vlan = 0x1 << i;	/* vlan group: i     */
		mac->vlan_id = i;		/* vlan group: i     */

		/* Set MAC address */
		ret = spl2sw_mac_addr_add(mac);
		if (ret)
			goto out_unregister_dev;

		spl2sw_mac_rx_mode_set(mac);
	}

	/* Find first valid net device. */
	for (i = 0; i < MAX_NETDEV_NUM; i++) {
		if (comm->ndev[i])
			break;
	}
	if (i >= MAX_NETDEV_NUM) {
		dev_err(&pdev->dev, "No valid ethernet port!\n");
		ret = -ENODEV;
		goto out_free_mdio;
	}

	/* Save first valid net device */
	ndev = comm->ndev[i];

	ret = spl2sw_phy_connect(comm);
	if (ret) {
		netdev_err(ndev, "Failed to connect phy!\n");
		goto out_unregister_dev;
	}

	/* Add and enable napi. */
	netif_napi_add(ndev, &comm->rx_napi, spl2sw_rx_poll);
	napi_enable(&comm->rx_napi);
	netif_napi_add_tx(ndev, &comm->tx_napi, spl2sw_tx_poll);
	napi_enable(&comm->tx_napi);
	return 0;

out_unregister_dev:
	for (i = 0; i < MAX_NETDEV_NUM; i++)
		if (comm->ndev[i])
			unregister_netdev(comm->ndev[i]);

out_free_mdio:
	spl2sw_mdio_remove(comm);

out_clk_disable:
	clk_disable_unprepare(comm->clk);
	return ret;
}

static int spl2sw_remove(struct platform_device *pdev)
{
	struct spl2sw_common *comm;
	int i;

	comm = platform_get_drvdata(pdev);

	spl2sw_phy_remove(comm);

	/* Unregister and free net device. */
	for (i = 0; i < MAX_NETDEV_NUM; i++)
		if (comm->ndev[i])
			unregister_netdev(comm->ndev[i]);

	comm->enable = 0;
	spl2sw_mac_hw_stop(comm);
	spl2sw_descs_free(comm);

	/* Disable and delete napi. */
	napi_disable(&comm->rx_napi);
	netif_napi_del(&comm->rx_napi);
	napi_disable(&comm->tx_napi);
	netif_napi_del(&comm->tx_napi);

	spl2sw_mdio_remove(comm);

	clk_disable_unprepare(comm->clk);

	return 0;
}

static const struct of_device_id spl2sw_of_match[] = {
	{.compatible = "sunplus,sp7021-emac"},
	{ /* sentinel */ }
};

MODULE_DEVICE_TABLE(of, spl2sw_of_match);

static struct platform_driver spl2sw_driver = {
	.probe = spl2sw_probe,
	.remove = spl2sw_remove,
	.driver = {
		.name = "sp7021_emac",
		.of_match_table = spl2sw_of_match,
	},
};

module_platform_driver(spl2sw_driver);

MODULE_AUTHOR("Wells Lu <wellslutw@gmail.com>");
MODULE_DESCRIPTION("Sunplus Dual 10M/100M Ethernet driver");
MODULE_LICENSE("GPL");
