// SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause

/* Gigabit Ethernet driver for Mellanox BlueField SoC
 *
 * Copyright (C) 2020-2021 NVIDIA CORPORATION & AFFILIATES
 */

#include <linux/acpi.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/etherdevice.h>
#include <linux/interrupt.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
#include <linux/skbuff.h>

#include "mlxbf_gige.h"
#include "mlxbf_gige_regs.h"

#define DRV_NAME    "mlxbf_gige"

/* Allocate SKB whose payload pointer aligns with the Bluefield
 * hardware DMA limitation, i.e. DMA operation can't cross
 * a 4KB boundary.  A maximum packet size of 2KB is assumed in the
 * alignment formula.  The alignment logic overallocates an SKB,
 * and then adjusts the headroom so that the SKB data pointer is
 * naturally aligned to a 2KB boundary.
 */
struct sk_buff *mlxbf_gige_alloc_skb(struct mlxbf_gige *priv,
				     unsigned int map_len,
				     dma_addr_t *buf_dma,
				     enum dma_data_direction dir)
{
	struct sk_buff *skb;
	u64 addr, offset;

	/* Overallocate the SKB so that any headroom adjustment (to
	 * provide 2KB natural alignment) does not exceed payload area
	 */
	skb = netdev_alloc_skb(priv->netdev, MLXBF_GIGE_DEFAULT_BUF_SZ * 2);
	if (!skb)
		return NULL;

	/* Adjust the headroom so that skb->data is naturally aligned to
	 * a 2KB boundary, which is the maximum packet size supported.
	 */
	addr = (long)skb->data;
	offset = (addr + MLXBF_GIGE_DEFAULT_BUF_SZ - 1) &
		~(MLXBF_GIGE_DEFAULT_BUF_SZ - 1);
	offset -= addr;
	if (offset)
		skb_reserve(skb, offset);

	/* Return streaming DMA mapping to caller */
	*buf_dma = dma_map_single(priv->dev, skb->data, map_len, dir);
	if (dma_mapping_error(priv->dev, *buf_dma)) {
		dev_kfree_skb(skb);
		*buf_dma = (dma_addr_t)0;
		return NULL;
	}

	return skb;
}

static void mlxbf_gige_initial_mac(struct mlxbf_gige *priv)
{
	u8 mac[ETH_ALEN];
	u64 local_mac;

	memset(mac, 0, ETH_ALEN);
	mlxbf_gige_get_mac_rx_filter(priv, MLXBF_GIGE_LOCAL_MAC_FILTER_IDX,
				     &local_mac);
	u64_to_ether_addr(local_mac, mac);

	if (is_valid_ether_addr(mac)) {
		ether_addr_copy(priv->netdev->dev_addr, mac);
	} else {
		/* Provide a random MAC if for some reason the device has
		 * not been configured with a valid MAC address already.
		 */
		eth_hw_addr_random(priv->netdev);
	}

	local_mac = ether_addr_to_u64(priv->netdev->dev_addr);
	mlxbf_gige_set_mac_rx_filter(priv, MLXBF_GIGE_LOCAL_MAC_FILTER_IDX,
				     local_mac);
}

static void mlxbf_gige_cache_stats(struct mlxbf_gige *priv)
{
	struct mlxbf_gige_stats *p;

	/* Cache stats that will be cleared by clean port operation */
	p = &priv->stats;
	p->rx_din_dropped_pkts += readq(priv->base +
					MLXBF_GIGE_RX_DIN_DROP_COUNTER);
	p->rx_filter_passed_pkts += readq(priv->base +
					  MLXBF_GIGE_RX_PASS_COUNTER_ALL);
	p->rx_filter_discard_pkts += readq(priv->base +
					   MLXBF_GIGE_RX_DISC_COUNTER_ALL);
}

