// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (c) 2014-2015 Hisilicon Limited.
 */

#include "hns_dsaf_mac.h"
#include "hns_dsaf_misc.h"
#include "hns_dsaf_ppe.h"
#include "hns_dsaf_reg.h"

enum _dsm_op_index {
	HNS_OP_RESET_FUNC               = 0x1,
	HNS_OP_SERDES_LP_FUNC           = 0x2,
	HNS_OP_LED_SET_FUNC             = 0x3,
	HNS_OP_GET_PORT_TYPE_FUNC       = 0x4,
	HNS_OP_GET_SFP_STAT_FUNC        = 0x5,
	HNS_OP_LOCATE_LED_SET_FUNC      = 0x6,
};

enum _dsm_rst_type {
	HNS_DSAF_RESET_FUNC     = 0x1,
	HNS_PPE_RESET_FUNC      = 0x2,
	HNS_XGE_RESET_FUNC      = 0x4,
	HNS_GE_RESET_FUNC       = 0x5,
	HNS_DSAF_CHN_RESET_FUNC = 0x6,
	HNS_ROCE_RESET_FUNC     = 0x7,
};

static const guid_t hns_dsaf_acpi_dsm_guid =
	GUID_INIT(0x1A85AA1A, 0xE293, 0x415E,
		  0x8E, 0x28, 0x8D, 0x69, 0x0A, 0x0F, 0x82, 0x0A);

static void dsaf_write_sub(struct dsaf_device *dsaf_dev, u32 reg, u32 val)
{
	if (dsaf_dev->sub_ctrl)
		dsaf_write_syscon(dsaf_dev->sub_ctrl, reg, val);
	else
		dsaf_write_reg(dsaf_dev->sc_base, reg, val);
}

static u32 dsaf_read_sub(struct dsaf_device *dsaf_dev, u32 reg)
{
	u32 ret = 0;
	int err;

	if (dsaf_dev->sub_ctrl) {
		err = dsaf_read_syscon(dsaf_dev->sub_ctrl, reg, &ret);
		if (err)
			dev_err(dsaf_dev->dev, "dsaf_read_syscon error %d!\n",
				err);
	} else {
		ret = dsaf_read_reg(dsaf_dev->sc_base, reg);
	}

	return ret;
}

static void hns_dsaf_acpi_ledctrl_by_port(struct hns_mac_cb *mac_cb, u8 op_type,
					  u32 link, u32 port, u32 act)
{
	union acpi_object *obj;
	union acpi_object obj_args[3], argv4;

	obj_args[0].integer.type = ACPI_TYPE_INTEGER;
	obj_args[0].integer.value = link;
	obj_args[1].integer.type = ACPI_TYPE_INTEGER;
	obj_args[1].integer.value = port;
	obj_args[2].integer.type = ACPI_TYPE_INTEGER;
	obj_args[2].integer.value = act;

	argv4.type = ACPI_TYPE_PACKAGE;
	argv4.package.count = 3;
	argv4.package.elements = obj_args;

	obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev),
				&hns_dsaf_acpi_dsm_guid, 0, op_type, &argv4);
	if (!obj) {
		dev_warn(mac_cb->dev, "ledctrl fail, link:%d port:%d act:%d!\n",
			 link, port, act);
		return;
	}

	ACPI_FREE(obj);
}

static void hns_dsaf_acpi_locate_ledctrl_by_port(struct hns_mac_cb *mac_cb,
						 u8 op_type, u32 locate,
						 u32 port)
{
	union acpi_object obj_args[2], argv4;
	union acpi_object *obj;

	obj_args[0].integer.type = ACPI_TYPE_INTEGER;
	obj_args[0].integer.value = locate;
	obj_args[1].integer.type = ACPI_TYPE_INTEGER;
	obj_args[1].integer.value = port;

	argv4.type = ACPI_TYPE_PACKAGE;
	argv4.package.count = 2;
	argv4.package.elements = obj_args;

	obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev),
				&hns_dsaf_acpi_dsm_guid, 0, op_type, &argv4);
	if (!obj) {
		dev_err(mac_cb->dev, "ledctrl fail, locate:%d port:%d!\n",
			locate, port);
		return;
	}

	ACPI_FREE(obj);
}

