// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
 * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
 * stmmac XGMAC support.
 */

#include <linux/bitrev.h>
#include <linux/crc32.h>
#include "stmmac.h"
#include "dwxgmac2.h"

static void dwxgmac2_core_init(struct mac_device_info *hw,
			       struct net_device *dev)
{
	void __iomem *ioaddr = hw->pcsr;
	int mtu = dev->mtu;
	u32 tx, rx;

	tx = readl(ioaddr + XGMAC_TX_CONFIG);
	rx = readl(ioaddr + XGMAC_RX_CONFIG);

	tx |= XGMAC_CORE_INIT_TX;
	rx |= XGMAC_CORE_INIT_RX;

	if (mtu >= 9000) {
		rx |= XGMAC_CONFIG_GPSLCE;
		rx |= XGMAC_JUMBO_LEN << XGMAC_CONFIG_GPSL_SHIFT;
		rx |= XGMAC_CONFIG_WD;
	} else if (mtu > 2000) {
		rx |= XGMAC_CONFIG_JE;
	} else if (mtu > 1500) {
		rx |= XGMAC_CONFIG_S2KP;
	}

	if (hw->ps) {
		tx |= XGMAC_CONFIG_TE;
		tx &= ~hw->link.speed_mask;

		switch (hw->ps) {
		case SPEED_10000:
			tx |= hw->link.xgmii.speed10000;
			break;
		case SPEED_2500:
			tx |= hw->link.speed2500;
			break;
		case SPEED_1000:
		default:
			tx |= hw->link.speed1000;
			break;
		}
	}

	writel(tx, ioaddr + XGMAC_TX_CONFIG);
	writel(rx, ioaddr + XGMAC_RX_CONFIG);
	writel(XGMAC_INT_DEFAULT_EN, ioaddr + XGMAC_INT_EN);
}

static void dwxgmac2_set_mac(void __iomem *ioaddr, bool enable)
{
	u32 tx = readl(ioaddr + XGMAC_TX_CONFIG);
	u32 rx = readl(ioaddr + XGMAC_RX_CONFIG);

	if (enable) {
		tx |= XGMAC_CONFIG_TE;
		rx |= XGMAC_CONFIG_RE;
	} else {
		tx &= ~XGMAC_CONFIG_TE;
		rx &= ~XGMAC_CONFIG_RE;
	}

	writel(tx, ioaddr + XGMAC_TX_CONFIG);
	writel(rx, ioaddr + XGMAC_RX_CONFIG);
}

static int dwxgmac2_rx_ipc(struct mac_device_info *hw)
{
	void __iomem *ioaddr = hw->pcsr;
	u32 value;

	value = readl(ioaddr + XGMAC_RX_CONFIG);
	if (hw->rx_csum)
		value |= XGMAC_CONFIG_IPC;
	else
		value &= ~XGMAC_CONFIG_IPC;
	writel(value, ioaddr + XGMAC_RX_CONFIG);

	return !!(readl(ioaddr + XGMAC_RX_CONFIG) & XGMAC_CONFIG_IPC);
}

static void dwxgmac2_rx_queue_enable(struct mac_device_info *hw, u8 mode,
				     u32 queue)
{
	void __iomem *ioaddr = hw->pcsr;
	u32 value;

	value = readl(ioaddr + XGMAC_RXQ_CTRL0) & ~XGMAC_RXQEN(queue);
	if (mode == MTL_QUEUE_AVB)
		value |= 0x1 << XGMAC_RXQEN_SHIFT(queue);
	else if (mode == MTL_QUEUE_DCB)
		value |= 0x2 << XGMAC_RXQEN_SHIFT(queue);
	writel(value, ioaddr + XGMAC_RXQ_CTRL0);
}

static void dwxgmac2_rx_queue_prio(struct mac_device_info *hw, u32 prio,
				   u32 queue)
{
	void __iomem *ioaddr = hw->pcsr;
	u32 value, reg;

	reg = (queue < 4) ? XGMAC_RXQ_CTRL2 : XGMAC_RXQ_CTRL3;
	if (queue >= 4)
		queue -= 4;

	value = readl(ioaddr + reg);
	value &= ~XGMAC_PSRQ(queue);
	value |= (prio << XGMAC_PSRQ_SHIFT(queue)) & XGMAC_PSRQ(queue);

	writel(value, ioaddr + reg);
}