static int mlxbf_gige_clean_port(struct mlxbf_gige *priv)
{
	u64 control;
	u64 temp;
	int err;

	/* Set the CLEAN_PORT_EN bit to trigger SW reset */
	control = readq(priv->base + MLXBF_GIGE_CONTROL);
	control |= MLXBF_GIGE_CONTROL_CLEAN_PORT_EN;
	writeq(control, priv->base + MLXBF_GIGE_CONTROL);

	/* Ensure completion of "clean port" write before polling status */
	mb();

	err = readq_poll_timeout_atomic(priv->base + MLXBF_GIGE_STATUS, temp,
					(temp & MLXBF_GIGE_STATUS_READY),
					100, 100000);

	/* Clear the CLEAN_PORT_EN bit at end of this loop */
	control = readq(priv->base + MLXBF_GIGE_CONTROL);
	control &= ~MLXBF_GIGE_CONTROL_CLEAN_PORT_EN;
	writeq(control, priv->base + MLXBF_GIGE_CONTROL);

	return err;
}

static int mlxbf_gige_open(struct net_device *netdev)
{
	struct mlxbf_gige *priv = netdev_priv(netdev);
	struct phy_device *phydev = netdev->phydev;
	u64 int_en;
	int err;

	err = mlxbf_gige_request_irqs(priv);
	if (err)
		return err;
	mlxbf_gige_cache_stats(priv);
	err = mlxbf_gige_clean_port(priv);
	if (err)
		goto free_irqs;
	err = mlxbf_gige_rx_init(priv);
	if (err)
		goto free_irqs;
	err = mlxbf_gige_tx_init(priv);
	if (err)
		goto rx_deinit;

	phy_start(phydev);

	netif_napi_add(netdev, &priv->napi, mlxbf_gige_poll, NAPI_POLL_WEIGHT);
	napi_enable(&priv->napi);
	netif_start_queue(netdev);

	/* Set bits in INT_EN that we care about */
	int_en = MLXBF_GIGE_INT_EN_HW_ACCESS_ERROR |
		 MLXBF_GIGE_INT_EN_TX_CHECKSUM_INPUTS |
		 MLXBF_GIGE_INT_EN_TX_SMALL_FRAME_SIZE |
		 MLXBF_GIGE_INT_EN_TX_PI_CI_EXCEED_WQ_SIZE |
		 MLXBF_GIGE_INT_EN_SW_CONFIG_ERROR |
		 MLXBF_GIGE_INT_EN_SW_ACCESS_ERROR |
		 MLXBF_GIGE_INT_EN_RX_RECEIVE_PACKET;

	/* Ensure completion of all initialization before enabling interrupts */
	mb();

	writeq(int_en, priv->base + MLXBF_GIGE_INT_EN);

	return 0;

rx_deinit:
	mlxbf_gige_rx_deinit(priv);

free_irqs:
	mlxbf_gige_free_irqs(priv);
	return err;
}

static int mlxbf_gige_stop(struct net_device *netdev)
{
	struct mlxbf_gige *priv = netdev_priv(netdev);

	writeq(0, priv->base + MLXBF_GIGE_INT_EN);
	netif_stop_queue(netdev);
	napi_disable(&priv->napi);
	netif_napi_del(&priv->napi);
	mlxbf_gige_free_irqs(priv);

	phy_stop(netdev->phydev);

	mlxbf_gige_rx_deinit(priv);
	mlxbf_gige_tx_deinit(priv);
	mlxbf_gige_cache_stats(priv);
	mlxbf_gige_clean_port(priv);

	return 0;
}

static int mlxbf_gige_do_ioctl(struct net_device *netdev,
			       struct ifreq *ifr, int cmd)
{
	if (!(netif_running(netdev)))
		return -EINVAL;

	return phy_mii_ioctl(netdev->phydev, ifr, cmd);
}

static void mlxbf_gige_set_rx_mode(struct net_device *netdev)
{
	struct mlxbf_gige *priv = netdev_priv(netdev);
	bool new_promisc_enabled;

	new_promisc_enabled = netdev->flags & IFF_PROMISC;

	/* Only write to the hardware registers if the new setting
	 * of promiscuous mode is different from the current one.
	 */
	if (new_promisc_enabled != priv->promisc_enabled) {
		priv->promisc_enabled = new_promisc_enabled;

		if (new_promisc_enabled)
			mlxbf_gige_enable_promisc(priv);
		else
			mlxbf_gige_disable_promisc(priv);
	}
}