static void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status,
			     u16 speed, int data)
{
	int speed_reg = 0;
	u8 value;

	if (!mac_cb) {
		pr_err("sfp_led_opt mac_dev is null!\n");
		return;
	}
	if (!mac_cb->cpld_ctrl) {
		dev_err(mac_cb->dev, "mac_id=%d, cpld syscon is null !\n",
			mac_cb->mac_id);
		return;
	}

	if (speed == MAC_SPEED_10000)
		speed_reg = 1;

	value = mac_cb->cpld_led_value;

	if (link_status) {
		dsaf_set_bit(value, DSAF_LED_LINK_B, link_status);
		dsaf_set_field(value, DSAF_LED_SPEED_M,
			       DSAF_LED_SPEED_S, speed_reg);
		dsaf_set_bit(value, DSAF_LED_DATA_B, data);

		if (value != mac_cb->cpld_led_value) {
			dsaf_write_syscon(mac_cb->cpld_ctrl,
					  mac_cb->cpld_ctrl_reg, value);
			mac_cb->cpld_led_value = value;
		}
	} else {
		value = (mac_cb->cpld_led_value) & (0x1 << DSAF_LED_ANCHOR_B);
		dsaf_write_syscon(mac_cb->cpld_ctrl,
				  mac_cb->cpld_ctrl_reg, value);
		mac_cb->cpld_led_value = value;
	}
}

static void hns_cpld_set_led_acpi(struct hns_mac_cb *mac_cb, int link_status,
				  u16 speed, int data)
{
	if (!mac_cb) {
		pr_err("cpld_led_set mac_cb is null!\n");
		return;
	}

	hns_dsaf_acpi_ledctrl_by_port(mac_cb, HNS_OP_LED_SET_FUNC,
				      link_status, mac_cb->mac_id, data);
}

static void cpld_led_reset(struct hns_mac_cb *mac_cb)
{
	if (!mac_cb || !mac_cb->cpld_ctrl)
		return;

	dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg,
			  CPLD_LED_DEFAULT_VALUE);
	mac_cb->cpld_led_value = CPLD_LED_DEFAULT_VALUE;
}

static void cpld_led_reset_acpi(struct hns_mac_cb *mac_cb)
{
	if (!mac_cb) {
		pr_err("cpld_led_reset mac_cb is null!\n");
		return;
	}

	if (mac_cb->media_type != HNAE_MEDIA_TYPE_FIBER)
		return;

	hns_dsaf_acpi_ledctrl_by_port(mac_cb, HNS_OP_LED_SET_FUNC,
				      0, mac_cb->mac_id, 0);
}

static int cpld_set_led_id(struct hns_mac_cb *mac_cb,
			   enum hnae_led_state status)
{
	u32 val = 0;
	int ret;

	if (!mac_cb->cpld_ctrl)
		return 0;

	switch (status) {
	case HNAE_LED_ACTIVE:
		ret = dsaf_read_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg,
				       &val);
		if (ret)
			return ret;

		dsaf_set_bit(val, DSAF_LED_ANCHOR_B, CPLD_LED_ON_VALUE);
		dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg,
				  val);
		mac_cb->cpld_led_value = val;
		break;
	case HNAE_LED_INACTIVE:
		dsaf_set_bit(mac_cb->cpld_led_value, DSAF_LED_ANCHOR_B,
			     CPLD_LED_DEFAULT_VALUE);
		dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg,
				  mac_cb->cpld_led_value);
		break;
	default:
		dev_err(mac_cb->dev, "invalid led state: %d!", status);
		return -EINVAL;
	}

	return 0;
}

static int cpld_set_led_id_acpi(struct hns_mac_cb *mac_cb,
				enum hnae_led_state status)
{
	switch (status) {
	case HNAE_LED_ACTIVE:
		hns_dsaf_acpi_locate_ledctrl_by_port(mac_cb,
						     HNS_OP_LOCATE_LED_SET_FUNC,
						     CPLD_LED_ON_VALUE,
						     mac_cb->mac_id);
		break;
	case HNAE_LED_INACTIVE:
		hns_dsaf_acpi_locate_ledctrl_by_port(mac_cb,
						     HNS_OP_LOCATE_LED_SET_FUNC,
						     CPLD_LED_DEFAULT_VALUE,
						     mac_cb->mac_id);
		break;
	default:
		dev_err(mac_cb->dev, "invalid led state: %d!", status);
		return -EINVAL;
	}

	return 0;
}

#define RESET_REQ_OR_DREQ 1