static void dwxgmac2_prog_mtl_rx_algorithms(struct mac_device_info *hw,
					    u32 rx_alg)
{
	void __iomem *ioaddr = hw->pcsr;
	u32 value;

	value = readl(ioaddr + XGMAC_MTL_OPMODE);
	value &= ~XGMAC_RAA;

	switch (rx_alg) {
	case MTL_RX_ALGORITHM_SP:
		break;
	case MTL_RX_ALGORITHM_WSP:
		value |= XGMAC_RAA;
		break;
	default:
		break;
	}

	writel(value, ioaddr + XGMAC_MTL_OPMODE);
}

static void dwxgmac2_prog_mtl_tx_algorithms(struct mac_device_info *hw,
					    u32 tx_alg)
{
	void __iomem *ioaddr = hw->pcsr;
	u32 value;

	value = readl(ioaddr + XGMAC_MTL_OPMODE);
	value &= ~XGMAC_ETSALG;

	switch (tx_alg) {
	case MTL_TX_ALGORITHM_WRR:
		value |= XGMAC_WRR;
		break;
	case MTL_TX_ALGORITHM_WFQ:
		value |= XGMAC_WFQ;
		break;
	case MTL_TX_ALGORITHM_DWRR:
		value |= XGMAC_DWRR;
		break;
	default:
		break;
	}

	writel(value, ioaddr + XGMAC_MTL_OPMODE);
}

static void dwxgmac2_map_mtl_to_dma(struct mac_device_info *hw, u32 queue,
				    u32 chan)
{
	void __iomem *ioaddr = hw->pcsr;
	u32 value, reg;

	reg = (queue < 4) ? XGMAC_MTL_RXQ_DMA_MAP0 : XGMAC_MTL_RXQ_DMA_MAP1;
	if (queue >= 4)
		queue -= 4;

	value = readl(ioaddr + reg);
	value &= ~XGMAC_QxMDMACH(queue);
	value |= (chan << XGMAC_QxMDMACH_SHIFT(queue)) & XGMAC_QxMDMACH(queue);

	writel(value, ioaddr + reg);
}

static void dwxgmac2_config_cbs(struct mac_device_info *hw,
				u32 send_slope, u32 idle_slope,
				u32 high_credit, u32 low_credit, u32 queue)
{
	void __iomem *ioaddr = hw->pcsr;
	u32 value;

	writel(send_slope, ioaddr + XGMAC_MTL_TCx_SENDSLOPE(queue));
	writel(idle_slope, ioaddr + XGMAC_MTL_TCx_QUANTUM_WEIGHT(queue));
	writel(high_credit, ioaddr + XGMAC_MTL_TCx_HICREDIT(queue));
	writel(low_credit, ioaddr + XGMAC_MTL_TCx_LOCREDIT(queue));

	value = readl(ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(queue));
	value |= XGMAC_CC | XGMAC_CBS;
	writel(value, ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(queue));
}

static int dwxgmac2_host_irq_status(struct mac_device_info *hw,
				    struct stmmac_extra_stats *x)
{
	void __iomem *ioaddr = hw->pcsr;
	u32 stat, en;

	en = readl(ioaddr + XGMAC_INT_EN);
	stat = readl(ioaddr + XGMAC_INT_STATUS);

	stat &= en;

	if (stat & XGMAC_PMTIS) {
		x->irq_receive_pmt_irq_n++;
		readl(ioaddr + XGMAC_PMT);
	}

	return 0;
}

static int dwxgmac2_host_mtl_irq_status(struct mac_device_info *hw, u32 chan)
{
	void __iomem *ioaddr = hw->pcsr;
	int ret = 0;
	u32 status;

	status = readl(ioaddr + XGMAC_MTL_INT_STATUS);
	if (status & BIT(chan)) {
		u32 chan_status = readl(ioaddr + XGMAC_MTL_QINT_STATUS(chan));

		if (chan_status & XGMAC_RXOVFIS)
			ret |= CORE_IRQ_MTL_RX_OVERFLOW;

		writel(~0x0, ioaddr + XGMAC_MTL_QINT_STATUS(chan));
	}

	return ret;
}

static void dwxgmac2_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
			       unsigned int fc, unsigned int pause_time,
			       u32 tx_cnt)
{
	void __iomem *ioaddr = hw->pcsr;
	u32 i;

	if (fc & FLOW_RX)
		writel(XGMAC_RFE, ioaddr + XGMAC_RX_FLOW_CTRL);
	if (fc & FLOW_TX) {
		for (i = 0; i < tx_cnt; i++) {
			u32 value = XGMAC_TFE;

			if (duplex)
				value |= pause_time << XGMAC_PT_SHIFT;

			writel(value, ioaddr + XGMAC_Qx_TX_FLOW_CTRL(i));
		}
	}
}