static void mlxbf_gige_get_stats64(struct net_device *netdev,
				   struct rtnl_link_stats64 *stats)
{
	struct mlxbf_gige *priv = netdev_priv(netdev);

	netdev_stats_to_stats64(stats, &netdev->stats);

	stats->rx_length_errors = priv->stats.rx_truncate_errors;
	stats->rx_fifo_errors = priv->stats.rx_din_dropped_pkts +
				readq(priv->base + MLXBF_GIGE_RX_DIN_DROP_COUNTER);
	stats->rx_crc_errors = priv->stats.rx_mac_errors;
	stats->rx_errors = stats->rx_length_errors +
			   stats->rx_fifo_errors +
			   stats->rx_crc_errors;

	stats->tx_fifo_errors = priv->stats.tx_fifo_full;
	stats->tx_errors = stats->tx_fifo_errors;
}

static const struct net_device_ops mlxbf_gige_netdev_ops = {
	.ndo_open		= mlxbf_gige_open,
	.ndo_stop		= mlxbf_gige_stop,
	.ndo_start_xmit		= mlxbf_gige_start_xmit,
	.ndo_set_mac_address	= eth_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_do_ioctl		= mlxbf_gige_do_ioctl,
	.ndo_set_rx_mode        = mlxbf_gige_set_rx_mode,
	.ndo_get_stats64        = mlxbf_gige_get_stats64,
};

static void mlxbf_gige_adjust_link(struct net_device *netdev)
{
	struct phy_device *phydev = netdev->phydev;

	phy_print_status(phydev);
}

static int mlxbf_gige_probe(struct platform_device *pdev)
{
	struct phy_device *phydev;
	struct net_device *netdev;
	struct resource *mac_res;
	struct resource *llu_res;
	struct resource *plu_res;
	struct mlxbf_gige *priv;
	void __iomem *llu_base;
	void __iomem *plu_base;
	void __iomem *base;
	u64 control;
	int addr;
	int err;

	mac_res = platform_get_resource(pdev, IORESOURCE_MEM, MLXBF_GIGE_RES_MAC);
	if (!mac_res)
		return -ENXIO;

	base = devm_ioremap_resource(&pdev->dev, mac_res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	llu_res = platform_get_resource(pdev, IORESOURCE_MEM, MLXBF_GIGE_RES_LLU);
	if (!llu_res)
		return -ENXIO;

	llu_base = devm_ioremap_resource(&pdev->dev, llu_res);
	if (IS_ERR(llu_base))
		return PTR_ERR(llu_base);

	plu_res = platform_get_resource(pdev, IORESOURCE_MEM, MLXBF_GIGE_RES_PLU);
	if (!plu_res)
		return -ENXIO;

	plu_base = devm_ioremap_resource(&pdev->dev, plu_res);
	if (IS_ERR(plu_base))
		return PTR_ERR(plu_base);

	/* Perform general init of GigE block */
	control = readq(base + MLXBF_GIGE_CONTROL);
	control |= MLXBF_GIGE_CONTROL_PORT_EN;
	writeq(control, base + MLXBF_GIGE_CONTROL);

	netdev = devm_alloc_etherdev(&pdev->dev, sizeof(*priv));
	if (!netdev)
		return -ENOMEM;

	SET_NETDEV_DEV(netdev, &pdev->dev);
	netdev->netdev_ops = &mlxbf_gige_netdev_ops;
	netdev->ethtool_ops = &mlxbf_gige_ethtool_ops;
	priv = netdev_priv(netdev);
	priv->netdev = netdev;

	platform_set_drvdata(pdev, priv);
	priv->dev = &pdev->dev;
	priv->pdev = pdev;

	spin_lock_init(&priv->lock);
	spin_lock_init(&priv->gpio_lock);

	/* Attach MDIO device */
	err = mlxbf_gige_mdio_probe(pdev, priv);
	if (err)
		return err;

	err = mlxbf_gige_gpio_init(pdev, priv);
	if (err) {
		dev_err(&pdev->dev, "PHY IRQ initialization failed\n");
		mlxbf_gige_mdio_remove(priv);
		return -ENODEV;
	}

	priv->base = base;
	priv->llu_base = llu_base;
	priv->plu_base = plu_base;

	priv->rx_q_entries = MLXBF_GIGE_DEFAULT_RXQ_SZ;
	priv->tx_q_entries = MLXBF_GIGE_DEFAULT_TXQ_SZ;

	/* Write initial MAC address to hardware */
	mlxbf_gige_initial_mac(priv);

	err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
	if (err) {
		dev_err(&pdev->dev, "DMA configuration failed: 0x%x\n", err);
		goto out;
	}

	priv->error_irq = platform_get_irq(pdev, MLXBF_GIGE_ERROR_INTR_IDX);
	priv->rx_irq = platform_get_irq(pdev, MLXBF_GIGE_RECEIVE_PKT_INTR_IDX);
	priv->llu_plu_irq = platform_get_irq(pdev, MLXBF_GIGE_LLU_PLU_INTR_IDX);

	phydev = phy_find_first(priv->mdiobus);
	if (!phydev) {
		err = -ENODEV;
		goto out;
	}

	addr = phydev->mdio.addr;
	priv->mdiobus->irq[addr] = priv->phy_irq;
	phydev->irq = priv->phy_irq;

	err = phy_connect_direct(netdev, phydev,
				 mlxbf_gige_adjust_link,
				 PHY_INTERFACE_MODE_GMII);
	if (err) {
		dev_err(&pdev->dev, "Could not attach to PHY\n");
		goto out;
	}

	/* MAC only supports 1000T full duplex mode */
	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Full_BIT);
	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT);
	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT);

	/* Only symmetric pause with flow control enabled is supported so no
	 * need to negotiate pause.
	 */
	linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->advertising);
	linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->advertising);

	/* Display information about attached PHY device */
	phy_attached_info(phydev);

	err = register_netdev(netdev);
	if (err) {
		dev_err(&pdev->dev, "Failed to register netdev\n");
		phy_disconnect(phydev);
		goto out;
	}

	return 0;