static void hns_dsaf_acpi_srst_by_port(struct dsaf_device *dsaf_dev, u8 op_type,
				       u32 port_type, u32 port, u32 val)
{
	union acpi_object *obj;
	union acpi_object obj_args[3], argv4;

	obj_args[0].integer.type = ACPI_TYPE_INTEGER;
	obj_args[0].integer.value = port_type;
	obj_args[1].integer.type = ACPI_TYPE_INTEGER;
	obj_args[1].integer.value = port;
	obj_args[2].integer.type = ACPI_TYPE_INTEGER;
	obj_args[2].integer.value = val;

	argv4.type = ACPI_TYPE_PACKAGE;
	argv4.package.count = 3;
	argv4.package.elements = obj_args;

	obj = acpi_evaluate_dsm(ACPI_HANDLE(dsaf_dev->dev),
				&hns_dsaf_acpi_dsm_guid, 0, op_type, &argv4);
	if (!obj) {
		dev_warn(dsaf_dev->dev, "reset port_type%d port%d fail!",
			 port_type, port);
		return;
	}

	ACPI_FREE(obj);
}

static void hns_dsaf_rst(struct dsaf_device *dsaf_dev, bool dereset)
{
	u32 xbar_reg_addr;
	u32 nt_reg_addr;

	if (!dereset) {
		xbar_reg_addr = DSAF_SUB_SC_XBAR_RESET_REQ_REG;
		nt_reg_addr = DSAF_SUB_SC_NT_RESET_REQ_REG;
	} else {
		xbar_reg_addr = DSAF_SUB_SC_XBAR_RESET_DREQ_REG;
		nt_reg_addr = DSAF_SUB_SC_NT_RESET_DREQ_REG;
	}

	dsaf_write_sub(dsaf_dev, xbar_reg_addr, RESET_REQ_OR_DREQ);
	dsaf_write_sub(dsaf_dev, nt_reg_addr, RESET_REQ_OR_DREQ);
}

static void hns_dsaf_rst_acpi(struct dsaf_device *dsaf_dev, bool dereset)
{
	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
				   HNS_DSAF_RESET_FUNC,
				   0, dereset);
}

static void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
				      bool dereset)
{
	u32 reg_val = 0;
	u32 reg_addr;

	if (port >= DSAF_XGE_NUM)
		return;

	reg_val |= RESET_REQ_OR_DREQ;
	reg_val |= 0x2082082 << dsaf_dev->mac_cb[port]->port_rst_off;

	if (!dereset)
		reg_addr = DSAF_SUB_SC_XGE_RESET_REQ_REG;
	else
		reg_addr = DSAF_SUB_SC_XGE_RESET_DREQ_REG;

	dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
}

static void hns_dsaf_xge_srst_by_port_acpi(struct dsaf_device *dsaf_dev,
					   u32 port, bool dereset)
{
	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
				   HNS_XGE_RESET_FUNC, port, dereset);
}

/**
 * hns_dsaf_srst_chns - reset dsaf channels
 * @dsaf_dev: dsaf device struct pointer
 * @msk: xbar channels mask value:
 * @dereset: false - request reset , true - drop reset
 *
 * bit0-5 for xge0-5
 * bit6-11 for ppe0-5
 * bit12-17 for roce0-5
 * bit18-19 for com/dfx
 */
static void
hns_dsaf_srst_chns(struct dsaf_device *dsaf_dev, u32 msk, bool dereset)
{
	u32 reg_addr;

	if (!dereset)
		reg_addr = DSAF_SUB_SC_DSAF_RESET_REQ_REG;
	else
		reg_addr = DSAF_SUB_SC_DSAF_RESET_DREQ_REG;

	dsaf_write_sub(dsaf_dev, reg_addr, msk);
}

/**
 * hns_dsaf_srst_chns_acpi - reset dsaf channels
 * @dsaf_dev: dsaf device struct pointer
 * @msk: xbar channels mask value:
 * @dereset: false - request reset , true - drop reset
 *
 * bit0-5 for xge0-5
 * bit6-11 for ppe0-5
 * bit12-17 for roce0-5
 * bit18-19 for com/dfx
 */
static void
hns_dsaf_srst_chns_acpi(struct dsaf_device *dsaf_dev, u32 msk, bool dereset)
{
	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
				   HNS_DSAF_CHN_RESET_FUNC,
				   msk, dereset);
}