static void dwxgmac2_pmt(struct mac_device_info *hw, unsigned long mode)
{
	void __iomem *ioaddr = hw->pcsr;
	u32 val = 0x0;

	if (mode & WAKE_MAGIC)
		val |= XGMAC_PWRDWN | XGMAC_MGKPKTEN;
	if (mode & WAKE_UCAST)
		val |= XGMAC_PWRDWN | XGMAC_GLBLUCAST | XGMAC_RWKPKTEN;
	if (val) {
		u32 cfg = readl(ioaddr + XGMAC_RX_CONFIG);
		cfg |= XGMAC_CONFIG_RE;
		writel(cfg, ioaddr + XGMAC_RX_CONFIG);
	}

	writel(val, ioaddr + XGMAC_PMT);
}

static void dwxgmac2_set_umac_addr(struct mac_device_info *hw,
				   unsigned char *addr, unsigned int reg_n)
{
	void __iomem *ioaddr = hw->pcsr;
	u32 value;

	value = (addr[5] << 8) | addr[4];
	writel(value | XGMAC_AE, ioaddr + XGMAC_ADDRx_HIGH(reg_n));

	value = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
	writel(value, ioaddr + XGMAC_ADDRx_LOW(reg_n));
}

static void dwxgmac2_get_umac_addr(struct mac_device_info *hw,
				   unsigned char *addr, unsigned int reg_n)
{
	void __iomem *ioaddr = hw->pcsr;
	u32 hi_addr, lo_addr;

	/* Read the MAC address from the hardware */
	hi_addr = readl(ioaddr + XGMAC_ADDRx_HIGH(reg_n));
	lo_addr = readl(ioaddr + XGMAC_ADDRx_LOW(reg_n));

	/* Extract the MAC address from the high and low words */
	addr[0] = lo_addr & 0xff;
	addr[1] = (lo_addr >> 8) & 0xff;
	addr[2] = (lo_addr >> 16) & 0xff;
	addr[3] = (lo_addr >> 24) & 0xff;
	addr[4] = hi_addr & 0xff;
	addr[5] = (hi_addr >> 8) & 0xff;
}

static void dwxgmac2_set_mchash(void __iomem *ioaddr, u32 *mcfilterbits,
				int mcbitslog2)
{
	int numhashregs, regs;

	switch (mcbitslog2) {
	case 6:
		numhashregs = 2;
		break;
	case 7:
		numhashregs = 4;
		break;
	case 8:
		numhashregs = 8;
		break;
	default:
		return;
	}

	for (regs = 0; regs < numhashregs; regs++)
		writel(mcfilterbits[regs], ioaddr + XGMAC_HASH_TABLE(regs));
}

static void dwxgmac2_set_filter(struct mac_device_info *hw,
				struct net_device *dev)
{
	void __iomem *ioaddr = (void __iomem *)dev->base_addr;
	u32 value = readl(ioaddr + XGMAC_PACKET_FILTER);
	int mcbitslog2 = hw->mcast_bits_log2;
	u32 mc_filter[8];
	int i;

	value &= ~(XGMAC_FILTER_PR | XGMAC_FILTER_HMC | XGMAC_FILTER_PM);
	value |= XGMAC_FILTER_HPF;

	memset(mc_filter, 0, sizeof(mc_filter));

	if (dev->flags & IFF_PROMISC) {
		value |= XGMAC_FILTER_PR;
		value |= XGMAC_FILTER_PCF;
	} else if ((dev->flags & IFF_ALLMULTI) ||
		   (netdev_mc_count(dev) > hw->multicast_filter_bins)) {
		value |= XGMAC_FILTER_PM;

		for (i = 0; i < XGMAC_MAX_HASH_TABLE; i++)
			writel(~0x0, ioaddr + XGMAC_HASH_TABLE(i));
	} else if (!netdev_mc_empty(dev)) {
		struct netdev_hw_addr *ha;

		value |= XGMAC_FILTER_HMC;

		netdev_for_each_mc_addr(ha, dev) {
			int nr = (bitrev32(~crc32_le(~0, ha->addr, 6)) >>
					(32 - mcbitslog2));
			mc_filter[nr >> 5] |= (1 << (nr & 0x1F));
		}
	}

	dwxgmac2_set_mchash(ioaddr, mc_filter, mcbitslog2);