out:
	mlxbf_gige_gpio_free(priv);
	mlxbf_gige_mdio_remove(priv);
	return err;
}

static int mlxbf_gige_remove(struct platform_device *pdev)
{
	struct mlxbf_gige *priv = platform_get_drvdata(pdev);

	unregister_netdev(priv->netdev);
	phy_disconnect(priv->netdev->phydev);
	mlxbf_gige_gpio_free(priv);
	mlxbf_gige_mdio_remove(priv);
	platform_set_drvdata(pdev, NULL);

	return 0;
}

static void mlxbf_gige_shutdown(struct platform_device *pdev)
{
	struct mlxbf_gige *priv = platform_get_drvdata(pdev);

	writeq(0, priv->base + MLXBF_GIGE_INT_EN);
	mlxbf_gige_clean_port(priv);
}

static const struct acpi_device_id __maybe_unused mlxbf_gige_acpi_match[] = {
	{ "MLNXBF17", 0 },
	{},
};
MODULE_DEVICE_TABLE(acpi, mlxbf_gige_acpi_match);

static struct platform_driver mlxbf_gige_driver = {
	.probe = mlxbf_gige_probe,
	.remove = mlxbf_gige_remove,
	.shutdown = mlxbf_gige_shutdown,
	.driver = {
		.name = DRV_NAME,
		.acpi_match_table = ACPI_PTR(mlxbf_gige_acpi_match),
	},
};

module_platform_driver(mlxbf_gige_driver);

MODULE_DESCRIPTION("Mellanox BlueField SoC Gigabit Ethernet Driver");
MODULE_AUTHOR("David Thompson <davthompson@nvidia.com>");
MODULE_AUTHOR("Asmaa Mnebhi <asmaa@nvidia.com>");
MODULE_LICENSE("Dual BSD/GPL");