static void hns_dsaf_roce_srst(struct dsaf_device *dsaf_dev, bool dereset)
{
	if (!dereset) {
		dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_ROCEE_RESET_REQ_REG, 1);
	} else {
		dsaf_write_sub(dsaf_dev,
			       DSAF_SUB_SC_ROCEE_CLK_DIS_REG, 1);
		dsaf_write_sub(dsaf_dev,
			       DSAF_SUB_SC_ROCEE_RESET_DREQ_REG, 1);
		msleep(20);
		dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_ROCEE_CLK_EN_REG, 1);
	}
}

static void hns_dsaf_roce_srst_acpi(struct dsaf_device *dsaf_dev, bool dereset)
{
	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
				   HNS_ROCE_RESET_FUNC, 0, dereset);
}

static void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
				     bool dereset)
{
	u32 reg_val_1;
	u32 reg_val_2;
	u32 port_rst_off;

	if (port >= DSAF_GE_NUM)
		return;

	if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) {
		reg_val_1  = 0x1 << port;
		port_rst_off = dsaf_dev->mac_cb[port]->port_rst_off;
		/* there is difference between V1 and V2 in register.*/
		reg_val_2 = AE_IS_VER1(dsaf_dev->dsaf_ver) ?
				0x1041041 : 0x2082082;
		reg_val_2 <<= port_rst_off;

		if (!dereset) {
			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG,
				       reg_val_1);

			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ0_REG,
				       reg_val_2);
		} else {
			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ0_REG,
				       reg_val_2);

			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ1_REG,
				       reg_val_1);
		}
	} else {
		reg_val_1 = 0x15540;
		reg_val_2 = AE_IS_VER1(dsaf_dev->dsaf_ver) ? 0x100 : 0x40;

		reg_val_1 <<= dsaf_dev->reset_offset;
		reg_val_2 <<= dsaf_dev->reset_offset;

		if (!dereset) {
			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG,
				       reg_val_1);

			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_PPE_RESET_REQ_REG,
				       reg_val_2);
		} else {
			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ1_REG,
				       reg_val_1);

			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_PPE_RESET_DREQ_REG,
				       reg_val_2);
		}
	}
}

static void hns_dsaf_ge_srst_by_port_acpi(struct dsaf_device *dsaf_dev,
					  u32 port, bool dereset)
{
	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
				   HNS_GE_RESET_FUNC, port, dereset);
}

static void hns_ppe_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
				 bool dereset)
{
	u32 reg_val = 0;
	u32 reg_addr;

	reg_val |= RESET_REQ_OR_DREQ <<	dsaf_dev->mac_cb[port]->port_rst_off;

	if (!dereset)
		reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG;
	else
		reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG;

	dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
}

static void
hns_ppe_srst_by_port_acpi(struct dsaf_device *dsaf_dev, u32 port, bool dereset)
{
	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
				   HNS_PPE_RESET_FUNC, port, dereset);
}

static void hns_ppe_com_srst(struct dsaf_device *dsaf_dev, bool dereset)
{
	u32 reg_val;
	u32 reg_addr;

	if (!(dev_of_node(dsaf_dev->dev)))
		return;

	if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) {
		reg_val = RESET_REQ_OR_DREQ;
		if (!dereset)
			reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_REQ_REG;
		else
			reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_DREQ_REG;

	} else {
		reg_val = 0x100 << dsaf_dev->reset_offset;

		if (!dereset)
			reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG;
		else
			reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG;
	}

	dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
}

/**
 * hns_mac_get_phy_if - get phy ifterface form serdes mode
 * @mac_cb: mac control block
 * retuen phy interface
 */
static phy_interface_t hns_mac_get_phy_if(struct hns_mac_cb *mac_cb)
{
	u32 mode;
	u32 reg;
	bool is_ver1 = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver);
	int mac_id = mac_cb->mac_id;
	phy_interface_t phy_if;

	if (is_ver1) {
		if (HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev))
			return PHY_INTERFACE_MODE_SGMII;

		if (mac_id >= 0 && mac_id <= 3)
			reg = HNS_MAC_HILINK4_REG;
		else
			reg = HNS_MAC_HILINK3_REG;
	} else {
		if (!HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev) && mac_id <= 3)
			reg = HNS_MAC_HILINK4V2_REG;
		else
			reg = HNS_MAC_HILINK3V2_REG;
	}

	mode = dsaf_read_sub(mac_cb->dsaf_dev, reg);
	if (dsaf_get_bit(mode, mac_cb->port_mode_off))
		phy_if = PHY_INTERFACE_MODE_XGMII;
	else
		phy_if = PHY_INTERFACE_MODE_SGMII;

	return phy_if;
}