	/* Handle multiple unicast addresses */
	if (netdev_uc_count(dev) > XGMAC_ADDR_MAX) {
		value |= XGMAC_FILTER_PR;
	} else {
		struct netdev_hw_addr *ha;
		int reg = 1;

		netdev_for_each_uc_addr(ha, dev) {
			dwxgmac2_set_umac_addr(hw, ha->addr, reg);
			reg++;
		}

		for ( ; reg < XGMAC_ADDR_MAX; reg++) {
			writel(0, ioaddr + XGMAC_ADDRx_HIGH(reg));
			writel(0, ioaddr + XGMAC_ADDRx_LOW(reg));
		}
	}

	writel(value, ioaddr + XGMAC_PACKET_FILTER);
}

static void dwxgmac2_set_mac_loopback(void __iomem *ioaddr, bool enable)
{
	u32 value = readl(ioaddr + XGMAC_RX_CONFIG);

	if (enable)
		value |= XGMAC_CONFIG_LM;
	else
		value &= ~XGMAC_CONFIG_LM;

	writel(value, ioaddr + XGMAC_RX_CONFIG);
}

const struct stmmac_ops dwxgmac210_ops = {
	.core_init = dwxgmac2_core_init,
	.set_mac = dwxgmac2_set_mac,
	.rx_ipc = dwxgmac2_rx_ipc,
	.rx_queue_enable = dwxgmac2_rx_queue_enable,
	.rx_queue_prio = dwxgmac2_rx_queue_prio,
	.tx_queue_prio = NULL,
	.rx_queue_routing = NULL,
	.prog_mtl_rx_algorithms = dwxgmac2_prog_mtl_rx_algorithms,
	.prog_mtl_tx_algorithms = dwxgmac2_prog_mtl_tx_algorithms,
	.set_mtl_tx_queue_weight = NULL,
	.map_mtl_to_dma = dwxgmac2_map_mtl_to_dma,
	.config_cbs = dwxgmac2_config_cbs,
	.dump_regs = NULL,
	.host_irq_status = dwxgmac2_host_irq_status,
	.host_mtl_irq_status = dwxgmac2_host_mtl_irq_status,
	.flow_ctrl = dwxgmac2_flow_ctrl,
	.pmt = dwxgmac2_pmt,
	.set_umac_addr = dwxgmac2_set_umac_addr,
	.get_umac_addr = dwxgmac2_get_umac_addr,
	.set_eee_mode = NULL,
	.reset_eee_mode = NULL,
	.set_eee_timer = NULL,
	.set_eee_pls = NULL,
	.pcs_ctrl_ane = NULL,
	.pcs_rane = NULL,
	.pcs_get_adv_lp = NULL,
	.debug = NULL,
	.set_filter = dwxgmac2_set_filter,
	.set_mac_loopback = dwxgmac2_set_mac_loopback,
};

int dwxgmac2_setup(struct stmmac_priv *priv)
{
	struct mac_device_info *mac = priv->hw;

	dev_info(priv->device, "\tXGMAC2\n");

	priv->dev->priv_flags |= IFF_UNICAST_FLT;
	mac->pcsr = priv->ioaddr;
	mac->multicast_filter_bins = priv->plat->multicast_filter_bins;
	mac->unicast_filter_entries = priv->plat->unicast_filter_entries;
	mac->mcast_bits_log2 = 0;

	if (mac->multicast_filter_bins)
		mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);

	mac->link.duplex = 0;
	mac->link.speed10 = XGMAC_CONFIG_SS_10_MII;
	mac->link.speed100 = XGMAC_CONFIG_SS_100_MII;
	mac->link.speed1000 = XGMAC_CONFIG_SS_1000_GMII;
	mac->link.speed2500 = XGMAC_CONFIG_SS_2500_GMII;
	mac->link.xgmii.speed2500 = XGMAC_CONFIG_SS_2500;
	mac->link.xgmii.speed5000 = XGMAC_CONFIG_SS_5000;
	mac->link.xgmii.speed10000 = XGMAC_CONFIG_SS_10000;
	mac->link.speed_mask = XGMAC_CONFIG_SS_MASK;

	mac->mii.addr = XGMAC_MDIO_ADDR;
	mac->mii.data = XGMAC_MDIO_DATA;
	mac->mii.addr_shift = 16;
	mac->mii.addr_mask = GENMASK(20, 16);
	mac->mii.reg_shift = 0;
	mac->mii.reg_mask = GENMASK(15, 0);
	mac->mii.clk_csr_shift = 19;
	mac->mii.clk_csr_mask = GENMASK(21, 19);

	return 0;
}
