// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2018, 2020 NXP
 *
 */

#include <netdev.h>
#include <exports.h>
#include <fsl-mc/fsl_mc.h>
#include "lx2160a.h"

DECLARE_GLOBAL_DATA_PTR;

int board_eth_init(struct bd_info *bis)
{
#ifdef CONFIG_PHY_AQUANTIA
	/*
	 * Export functions to be used by AQ firmware
	 * upload application
	 */
	gd->jt->strcpy = strcpy;
	gd->jt->mdelay = mdelay;
	gd->jt->mdio_get_current_dev = mdio_get_current_dev;
	gd->jt->phy_find_by_mask = phy_find_by_mask;
	gd->jt->mdio_phydev_for_ethname = mdio_phydev_for_ethname;
	gd->jt->miiphy_set_current_dev = miiphy_set_current_dev;
#endif
	return pci_eth_init(bis);
}

#if defined(CONFIG_RESET_PHY_R)
void reset_phy(void)
{
#if defined(CONFIG_FSL_MC_ENET)
	mc_env_boot();
#endif
}
#endif /* CONFIG_RESET_PHY_R */

static int fdt_get_dpmac_node(void *fdt, int dpmac_id)
{
	char dpmac_str[11] = "dpmacs@00";
	int offset, dpmacs_offset;

	/* get the dpmac offset */
	dpmacs_offset = fdt_path_offset(fdt, "/soc/fsl-mc/dpmacs");
	if (dpmacs_offset < 0)
		dpmacs_offset = fdt_path_offset(fdt, "/fsl-mc/dpmacs");

	if (dpmacs_offset < 0) {
		printf("dpmacs node not found in device tree\n");
		return dpmacs_offset;
	}

	sprintf(dpmac_str, "dpmac@%x", dpmac_id);
	offset = fdt_subnode_offset(fdt, dpmacs_offset, dpmac_str);
	if (offset < 0) {
		sprintf(dpmac_str, "ethernet@%x", dpmac_id);
		offset = fdt_subnode_offset(fdt, dpmacs_offset, dpmac_str);
		if (offset < 0) {
			printf("dpmac@%x/ethernet@%x node not found in device tree\n",
			       dpmac_id, dpmac_id);
			return offset;
		}
	}

	return offset;
}

static int fdt_update_phy_addr(void *fdt, int dpmac_id, int phy_addr)
{
	char dpmac_str[] = "dpmacs@00";
	const u32 *phyhandle;
	int offset;
	int err;

	/* get the dpmac offset */
	offset = fdt_get_dpmac_node(fdt, dpmac_id);
	if (offset < 0)
		return offset;

	/* get dpmac phy-handle */
	sprintf(dpmac_str, "dpmac@%x", dpmac_id);
	phyhandle = (u32 *)fdt_getprop(fdt, offset, "phy-handle", NULL);
	if (!phyhandle) {
		printf("%s node not found in device tree\n", dpmac_str);
		return offset;
	}

	offset = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*phyhandle));
	if (offset < 0) {
		printf("Could not get the ph node offset for dpmac %d\n",
		       dpmac_id);
		return offset;
	}

	phy_addr = cpu_to_fdt32(phy_addr);
	err = fdt_setprop(fdt, offset, "reg", &phy_addr, sizeof(phy_addr));
	if (err < 0) {
		printf("Could not set phy node's reg for dpmac %d: %s.\n",
		       dpmac_id, fdt_strerror(err));
		return err;
	}

	return 0;
}

static int fdt_delete_phy_handle(void *fdt, int dpmac_id)
{
	const u32 *phyhandle;
	int offset;

	/* get the dpmac offset */
	offset = fdt_get_dpmac_node(fdt, dpmac_id);
	if (offset < 0)
		return offset;

	/* verify if the node has a phy-handle */
	phyhandle = (u32 *)fdt_getprop(fdt, offset, "phy-handle", NULL);
	if (!phyhandle)
		return 0;

	return fdt_delprop(fdt, offset, "phy-handle");
}

int fdt_fixup_board_phy_revc(void *fdt)
{
	int ret;

	if (get_board_rev() < 'C')
		return 0;

	/* DPMACs 3,4 have their Aquantia PHYs at new addresses */
	ret = fdt_update_phy_addr(fdt, 3, AQR113C_PHY_ADDR1);
	if (ret)
		return ret;

	ret = fdt_update_phy_addr(fdt, 4, AQR113C_PHY_ADDR2);
	if (ret)
		return ret;

	/* There is no PHY for the DPMAC2, so remove the phy-handle */
	return fdt_delete_phy_handle(fdt, 2);
}