static phy_interface_t hns_mac_get_phy_if_acpi(struct hns_mac_cb *mac_cb)
{
	phy_interface_t phy_if = PHY_INTERFACE_MODE_NA;
	union acpi_object *obj;
	union acpi_object obj_args, argv4;

	obj_args.integer.type = ACPI_TYPE_INTEGER;
	obj_args.integer.value = mac_cb->mac_id;

	argv4.type = ACPI_TYPE_PACKAGE;
	argv4.package.count = 1;
	argv4.package.elements = &obj_args;

	obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev),
				&hns_dsaf_acpi_dsm_guid, 0,
				HNS_OP_GET_PORT_TYPE_FUNC, &argv4);

	if (!obj || obj->type != ACPI_TYPE_INTEGER)
		return phy_if;

	phy_if = obj->integer.value ?
		PHY_INTERFACE_MODE_XGMII : PHY_INTERFACE_MODE_SGMII;

	dev_dbg(mac_cb->dev, "mac_id=%d, phy_if=%d\n", mac_cb->mac_id, phy_if);

	ACPI_FREE(obj);

	return phy_if;
}

static int hns_mac_get_sfp_prsnt(struct hns_mac_cb *mac_cb, int *sfp_prsnt)
{
	u32 val = 0;
	int ret;

	if (!mac_cb->cpld_ctrl)
		return -ENODEV;

	ret = dsaf_read_syscon(mac_cb->cpld_ctrl,
			       mac_cb->cpld_ctrl_reg + MAC_SFP_PORT_OFFSET,
			       &val);
	if (ret)
		return ret;

	*sfp_prsnt = !val;
	return 0;
}

static int hns_mac_get_sfp_prsnt_acpi(struct hns_mac_cb *mac_cb, int *sfp_prsnt)
{
	union acpi_object *obj;
	union acpi_object obj_args, argv4;

	obj_args.integer.type = ACPI_TYPE_INTEGER;
	obj_args.integer.value = mac_cb->mac_id;

	argv4.type = ACPI_TYPE_PACKAGE;
	argv4.package.count = 1;
	argv4.package.elements = &obj_args;

	obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev),
				&hns_dsaf_acpi_dsm_guid, 0,
				HNS_OP_GET_SFP_STAT_FUNC, &argv4);

	if (!obj || obj->type != ACPI_TYPE_INTEGER)
		return -ENODEV;

	*sfp_prsnt = obj->integer.value;

	ACPI_FREE(obj);

	return 0;
}

/**
 * hns_mac_config_sds_loopback - set loop back for serdes
 * @mac_cb: mac control block
 * @en: enable or disable
 * return 0 == success
 */
static int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, bool en)
{
	const u8 lane_id[] = {
		0,	/* mac 0 -> lane 0 */
		1,	/* mac 1 -> lane 1 */
		2,	/* mac 2 -> lane 2 */
		3,	/* mac 3 -> lane 3 */
		2,	/* mac 4 -> lane 2 */
		3,	/* mac 5 -> lane 3 */
		0,	/* mac 6 -> lane 0 */
		1	/* mac 7 -> lane 1 */
	};
#define RX_CSR(lane, reg) ((0x4080 + (reg) * 0x0002 + (lane) * 0x0200) * 2)
	u64 reg_offset = RX_CSR(lane_id[mac_cb->mac_id], 0);

	int sfp_prsnt = 0;
	int ret = hns_mac_get_sfp_prsnt(mac_cb, &sfp_prsnt);

	if (!mac_cb->phy_dev) {
		if (ret)
			pr_info("please confirm sfp is present or not\n");
		else
			if (!sfp_prsnt)
				pr_info("no sfp in this eth\n");
	}

	if (mac_cb->serdes_ctrl) {
		u32 origin = 0;

		if (!AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver)) {
#define HILINK_ACCESS_SEL_CFG		0x40008
			/* hilink4 & hilink3 use the same xge training and
			 * xge u adaptor. There is a hilink access sel cfg
			 * register to select which one to be configed
			 */
			if ((!HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev)) &&
			    (mac_cb->mac_id <= 3))
				dsaf_write_syscon(mac_cb->serdes_ctrl,
						  HILINK_ACCESS_SEL_CFG, 0);
			else
				dsaf_write_syscon(mac_cb->serdes_ctrl,
						  HILINK_ACCESS_SEL_CFG, 3);
		}

		ret = dsaf_read_syscon(mac_cb->serdes_ctrl, reg_offset,
				       &origin);
		if (ret)
			return ret;

		dsaf_set_field(origin, 1ull << 10, 10, en);
		dsaf_write_syscon(mac_cb->serdes_ctrl, reg_offset, origin);
	} else {
		u8 __iomem *base_addr = mac_cb->serdes_vaddr +
				(mac_cb->mac_id <= 3 ? 0x00280000 : 0x00200000);
		dsaf_set_reg_field(base_addr, reg_offset, 1ull << 10, 10, en);
	}

	return 0;
}

static int
hns_mac_config_sds_loopback_acpi(struct hns_mac_cb *mac_cb, bool en)
{
	union acpi_object *obj;
	union acpi_object obj_args[3], argv4;

	obj_args[0].integer.type = ACPI_TYPE_INTEGER;
	obj_args[0].integer.value = mac_cb->mac_id;
	obj_args[1].integer.type = ACPI_TYPE_INTEGER;
	obj_args[1].integer.value = en;

	argv4.type = ACPI_TYPE_PACKAGE;
	argv4.package.count = 2;
	argv4.package.elements = obj_args;

	obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dsaf_dev->dev),
				&hns_dsaf_acpi_dsm_guid, 0,
				HNS_OP_SERDES_LP_FUNC, &argv4);
	if (!obj) {
		dev_warn(mac_cb->dsaf_dev->dev, "set port%d serdes lp fail!",
			 mac_cb->mac_id);

		return -ENOTSUPP;
	}

	ACPI_FREE(obj);

	return 0;
}

struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device *dsaf_dev)
{
	struct dsaf_misc_op *misc_op;

	misc_op = devm_kzalloc(dsaf_dev->dev, sizeof(*misc_op), GFP_KERNEL);
	if (!misc_op)
		return NULL;

	if (dev_of_node(dsaf_dev->dev)) {
		misc_op->cpld_set_led = hns_cpld_set_led;
		misc_op->cpld_reset_led = cpld_led_reset;
		misc_op->cpld_set_led_id = cpld_set_led_id;

		misc_op->dsaf_reset = hns_dsaf_rst;
		misc_op->xge_srst = hns_dsaf_xge_srst_by_port;
		misc_op->ge_srst = hns_dsaf_ge_srst_by_port;
		misc_op->ppe_srst = hns_ppe_srst_by_port;
		misc_op->ppe_comm_srst = hns_ppe_com_srst;
		misc_op->hns_dsaf_srst_chns = hns_dsaf_srst_chns;
		misc_op->hns_dsaf_roce_srst = hns_dsaf_roce_srst;

		misc_op->get_phy_if = hns_mac_get_phy_if;
		misc_op->get_sfp_prsnt = hns_mac_get_sfp_prsnt;

		misc_op->cfg_serdes_loopback = hns_mac_config_sds_loopback;
	} else if (is_acpi_node(dsaf_dev->dev->fwnode)) {
		misc_op->cpld_set_led = hns_cpld_set_led_acpi;
		misc_op->cpld_reset_led = cpld_led_reset_acpi;
		misc_op->cpld_set_led_id = cpld_set_led_id_acpi;

		misc_op->dsaf_reset = hns_dsaf_rst_acpi;
		misc_op->xge_srst = hns_dsaf_xge_srst_by_port_acpi;
		misc_op->ge_srst = hns_dsaf_ge_srst_by_port_acpi;
		misc_op->ppe_srst = hns_ppe_srst_by_port_acpi;
		misc_op->ppe_comm_srst = hns_ppe_com_srst;
		misc_op->hns_dsaf_srst_chns = hns_dsaf_srst_chns_acpi;
		misc_op->hns_dsaf_roce_srst = hns_dsaf_roce_srst_acpi;

		misc_op->get_phy_if = hns_mac_get_phy_if_acpi;
		misc_op->get_sfp_prsnt = hns_mac_get_sfp_prsnt_acpi;

		misc_op->cfg_serdes_loopback = hns_mac_config_sds_loopback_acpi;
	} else {
		devm_kfree(dsaf_dev->dev, (void *)misc_op);
		misc_op = NULL;
	}

	return (void *)misc_op;
}

struct
platform_device *hns_dsaf_find_platform_device(struct fwnode_handle *fwnode)
{
	struct device *dev;

	dev = bus_find_device_by_fwnode(&platform_bus_type, fwnode);
	return dev ? to_platform_device(dev) : NULL;
}
