xref: /linux/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c (revision 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2511e6bc0Shuangdaode /*
3511e6bc0Shuangdaode  * Copyright (c) 2014-2015 Hisilicon Limited.
4511e6bc0Shuangdaode  */
5511e6bc0Shuangdaode 
6511e6bc0Shuangdaode #include "hns_dsaf_mac.h"
72e2591b1SDaode Huang #include "hns_dsaf_misc.h"
8511e6bc0Shuangdaode #include "hns_dsaf_ppe.h"
92e2591b1SDaode Huang #include "hns_dsaf_reg.h"
10511e6bc0Shuangdaode 
11f00ef863SKejian Yan enum _dsm_op_index {
12f00ef863SKejian Yan 	HNS_OP_RESET_FUNC               = 0x1,
13f00ef863SKejian Yan 	HNS_OP_SERDES_LP_FUNC           = 0x2,
14f00ef863SKejian Yan 	HNS_OP_LED_SET_FUNC             = 0x3,
15f00ef863SKejian Yan 	HNS_OP_GET_PORT_TYPE_FUNC       = 0x4,
16f00ef863SKejian Yan 	HNS_OP_GET_SFP_STAT_FUNC        = 0x5,
173abbccccSJian Shen 	HNS_OP_LOCATE_LED_SET_FUNC      = 0x6,
18f00ef863SKejian Yan };
19f00ef863SKejian Yan 
20f00ef863SKejian Yan enum _dsm_rst_type {
21f00ef863SKejian Yan 	HNS_DSAF_RESET_FUNC     = 0x1,
22f00ef863SKejian Yan 	HNS_PPE_RESET_FUNC      = 0x2,
23f00ef863SKejian Yan 	HNS_XGE_RESET_FUNC      = 0x4,
24f00ef863SKejian Yan 	HNS_GE_RESET_FUNC       = 0x5,
25d605916bSSalil 	HNS_DSAF_CHN_RESET_FUNC = 0x6,
26d605916bSSalil 	HNS_ROCE_RESET_FUNC     = 0x7,
27f00ef863SKejian Yan };
28f00ef863SKejian Yan 
29b86a496aSkbuild test robot static const guid_t hns_dsaf_acpi_dsm_guid =
3094116f81SAndy Shevchenko 	GUID_INIT(0x1A85AA1A, 0xE293, 0x415E,
3194116f81SAndy Shevchenko 		  0x8E, 0x28, 0x8D, 0x69, 0x0A, 0x0F, 0x82, 0x0A);
32f00ef863SKejian Yan 
dsaf_write_sub(struct dsaf_device * dsaf_dev,u32 reg,u32 val)33831d828bSYisen.Zhuang\(Zhuangyuzeng\) static void dsaf_write_sub(struct dsaf_device *dsaf_dev, u32 reg, u32 val)
34831d828bSYisen.Zhuang\(Zhuangyuzeng\) {
35831d828bSYisen.Zhuang\(Zhuangyuzeng\) 	if (dsaf_dev->sub_ctrl)
36831d828bSYisen.Zhuang\(Zhuangyuzeng\) 		dsaf_write_syscon(dsaf_dev->sub_ctrl, reg, val);
37831d828bSYisen.Zhuang\(Zhuangyuzeng\) 	else
38831d828bSYisen.Zhuang\(Zhuangyuzeng\) 		dsaf_write_reg(dsaf_dev->sc_base, reg, val);
39831d828bSYisen.Zhuang\(Zhuangyuzeng\) }
40831d828bSYisen.Zhuang\(Zhuangyuzeng\) 
dsaf_read_sub(struct dsaf_device * dsaf_dev,u32 reg)41831d828bSYisen.Zhuang\(Zhuangyuzeng\) static u32 dsaf_read_sub(struct dsaf_device *dsaf_dev, u32 reg)
42831d828bSYisen.Zhuang\(Zhuangyuzeng\) {
435e89cfacSHuazhong Tan 	u32 ret = 0;
445e89cfacSHuazhong Tan 	int err;
45831d828bSYisen.Zhuang\(Zhuangyuzeng\) 
465e89cfacSHuazhong Tan 	if (dsaf_dev->sub_ctrl) {
475e89cfacSHuazhong Tan 		err = dsaf_read_syscon(dsaf_dev->sub_ctrl, reg, &ret);
485e89cfacSHuazhong Tan 		if (err)
495e89cfacSHuazhong Tan 			dev_err(dsaf_dev->dev, "dsaf_read_syscon error %d!\n",
505e89cfacSHuazhong Tan 				err);
515e89cfacSHuazhong Tan 	} else {
52831d828bSYisen.Zhuang\(Zhuangyuzeng\) 		ret = dsaf_read_reg(dsaf_dev->sc_base, reg);
535e89cfacSHuazhong Tan 	}
54831d828bSYisen.Zhuang\(Zhuangyuzeng\) 
55831d828bSYisen.Zhuang\(Zhuangyuzeng\) 	return ret;
56831d828bSYisen.Zhuang\(Zhuangyuzeng\) }
57831d828bSYisen.Zhuang\(Zhuangyuzeng\) 
hns_dsaf_acpi_ledctrl_by_port(struct hns_mac_cb * mac_cb,u8 op_type,u32 link,u32 port,u32 act)581e4babeeSLiuJian static void hns_dsaf_acpi_ledctrl_by_port(struct hns_mac_cb *mac_cb, u8 op_type,
591e4babeeSLiuJian 					  u32 link, u32 port, u32 act)
601e4babeeSLiuJian {
611e4babeeSLiuJian 	union acpi_object *obj;
621e4babeeSLiuJian 	union acpi_object obj_args[3], argv4;
631e4babeeSLiuJian 
641e4babeeSLiuJian 	obj_args[0].integer.type = ACPI_TYPE_INTEGER;
651e4babeeSLiuJian 	obj_args[0].integer.value = link;
661e4babeeSLiuJian 	obj_args[1].integer.type = ACPI_TYPE_INTEGER;
671e4babeeSLiuJian 	obj_args[1].integer.value = port;
681e4babeeSLiuJian 	obj_args[2].integer.type = ACPI_TYPE_INTEGER;
691e4babeeSLiuJian 	obj_args[2].integer.value = act;
701e4babeeSLiuJian 
711e4babeeSLiuJian 	argv4.type = ACPI_TYPE_PACKAGE;
721e4babeeSLiuJian 	argv4.package.count = 3;
731e4babeeSLiuJian 	argv4.package.elements = obj_args;
741e4babeeSLiuJian 
751e4babeeSLiuJian 	obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev),
761e4babeeSLiuJian 				&hns_dsaf_acpi_dsm_guid, 0, op_type, &argv4);
771e4babeeSLiuJian 	if (!obj) {
781e4babeeSLiuJian 		dev_warn(mac_cb->dev, "ledctrl fail, link:%d port:%d act:%d!\n",
791e4babeeSLiuJian 			 link, port, act);
801e4babeeSLiuJian 		return;
811e4babeeSLiuJian 	}
821e4babeeSLiuJian 
831e4babeeSLiuJian 	ACPI_FREE(obj);
841e4babeeSLiuJian }
851e4babeeSLiuJian 
hns_dsaf_acpi_locate_ledctrl_by_port(struct hns_mac_cb * mac_cb,u8 op_type,u32 locate,u32 port)863abbccccSJian Shen static void hns_dsaf_acpi_locate_ledctrl_by_port(struct hns_mac_cb *mac_cb,
873abbccccSJian Shen 						 u8 op_type, u32 locate,
883abbccccSJian Shen 						 u32 port)
893abbccccSJian Shen {
903abbccccSJian Shen 	union acpi_object obj_args[2], argv4;
913abbccccSJian Shen 	union acpi_object *obj;
923abbccccSJian Shen 
933abbccccSJian Shen 	obj_args[0].integer.type = ACPI_TYPE_INTEGER;
943abbccccSJian Shen 	obj_args[0].integer.value = locate;
953abbccccSJian Shen 	obj_args[1].integer.type = ACPI_TYPE_INTEGER;
963abbccccSJian Shen 	obj_args[1].integer.value = port;
973abbccccSJian Shen 
983abbccccSJian Shen 	argv4.type = ACPI_TYPE_PACKAGE;
993abbccccSJian Shen 	argv4.package.count = 2;
1003abbccccSJian Shen 	argv4.package.elements = obj_args;
1013abbccccSJian Shen 
1023abbccccSJian Shen 	obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev),
1033abbccccSJian Shen 				&hns_dsaf_acpi_dsm_guid, 0, op_type, &argv4);
1043abbccccSJian Shen 	if (!obj) {
1053abbccccSJian Shen 		dev_err(mac_cb->dev, "ledctrl fail, locate:%d port:%d!\n",
1063abbccccSJian Shen 			locate, port);
1073abbccccSJian Shen 		return;
1083abbccccSJian Shen 	}
1093abbccccSJian Shen 
1103abbccccSJian Shen 	ACPI_FREE(obj);
1113abbccccSJian Shen }
1123abbccccSJian Shen 
hns_cpld_set_led(struct hns_mac_cb * mac_cb,int link_status,u16 speed,int data)113a24274aaSKejian Yan static void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status,
114511e6bc0Shuangdaode 			     u16 speed, int data)
115511e6bc0Shuangdaode {
116511e6bc0Shuangdaode 	int speed_reg = 0;
117511e6bc0Shuangdaode 	u8 value;
118511e6bc0Shuangdaode 
119511e6bc0Shuangdaode 	if (!mac_cb) {
120511e6bc0Shuangdaode 		pr_err("sfp_led_opt mac_dev is null!\n");
121511e6bc0Shuangdaode 		return;
122511e6bc0Shuangdaode 	}
12331d4446dSYisen.Zhuang\(Zhuangyuzeng\) 	if (!mac_cb->cpld_ctrl) {
12431d4446dSYisen.Zhuang\(Zhuangyuzeng\) 		dev_err(mac_cb->dev, "mac_id=%d, cpld syscon is null !\n",
125511e6bc0Shuangdaode 			mac_cb->mac_id);
126511e6bc0Shuangdaode 		return;
127511e6bc0Shuangdaode 	}
128511e6bc0Shuangdaode 
129511e6bc0Shuangdaode 	if (speed == MAC_SPEED_10000)
130511e6bc0Shuangdaode 		speed_reg = 1;
131511e6bc0Shuangdaode 
132511e6bc0Shuangdaode 	value = mac_cb->cpld_led_value;
133511e6bc0Shuangdaode 
134511e6bc0Shuangdaode 	if (link_status) {
135511e6bc0Shuangdaode 		dsaf_set_bit(value, DSAF_LED_LINK_B, link_status);
136511e6bc0Shuangdaode 		dsaf_set_field(value, DSAF_LED_SPEED_M,
137511e6bc0Shuangdaode 			       DSAF_LED_SPEED_S, speed_reg);
138511e6bc0Shuangdaode 		dsaf_set_bit(value, DSAF_LED_DATA_B, data);
139511e6bc0Shuangdaode 
140511e6bc0Shuangdaode 		if (value != mac_cb->cpld_led_value) {
14131d4446dSYisen.Zhuang\(Zhuangyuzeng\) 			dsaf_write_syscon(mac_cb->cpld_ctrl,
14231d4446dSYisen.Zhuang\(Zhuangyuzeng\) 					  mac_cb->cpld_ctrl_reg, value);
143511e6bc0Shuangdaode 			mac_cb->cpld_led_value = value;
144511e6bc0Shuangdaode 		}
145511e6bc0Shuangdaode 	} else {
146d8a8371eSDaode Huang 		value = (mac_cb->cpld_led_value) & (0x1 << DSAF_LED_ANCHOR_B);
147d8a8371eSDaode Huang 		dsaf_write_syscon(mac_cb->cpld_ctrl,
148d8a8371eSDaode Huang 				  mac_cb->cpld_ctrl_reg, value);
149d8a8371eSDaode Huang 		mac_cb->cpld_led_value = value;
150511e6bc0Shuangdaode 	}
151511e6bc0Shuangdaode }
152511e6bc0Shuangdaode 
hns_cpld_set_led_acpi(struct hns_mac_cb * mac_cb,int link_status,u16 speed,int data)1531e4babeeSLiuJian static void hns_cpld_set_led_acpi(struct hns_mac_cb *mac_cb, int link_status,
1541e4babeeSLiuJian 				  u16 speed, int data)
1551e4babeeSLiuJian {
1561e4babeeSLiuJian 	if (!mac_cb) {
1571e4babeeSLiuJian 		pr_err("cpld_led_set mac_cb is null!\n");
1581e4babeeSLiuJian 		return;
1591e4babeeSLiuJian 	}
1601e4babeeSLiuJian 
1611e4babeeSLiuJian 	hns_dsaf_acpi_ledctrl_by_port(mac_cb, HNS_OP_LED_SET_FUNC,
1621e4babeeSLiuJian 				      link_status, mac_cb->mac_id, data);
1631e4babeeSLiuJian }
1641e4babeeSLiuJian 
cpld_led_reset(struct hns_mac_cb * mac_cb)165a24274aaSKejian Yan static void cpld_led_reset(struct hns_mac_cb *mac_cb)
166511e6bc0Shuangdaode {
16731d4446dSYisen.Zhuang\(Zhuangyuzeng\) 	if (!mac_cb || !mac_cb->cpld_ctrl)
168511e6bc0Shuangdaode 		return;
169511e6bc0Shuangdaode 
17031d4446dSYisen.Zhuang\(Zhuangyuzeng\) 	dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg,
17131d4446dSYisen.Zhuang\(Zhuangyuzeng\) 			  CPLD_LED_DEFAULT_VALUE);
172511e6bc0Shuangdaode 	mac_cb->cpld_led_value = CPLD_LED_DEFAULT_VALUE;
173511e6bc0Shuangdaode }
174511e6bc0Shuangdaode 
cpld_led_reset_acpi(struct hns_mac_cb * mac_cb)1751e4babeeSLiuJian static void cpld_led_reset_acpi(struct hns_mac_cb *mac_cb)
1761e4babeeSLiuJian {
1771e4babeeSLiuJian 	if (!mac_cb) {
1781e4babeeSLiuJian 		pr_err("cpld_led_reset mac_cb is null!\n");
1791e4babeeSLiuJian 		return;
1801e4babeeSLiuJian 	}
1811e4babeeSLiuJian 
1821e4babeeSLiuJian 	if (mac_cb->media_type != HNAE_MEDIA_TYPE_FIBER)
1831e4babeeSLiuJian 		return;
1841e4babeeSLiuJian 
1851e4babeeSLiuJian 	hns_dsaf_acpi_ledctrl_by_port(mac_cb, HNS_OP_LED_SET_FUNC,
1861e4babeeSLiuJian 				      0, mac_cb->mac_id, 0);
1871e4babeeSLiuJian }
1881e4babeeSLiuJian 
cpld_set_led_id(struct hns_mac_cb * mac_cb,enum hnae_led_state status)189a24274aaSKejian Yan static int cpld_set_led_id(struct hns_mac_cb *mac_cb,
190511e6bc0Shuangdaode 			   enum hnae_led_state status)
191511e6bc0Shuangdaode {
1925e89cfacSHuazhong Tan 	u32 val = 0;
1935e89cfacSHuazhong Tan 	int ret;
1945e89cfacSHuazhong Tan 
1953abbccccSJian Shen 	if (!mac_cb->cpld_ctrl)
1963abbccccSJian Shen 		return 0;
1973abbccccSJian Shen 
198511e6bc0Shuangdaode 	switch (status) {
199511e6bc0Shuangdaode 	case HNAE_LED_ACTIVE:
2005e89cfacSHuazhong Tan 		ret = dsaf_read_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg,
2015e89cfacSHuazhong Tan 				       &val);
2025e89cfacSHuazhong Tan 		if (ret)
2035e89cfacSHuazhong Tan 			return ret;
2045e89cfacSHuazhong Tan 
2055e89cfacSHuazhong Tan 		dsaf_set_bit(val, DSAF_LED_ANCHOR_B, CPLD_LED_ON_VALUE);
20631d4446dSYisen.Zhuang\(Zhuangyuzeng\) 		dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg,
2075e89cfacSHuazhong Tan 				  val);
2085e89cfacSHuazhong Tan 		mac_cb->cpld_led_value = val;
209d8a8371eSDaode Huang 		break;
210511e6bc0Shuangdaode 	case HNAE_LED_INACTIVE:
211511e6bc0Shuangdaode 		dsaf_set_bit(mac_cb->cpld_led_value, DSAF_LED_ANCHOR_B,
212511e6bc0Shuangdaode 			     CPLD_LED_DEFAULT_VALUE);
21331d4446dSYisen.Zhuang\(Zhuangyuzeng\) 		dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg,
21431d4446dSYisen.Zhuang\(Zhuangyuzeng\) 				  mac_cb->cpld_led_value);
215511e6bc0Shuangdaode 		break;
216511e6bc0Shuangdaode 	default:
217d8a8371eSDaode Huang 		dev_err(mac_cb->dev, "invalid led state: %d!", status);
218d8a8371eSDaode Huang 		return -EINVAL;
219511e6bc0Shuangdaode 	}
220511e6bc0Shuangdaode 
221511e6bc0Shuangdaode 	return 0;
222511e6bc0Shuangdaode }
223511e6bc0Shuangdaode 
cpld_set_led_id_acpi(struct hns_mac_cb * mac_cb,enum hnae_led_state status)2243abbccccSJian Shen static int cpld_set_led_id_acpi(struct hns_mac_cb *mac_cb,
2253abbccccSJian Shen 				enum hnae_led_state status)
2263abbccccSJian Shen {
2273abbccccSJian Shen 	switch (status) {
2283abbccccSJian Shen 	case HNAE_LED_ACTIVE:
2293abbccccSJian Shen 		hns_dsaf_acpi_locate_ledctrl_by_port(mac_cb,
2303abbccccSJian Shen 						     HNS_OP_LOCATE_LED_SET_FUNC,
2313abbccccSJian Shen 						     CPLD_LED_ON_VALUE,
2323abbccccSJian Shen 						     mac_cb->mac_id);
2333abbccccSJian Shen 		break;
2343abbccccSJian Shen 	case HNAE_LED_INACTIVE:
2353abbccccSJian Shen 		hns_dsaf_acpi_locate_ledctrl_by_port(mac_cb,
2363abbccccSJian Shen 						     HNS_OP_LOCATE_LED_SET_FUNC,
2373abbccccSJian Shen 						     CPLD_LED_DEFAULT_VALUE,
2383abbccccSJian Shen 						     mac_cb->mac_id);
2393abbccccSJian Shen 		break;
2403abbccccSJian Shen 	default:
2413abbccccSJian Shen 		dev_err(mac_cb->dev, "invalid led state: %d!", status);
2423abbccccSJian Shen 		return -EINVAL;
2433abbccccSJian Shen 	}
2443abbccccSJian Shen 
2453abbccccSJian Shen 	return 0;
2463abbccccSJian Shen }
2473abbccccSJian Shen 
248511e6bc0Shuangdaode #define RESET_REQ_OR_DREQ 1
249511e6bc0Shuangdaode 
hns_dsaf_acpi_srst_by_port(struct dsaf_device * dsaf_dev,u8 op_type,u32 port_type,u32 port,u32 val)250f00ef863SKejian Yan static void hns_dsaf_acpi_srst_by_port(struct dsaf_device *dsaf_dev, u8 op_type,
251f00ef863SKejian Yan 				       u32 port_type, u32 port, u32 val)
252f00ef863SKejian Yan {
253f00ef863SKejian Yan 	union acpi_object *obj;
254f00ef863SKejian Yan 	union acpi_object obj_args[3], argv4;
255f00ef863SKejian Yan 
256f00ef863SKejian Yan 	obj_args[0].integer.type = ACPI_TYPE_INTEGER;
257f00ef863SKejian Yan 	obj_args[0].integer.value = port_type;
258f00ef863SKejian Yan 	obj_args[1].integer.type = ACPI_TYPE_INTEGER;
259f00ef863SKejian Yan 	obj_args[1].integer.value = port;
260f00ef863SKejian Yan 	obj_args[2].integer.type = ACPI_TYPE_INTEGER;
261f00ef863SKejian Yan 	obj_args[2].integer.value = val;
262f00ef863SKejian Yan 
263f00ef863SKejian Yan 	argv4.type = ACPI_TYPE_PACKAGE;
264f00ef863SKejian Yan 	argv4.package.count = 3;
265f00ef863SKejian Yan 	argv4.package.elements = obj_args;
266f00ef863SKejian Yan 
267f00ef863SKejian Yan 	obj = acpi_evaluate_dsm(ACPI_HANDLE(dsaf_dev->dev),
26894116f81SAndy Shevchenko 				&hns_dsaf_acpi_dsm_guid, 0, op_type, &argv4);
269f00ef863SKejian Yan 	if (!obj) {
270f00ef863SKejian Yan 		dev_warn(dsaf_dev->dev, "reset port_type%d port%d fail!",
271f00ef863SKejian Yan 			 port_type, port);
272f00ef863SKejian Yan 		return;
273f00ef863SKejian Yan 	}
274f00ef863SKejian Yan 
275f00ef863SKejian Yan 	ACPI_FREE(obj);
276f00ef863SKejian Yan }
277f00ef863SKejian Yan 
hns_dsaf_rst(struct dsaf_device * dsaf_dev,bool dereset)278a24274aaSKejian Yan static void hns_dsaf_rst(struct dsaf_device *dsaf_dev, bool dereset)
279511e6bc0Shuangdaode {
280511e6bc0Shuangdaode 	u32 xbar_reg_addr;
281511e6bc0Shuangdaode 	u32 nt_reg_addr;
282511e6bc0Shuangdaode 
283a24274aaSKejian Yan 	if (!dereset) {
284511e6bc0Shuangdaode 		xbar_reg_addr = DSAF_SUB_SC_XBAR_RESET_REQ_REG;
285511e6bc0Shuangdaode 		nt_reg_addr = DSAF_SUB_SC_NT_RESET_REQ_REG;
286511e6bc0Shuangdaode 	} else {
287511e6bc0Shuangdaode 		xbar_reg_addr = DSAF_SUB_SC_XBAR_RESET_DREQ_REG;
288511e6bc0Shuangdaode 		nt_reg_addr = DSAF_SUB_SC_NT_RESET_DREQ_REG;
289511e6bc0Shuangdaode 	}
290511e6bc0Shuangdaode 
291831d828bSYisen.Zhuang\(Zhuangyuzeng\) 	dsaf_write_sub(dsaf_dev, xbar_reg_addr, RESET_REQ_OR_DREQ);
292831d828bSYisen.Zhuang\(Zhuangyuzeng\) 	dsaf_write_sub(dsaf_dev, nt_reg_addr, RESET_REQ_OR_DREQ);
293511e6bc0Shuangdaode }
294511e6bc0Shuangdaode 
hns_dsaf_rst_acpi(struct dsaf_device * dsaf_dev,bool dereset)295f00ef863SKejian Yan static void hns_dsaf_rst_acpi(struct dsaf_device *dsaf_dev, bool dereset)
296f00ef863SKejian Yan {
297f00ef863SKejian Yan 	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
298f00ef863SKejian Yan 				   HNS_DSAF_RESET_FUNC,
299f00ef863SKejian Yan 				   0, dereset);
300f00ef863SKejian Yan }
301f00ef863SKejian Yan 
hns_dsaf_xge_srst_by_port(struct dsaf_device * dsaf_dev,u32 port,bool dereset)302a24274aaSKejian Yan static void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
303a24274aaSKejian Yan 				      bool dereset)
304511e6bc0Shuangdaode {
305511e6bc0Shuangdaode 	u32 reg_val = 0;
306511e6bc0Shuangdaode 	u32 reg_addr;
307511e6bc0Shuangdaode 
308511e6bc0Shuangdaode 	if (port >= DSAF_XGE_NUM)
309511e6bc0Shuangdaode 		return;
310511e6bc0Shuangdaode 
311511e6bc0Shuangdaode 	reg_val |= RESET_REQ_OR_DREQ;
312850bfa3bSYisen.Zhuang\(Zhuangyuzeng\) 	reg_val |= 0x2082082 << dsaf_dev->mac_cb[port]->port_rst_off;
313511e6bc0Shuangdaode 
314a24274aaSKejian Yan 	if (!dereset)
315511e6bc0Shuangdaode 		reg_addr = DSAF_SUB_SC_XGE_RESET_REQ_REG;
316511e6bc0Shuangdaode 	else
317511e6bc0Shuangdaode 		reg_addr = DSAF_SUB_SC_XGE_RESET_DREQ_REG;
318511e6bc0Shuangdaode 
319831d828bSYisen.Zhuang\(Zhuangyuzeng\) 	dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
320511e6bc0Shuangdaode }
321511e6bc0Shuangdaode 
hns_dsaf_xge_srst_by_port_acpi(struct dsaf_device * dsaf_dev,u32 port,bool dereset)322f00ef863SKejian Yan static void hns_dsaf_xge_srst_by_port_acpi(struct dsaf_device *dsaf_dev,
323f00ef863SKejian Yan 					   u32 port, bool dereset)
324f00ef863SKejian Yan {
325f00ef863SKejian Yan 	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
326f00ef863SKejian Yan 				   HNS_XGE_RESET_FUNC, port, dereset);
327f00ef863SKejian Yan }
328f00ef863SKejian Yan 
329e0180688Soulijun /**
330e0180688Soulijun  * hns_dsaf_srst_chns - reset dsaf channels
331e0180688Soulijun  * @dsaf_dev: dsaf device struct pointer
332e0180688Soulijun  * @msk: xbar channels mask value:
333d0ea5cbdSJesse Brandeburg  * @dereset: false - request reset , true - drop reset
334d0ea5cbdSJesse Brandeburg  *
335e0180688Soulijun  * bit0-5 for xge0-5
336e0180688Soulijun  * bit6-11 for ppe0-5
337e0180688Soulijun  * bit12-17 for roce0-5
338e0180688Soulijun  * bit18-19 for com/dfx
339e0180688Soulijun  */
340336a443bSYueHaibing static void
hns_dsaf_srst_chns(struct dsaf_device * dsaf_dev,u32 msk,bool dereset)341336a443bSYueHaibing hns_dsaf_srst_chns(struct dsaf_device *dsaf_dev, u32 msk, bool dereset)
342e0180688Soulijun {
343e0180688Soulijun 	u32 reg_addr;
344e0180688Soulijun 
345d605916bSSalil 	if (!dereset)
346e0180688Soulijun 		reg_addr = DSAF_SUB_SC_DSAF_RESET_REQ_REG;
347e0180688Soulijun 	else
348e0180688Soulijun 		reg_addr = DSAF_SUB_SC_DSAF_RESET_DREQ_REG;
349e0180688Soulijun 
350e0180688Soulijun 	dsaf_write_sub(dsaf_dev, reg_addr, msk);
351e0180688Soulijun }
352e0180688Soulijun 
353d605916bSSalil /**
3545a9594cfSYang Shen  * hns_dsaf_srst_chns_acpi - reset dsaf channels
355d605916bSSalil  * @dsaf_dev: dsaf device struct pointer
356d605916bSSalil  * @msk: xbar channels mask value:
357d0ea5cbdSJesse Brandeburg  * @dereset: false - request reset , true - drop reset
358d0ea5cbdSJesse Brandeburg  *
359d605916bSSalil  * bit0-5 for xge0-5
360d605916bSSalil  * bit6-11 for ppe0-5
361d605916bSSalil  * bit12-17 for roce0-5
362d605916bSSalil  * bit18-19 for com/dfx
363d605916bSSalil  */
364336a443bSYueHaibing static void
hns_dsaf_srst_chns_acpi(struct dsaf_device * dsaf_dev,u32 msk,bool dereset)365d605916bSSalil hns_dsaf_srst_chns_acpi(struct dsaf_device *dsaf_dev, u32 msk, bool dereset)
366e0180688Soulijun {
367d605916bSSalil 	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
368d605916bSSalil 				   HNS_DSAF_CHN_RESET_FUNC,
369d605916bSSalil 				   msk, dereset);
370d605916bSSalil }
371d605916bSSalil 
hns_dsaf_roce_srst(struct dsaf_device * dsaf_dev,bool dereset)372336a443bSYueHaibing static void hns_dsaf_roce_srst(struct dsaf_device *dsaf_dev, bool dereset)
373d605916bSSalil {
374d605916bSSalil 	if (!dereset) {
375e0180688Soulijun 		dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_ROCEE_RESET_REQ_REG, 1);
376e0180688Soulijun 	} else {
377e0180688Soulijun 		dsaf_write_sub(dsaf_dev,
378e0180688Soulijun 			       DSAF_SUB_SC_ROCEE_CLK_DIS_REG, 1);
379e0180688Soulijun 		dsaf_write_sub(dsaf_dev,
380e0180688Soulijun 			       DSAF_SUB_SC_ROCEE_RESET_DREQ_REG, 1);
381e0180688Soulijun 		msleep(20);
382e0180688Soulijun 		dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_ROCEE_CLK_EN_REG, 1);
383e0180688Soulijun 	}
384e0180688Soulijun }
385e0180688Soulijun 
hns_dsaf_roce_srst_acpi(struct dsaf_device * dsaf_dev,bool dereset)386336a443bSYueHaibing static void hns_dsaf_roce_srst_acpi(struct dsaf_device *dsaf_dev, bool dereset)
387d605916bSSalil {
388d605916bSSalil 	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
389d605916bSSalil 				   HNS_ROCE_RESET_FUNC, 0, dereset);
390d605916bSSalil }
391d605916bSSalil 
hns_dsaf_ge_srst_by_port(struct dsaf_device * dsaf_dev,u32 port,bool dereset)392a24274aaSKejian Yan static void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
393a24274aaSKejian Yan 				     bool dereset)
394511e6bc0Shuangdaode {
395511e6bc0Shuangdaode 	u32 reg_val_1;
396511e6bc0Shuangdaode 	u32 reg_val_2;
397850bfa3bSYisen.Zhuang\(Zhuangyuzeng\) 	u32 port_rst_off;
398511e6bc0Shuangdaode 
399511e6bc0Shuangdaode 	if (port >= DSAF_GE_NUM)
400511e6bc0Shuangdaode 		return;
401511e6bc0Shuangdaode 
40289a44093SYisen.Zhuang\(Zhuangyuzeng\) 	if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) {
403a66998e0STeng Qi 		/* DSAF_MAX_PORT_NUM is 6, but DSAF_GE_NUM is 8.
404a66998e0STeng Qi 		   We need check to prevent array overflow */
405a66998e0STeng Qi 		if (port >= DSAF_MAX_PORT_NUM)
406a66998e0STeng Qi 			return;
407511e6bc0Shuangdaode 		reg_val_1  = 0x1 << port;
408850bfa3bSYisen.Zhuang\(Zhuangyuzeng\) 		port_rst_off = dsaf_dev->mac_cb[port]->port_rst_off;
40913ac695eSSalil 		/* there is difference between V1 and V2 in register.*/
410d9fdb4edSDaode Huang 		reg_val_2 = AE_IS_VER1(dsaf_dev->dsaf_ver) ?
411d9fdb4edSDaode Huang 				0x1041041 : 0x2082082;
412d9fdb4edSDaode Huang 		reg_val_2 <<= port_rst_off;
413511e6bc0Shuangdaode 
414a24274aaSKejian Yan 		if (!dereset) {
415831d828bSYisen.Zhuang\(Zhuangyuzeng\) 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG,
416511e6bc0Shuangdaode 				       reg_val_1);
417511e6bc0Shuangdaode 
418831d828bSYisen.Zhuang\(Zhuangyuzeng\) 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ0_REG,
419511e6bc0Shuangdaode 				       reg_val_2);
420511e6bc0Shuangdaode 		} else {
421831d828bSYisen.Zhuang\(Zhuangyuzeng\) 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ0_REG,
422511e6bc0Shuangdaode 				       reg_val_2);
423511e6bc0Shuangdaode 
424831d828bSYisen.Zhuang\(Zhuangyuzeng\) 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ1_REG,
425511e6bc0Shuangdaode 				       reg_val_1);
426511e6bc0Shuangdaode 		}
427511e6bc0Shuangdaode 	} else {
428d9fdb4edSDaode Huang 		reg_val_1 = 0x15540;
429d9fdb4edSDaode Huang 		reg_val_2 = AE_IS_VER1(dsaf_dev->dsaf_ver) ? 0x100 : 0x40;
4300b03fd85SQianqian Xie 
431d9fdb4edSDaode Huang 		reg_val_1 <<= dsaf_dev->reset_offset;
432d9fdb4edSDaode Huang 		reg_val_2 <<= dsaf_dev->reset_offset;
433511e6bc0Shuangdaode 
434a24274aaSKejian Yan 		if (!dereset) {
435831d828bSYisen.Zhuang\(Zhuangyuzeng\) 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG,
436511e6bc0Shuangdaode 				       reg_val_1);
437511e6bc0Shuangdaode 
438831d828bSYisen.Zhuang\(Zhuangyuzeng\) 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_PPE_RESET_REQ_REG,
439511e6bc0Shuangdaode 				       reg_val_2);
440511e6bc0Shuangdaode 		} else {
441831d828bSYisen.Zhuang\(Zhuangyuzeng\) 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ1_REG,
442511e6bc0Shuangdaode 				       reg_val_1);
443511e6bc0Shuangdaode 
444831d828bSYisen.Zhuang\(Zhuangyuzeng\) 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_PPE_RESET_DREQ_REG,
445511e6bc0Shuangdaode 				       reg_val_2);
446511e6bc0Shuangdaode 		}
447511e6bc0Shuangdaode 	}
448511e6bc0Shuangdaode }
449511e6bc0Shuangdaode 
hns_dsaf_ge_srst_by_port_acpi(struct dsaf_device * dsaf_dev,u32 port,bool dereset)450f00ef863SKejian Yan static void hns_dsaf_ge_srst_by_port_acpi(struct dsaf_device *dsaf_dev,
451f00ef863SKejian Yan 					  u32 port, bool dereset)
452f00ef863SKejian Yan {
453f00ef863SKejian Yan 	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
454f00ef863SKejian Yan 				   HNS_GE_RESET_FUNC, port, dereset);
455f00ef863SKejian Yan }
456f00ef863SKejian Yan 
hns_ppe_srst_by_port(struct dsaf_device * dsaf_dev,u32 port,bool dereset)457a24274aaSKejian Yan static void hns_ppe_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
458a24274aaSKejian Yan 				 bool dereset)
459511e6bc0Shuangdaode {
460511e6bc0Shuangdaode 	u32 reg_val = 0;
461511e6bc0Shuangdaode 	u32 reg_addr;
462511e6bc0Shuangdaode 
463850bfa3bSYisen.Zhuang\(Zhuangyuzeng\) 	reg_val |= RESET_REQ_OR_DREQ <<	dsaf_dev->mac_cb[port]->port_rst_off;
464511e6bc0Shuangdaode 
465a24274aaSKejian Yan 	if (!dereset)
466511e6bc0Shuangdaode 		reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG;
467511e6bc0Shuangdaode 	else
468511e6bc0Shuangdaode 		reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG;
469511e6bc0Shuangdaode 
470831d828bSYisen.Zhuang\(Zhuangyuzeng\) 	dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
471511e6bc0Shuangdaode }
472511e6bc0Shuangdaode 
473f00ef863SKejian Yan static void
hns_ppe_srst_by_port_acpi(struct dsaf_device * dsaf_dev,u32 port,bool dereset)474f00ef863SKejian Yan hns_ppe_srst_by_port_acpi(struct dsaf_device *dsaf_dev, u32 port, bool dereset)
475f00ef863SKejian Yan {
476f00ef863SKejian Yan 	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
477f00ef863SKejian Yan 				   HNS_PPE_RESET_FUNC, port, dereset);
478f00ef863SKejian Yan }
479f00ef863SKejian Yan 
hns_ppe_com_srst(struct dsaf_device * dsaf_dev,bool dereset)480a24274aaSKejian Yan static void hns_ppe_com_srst(struct dsaf_device *dsaf_dev, bool dereset)
481511e6bc0Shuangdaode {
482511e6bc0Shuangdaode 	u32 reg_val;
483511e6bc0Shuangdaode 	u32 reg_addr;
484511e6bc0Shuangdaode 
485f00ef863SKejian Yan 	if (!(dev_of_node(dsaf_dev->dev)))
486f00ef863SKejian Yan 		return;
487f00ef863SKejian Yan 
48889a44093SYisen.Zhuang\(Zhuangyuzeng\) 	if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) {
489511e6bc0Shuangdaode 		reg_val = RESET_REQ_OR_DREQ;
490a24274aaSKejian Yan 		if (!dereset)
491511e6bc0Shuangdaode 			reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_REQ_REG;
492511e6bc0Shuangdaode 		else
493511e6bc0Shuangdaode 			reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_DREQ_REG;
494511e6bc0Shuangdaode 
495511e6bc0Shuangdaode 	} else {
496422c3107SYisen.Zhuang\(Zhuangyuzeng\) 		reg_val = 0x100 << dsaf_dev->reset_offset;
497511e6bc0Shuangdaode 
498a24274aaSKejian Yan 		if (!dereset)
499511e6bc0Shuangdaode 			reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG;
500511e6bc0Shuangdaode 		else
501511e6bc0Shuangdaode 			reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG;
502511e6bc0Shuangdaode 	}
503511e6bc0Shuangdaode 
504831d828bSYisen.Zhuang\(Zhuangyuzeng\) 	dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
505511e6bc0Shuangdaode }
506511e6bc0Shuangdaode 
507511e6bc0Shuangdaode /**
5085a9594cfSYang Shen  * hns_mac_get_phy_if - get phy ifterface form serdes mode
509511e6bc0Shuangdaode  * @mac_cb: mac control block
510511e6bc0Shuangdaode  * retuen phy interface
511511e6bc0Shuangdaode  */
hns_mac_get_phy_if(struct hns_mac_cb * mac_cb)512a24274aaSKejian Yan static phy_interface_t hns_mac_get_phy_if(struct hns_mac_cb *mac_cb)
513511e6bc0Shuangdaode {
514c1203fe7SSheng Li 	u32 mode;
515c1203fe7SSheng Li 	u32 reg;
516c1203fe7SSheng Li 	bool is_ver1 = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver);
517c1203fe7SSheng Li 	int mac_id = mac_cb->mac_id;
5180d768fc6SYisen.Zhuang\(Zhuangyuzeng\) 	phy_interface_t phy_if;
519511e6bc0Shuangdaode 
5200d768fc6SYisen.Zhuang\(Zhuangyuzeng\) 	if (is_ver1) {
5210d768fc6SYisen.Zhuang\(Zhuangyuzeng\) 		if (HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev))
5220d768fc6SYisen.Zhuang\(Zhuangyuzeng\) 			return PHY_INTERFACE_MODE_SGMII;
5230d768fc6SYisen.Zhuang\(Zhuangyuzeng\) 
5240d768fc6SYisen.Zhuang\(Zhuangyuzeng\) 		if (mac_id >= 0 && mac_id <= 3)
5250d768fc6SYisen.Zhuang\(Zhuangyuzeng\) 			reg = HNS_MAC_HILINK4_REG;
526c1203fe7SSheng Li 		else
5270d768fc6SYisen.Zhuang\(Zhuangyuzeng\) 			reg = HNS_MAC_HILINK3_REG;
528422c3107SYisen.Zhuang\(Zhuangyuzeng\) 	} else {
5290d768fc6SYisen.Zhuang\(Zhuangyuzeng\) 		if (!HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev) && mac_id <= 3)
5300d768fc6SYisen.Zhuang\(Zhuangyuzeng\) 			reg = HNS_MAC_HILINK4V2_REG;
5310d768fc6SYisen.Zhuang\(Zhuangyuzeng\) 		else
5320d768fc6SYisen.Zhuang\(Zhuangyuzeng\) 			reg = HNS_MAC_HILINK3V2_REG;
5330d768fc6SYisen.Zhuang\(Zhuangyuzeng\) 	}
5340d768fc6SYisen.Zhuang\(Zhuangyuzeng\) 
535831d828bSYisen.Zhuang\(Zhuangyuzeng\) 	mode = dsaf_read_sub(mac_cb->dsaf_dev, reg);
5360d768fc6SYisen.Zhuang\(Zhuangyuzeng\) 	if (dsaf_get_bit(mode, mac_cb->port_mode_off))
537511e6bc0Shuangdaode 		phy_if = PHY_INTERFACE_MODE_XGMII;
538c1203fe7SSheng Li 	else
539511e6bc0Shuangdaode 		phy_if = PHY_INTERFACE_MODE_SGMII;
5400d768fc6SYisen.Zhuang\(Zhuangyuzeng\) 
541511e6bc0Shuangdaode 	return phy_if;
542511e6bc0Shuangdaode }
543511e6bc0Shuangdaode 
hns_mac_get_phy_if_acpi(struct hns_mac_cb * mac_cb)544f00ef863SKejian Yan static phy_interface_t hns_mac_get_phy_if_acpi(struct hns_mac_cb *mac_cb)
545f00ef863SKejian Yan {
546f00ef863SKejian Yan 	phy_interface_t phy_if = PHY_INTERFACE_MODE_NA;
547f00ef863SKejian Yan 	union acpi_object *obj;
548f00ef863SKejian Yan 	union acpi_object obj_args, argv4;
549f00ef863SKejian Yan 
550f00ef863SKejian Yan 	obj_args.integer.type = ACPI_TYPE_INTEGER;
551f00ef863SKejian Yan 	obj_args.integer.value = mac_cb->mac_id;
552f00ef863SKejian Yan 
5533d4068b2SZheng Yongjun 	argv4.type = ACPI_TYPE_PACKAGE;
5543d4068b2SZheng Yongjun 	argv4.package.count = 1;
5553d4068b2SZheng Yongjun 	argv4.package.elements = &obj_args;
556f00ef863SKejian Yan 
557*498fe810SAndy Shevchenko 	obj = acpi_evaluate_dsm_typed(ACPI_HANDLE(mac_cb->dev),
55894116f81SAndy Shevchenko 				      &hns_dsaf_acpi_dsm_guid, 0,
559*498fe810SAndy Shevchenko 				      HNS_OP_GET_PORT_TYPE_FUNC, &argv4,
560*498fe810SAndy Shevchenko 				      ACPI_TYPE_INTEGER);
561*498fe810SAndy Shevchenko 	if (!obj)
562f00ef863SKejian Yan 		return phy_if;
563f00ef863SKejian Yan 
564f00ef863SKejian Yan 	phy_if = obj->integer.value ?
565f00ef863SKejian Yan 		PHY_INTERFACE_MODE_XGMII : PHY_INTERFACE_MODE_SGMII;
566f00ef863SKejian Yan 
567f00ef863SKejian Yan 	dev_dbg(mac_cb->dev, "mac_id=%d, phy_if=%d\n", mac_cb->mac_id, phy_if);
568f00ef863SKejian Yan 
569f00ef863SKejian Yan 	ACPI_FREE(obj);
570f00ef863SKejian Yan 
571f00ef863SKejian Yan 	return phy_if;
572f00ef863SKejian Yan }
573f00ef863SKejian Yan 
hns_mac_get_sfp_prsnt(struct hns_mac_cb * mac_cb,int * sfp_prsnt)574336a443bSYueHaibing static int hns_mac_get_sfp_prsnt(struct hns_mac_cb *mac_cb, int *sfp_prsnt)
57531d4446dSYisen.Zhuang\(Zhuangyuzeng\) {
5765e89cfacSHuazhong Tan 	u32 val = 0;
5775e89cfacSHuazhong Tan 	int ret;
5785e89cfacSHuazhong Tan 
57931d4446dSYisen.Zhuang\(Zhuangyuzeng\) 	if (!mac_cb->cpld_ctrl)
58031d4446dSYisen.Zhuang\(Zhuangyuzeng\) 		return -ENODEV;
58131d4446dSYisen.Zhuang\(Zhuangyuzeng\) 
5825e89cfacSHuazhong Tan 	ret = dsaf_read_syscon(mac_cb->cpld_ctrl,
5835e89cfacSHuazhong Tan 			       mac_cb->cpld_ctrl_reg + MAC_SFP_PORT_OFFSET,
5845e89cfacSHuazhong Tan 			       &val);
5855e89cfacSHuazhong Tan 	if (ret)
5865e89cfacSHuazhong Tan 		return ret;
58731d4446dSYisen.Zhuang\(Zhuangyuzeng\) 
5885e89cfacSHuazhong Tan 	*sfp_prsnt = !val;
58931d4446dSYisen.Zhuang\(Zhuangyuzeng\) 	return 0;
59031d4446dSYisen.Zhuang\(Zhuangyuzeng\) }
59131d4446dSYisen.Zhuang\(Zhuangyuzeng\) 
hns_mac_get_sfp_prsnt_acpi(struct hns_mac_cb * mac_cb,int * sfp_prsnt)592336a443bSYueHaibing static int hns_mac_get_sfp_prsnt_acpi(struct hns_mac_cb *mac_cb, int *sfp_prsnt)
593b917078cSDaode Huang {
594b917078cSDaode Huang 	union acpi_object *obj;
595b917078cSDaode Huang 	union acpi_object obj_args, argv4;
596b917078cSDaode Huang 
597b917078cSDaode Huang 	obj_args.integer.type = ACPI_TYPE_INTEGER;
598b917078cSDaode Huang 	obj_args.integer.value = mac_cb->mac_id;
599b917078cSDaode Huang 
6003d4068b2SZheng Yongjun 	argv4.type = ACPI_TYPE_PACKAGE;
6013d4068b2SZheng Yongjun 	argv4.package.count = 1;
6023d4068b2SZheng Yongjun 	argv4.package.elements = &obj_args;
603b917078cSDaode Huang 
604*498fe810SAndy Shevchenko 	obj = acpi_evaluate_dsm_typed(ACPI_HANDLE(mac_cb->dev),
60594116f81SAndy Shevchenko 				      &hns_dsaf_acpi_dsm_guid, 0,
606*498fe810SAndy Shevchenko 				      HNS_OP_GET_SFP_STAT_FUNC, &argv4,
607*498fe810SAndy Shevchenko 				      ACPI_TYPE_INTEGER);
608*498fe810SAndy Shevchenko 	if (!obj)
609b917078cSDaode Huang 		return -ENODEV;
610b917078cSDaode Huang 
611b917078cSDaode Huang 	*sfp_prsnt = obj->integer.value;
612b917078cSDaode Huang 
613b917078cSDaode Huang 	ACPI_FREE(obj);
614b917078cSDaode Huang 
615b917078cSDaode Huang 	return 0;
616b917078cSDaode Huang }
617b917078cSDaode Huang 
618511e6bc0Shuangdaode /**
619511e6bc0Shuangdaode  * hns_mac_config_sds_loopback - set loop back for serdes
620511e6bc0Shuangdaode  * @mac_cb: mac control block
621d0ea5cbdSJesse Brandeburg  * @en: enable or disable
622d0ea5cbdSJesse Brandeburg  * return 0 == success
623511e6bc0Shuangdaode  */
hns_mac_config_sds_loopback(struct hns_mac_cb * mac_cb,bool en)624a24274aaSKejian Yan static int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, bool en)
625511e6bc0Shuangdaode {
626511e6bc0Shuangdaode 	const u8 lane_id[] = {
627511e6bc0Shuangdaode 		0,	/* mac 0 -> lane 0 */
628511e6bc0Shuangdaode 		1,	/* mac 1 -> lane 1 */
629511e6bc0Shuangdaode 		2,	/* mac 2 -> lane 2 */
630511e6bc0Shuangdaode 		3,	/* mac 3 -> lane 3 */
631511e6bc0Shuangdaode 		2,	/* mac 4 -> lane 2 */
632511e6bc0Shuangdaode 		3,	/* mac 5 -> lane 3 */
633511e6bc0Shuangdaode 		0,	/* mac 6 -> lane 0 */
634511e6bc0Shuangdaode 		1	/* mac 7 -> lane 1 */
635511e6bc0Shuangdaode 	};
636511e6bc0Shuangdaode #define RX_CSR(lane, reg) ((0x4080 + (reg) * 0x0002 + (lane) * 0x0200) * 2)
637511e6bc0Shuangdaode 	u64 reg_offset = RX_CSR(lane_id[mac_cb->mac_id], 0);
638511e6bc0Shuangdaode 
6395e89cfacSHuazhong Tan 	int sfp_prsnt = 0;
640511e6bc0Shuangdaode 	int ret = hns_mac_get_sfp_prsnt(mac_cb, &sfp_prsnt);
641511e6bc0Shuangdaode 
642652d39b0SKejian Yan 	if (!mac_cb->phy_dev) {
643511e6bc0Shuangdaode 		if (ret)
644511e6bc0Shuangdaode 			pr_info("please confirm sfp is present or not\n");
645511e6bc0Shuangdaode 		else
646511e6bc0Shuangdaode 			if (!sfp_prsnt)
647511e6bc0Shuangdaode 				pr_info("no sfp in this eth\n");
648511e6bc0Shuangdaode 	}
649511e6bc0Shuangdaode 
650831d828bSYisen.Zhuang\(Zhuangyuzeng\) 	if (mac_cb->serdes_ctrl) {
6515e89cfacSHuazhong Tan 		u32 origin = 0;
65289a6b1aaSKejian Yan 
65389a6b1aaSKejian Yan 		if (!AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver)) {
65489a6b1aaSKejian Yan #define HILINK_ACCESS_SEL_CFG		0x40008
65589a6b1aaSKejian Yan 			/* hilink4 & hilink3 use the same xge training and
65689a6b1aaSKejian Yan 			 * xge u adaptor. There is a hilink access sel cfg
65789a6b1aaSKejian Yan 			 * register to select which one to be configed
65889a6b1aaSKejian Yan 			 */
65989a6b1aaSKejian Yan 			if ((!HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev)) &&
66089a6b1aaSKejian Yan 			    (mac_cb->mac_id <= 3))
66189a6b1aaSKejian Yan 				dsaf_write_syscon(mac_cb->serdes_ctrl,
66289a6b1aaSKejian Yan 						  HILINK_ACCESS_SEL_CFG, 0);
66389a6b1aaSKejian Yan 			else
66489a6b1aaSKejian Yan 				dsaf_write_syscon(mac_cb->serdes_ctrl,
66589a6b1aaSKejian Yan 						  HILINK_ACCESS_SEL_CFG, 3);
66689a6b1aaSKejian Yan 		}
66789a6b1aaSKejian Yan 
6685e89cfacSHuazhong Tan 		ret = dsaf_read_syscon(mac_cb->serdes_ctrl, reg_offset,
6695e89cfacSHuazhong Tan 				       &origin);
6705e89cfacSHuazhong Tan 		if (ret)
6715e89cfacSHuazhong Tan 			return ret;
672831d828bSYisen.Zhuang\(Zhuangyuzeng\) 
673a24274aaSKejian Yan 		dsaf_set_field(origin, 1ull << 10, 10, en);
674831d828bSYisen.Zhuang\(Zhuangyuzeng\) 		dsaf_write_syscon(mac_cb->serdes_ctrl, reg_offset, origin);
675831d828bSYisen.Zhuang\(Zhuangyuzeng\) 	} else {
67615400663SYonglong Liu 		u8 __iomem *base_addr = mac_cb->serdes_vaddr +
67789a6b1aaSKejian Yan 				(mac_cb->mac_id <= 3 ? 0x00280000 : 0x00200000);
678a24274aaSKejian Yan 		dsaf_set_reg_field(base_addr, reg_offset, 1ull << 10, 10, en);
679831d828bSYisen.Zhuang\(Zhuangyuzeng\) 	}
680511e6bc0Shuangdaode 
681511e6bc0Shuangdaode 	return 0;
682511e6bc0Shuangdaode }
683a24274aaSKejian Yan 
684f00ef863SKejian Yan static int
hns_mac_config_sds_loopback_acpi(struct hns_mac_cb * mac_cb,bool en)685f00ef863SKejian Yan hns_mac_config_sds_loopback_acpi(struct hns_mac_cb *mac_cb, bool en)
686f00ef863SKejian Yan {
687f00ef863SKejian Yan 	union acpi_object *obj;
688f00ef863SKejian Yan 	union acpi_object obj_args[3], argv4;
689f00ef863SKejian Yan 
690f00ef863SKejian Yan 	obj_args[0].integer.type = ACPI_TYPE_INTEGER;
691f00ef863SKejian Yan 	obj_args[0].integer.value = mac_cb->mac_id;
692f00ef863SKejian Yan 	obj_args[1].integer.type = ACPI_TYPE_INTEGER;
6934a4ec57cSYonglong Liu 	obj_args[1].integer.value = en;
694f00ef863SKejian Yan 
695f00ef863SKejian Yan 	argv4.type = ACPI_TYPE_PACKAGE;
696f00ef863SKejian Yan 	argv4.package.count = 2;
697f00ef863SKejian Yan 	argv4.package.elements = obj_args;
698f00ef863SKejian Yan 
699f00ef863SKejian Yan 	obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dsaf_dev->dev),
70094116f81SAndy Shevchenko 				&hns_dsaf_acpi_dsm_guid, 0,
701f00ef863SKejian Yan 				HNS_OP_SERDES_LP_FUNC, &argv4);
702f00ef863SKejian Yan 	if (!obj) {
703f00ef863SKejian Yan 		dev_warn(mac_cb->dsaf_dev->dev, "set port%d serdes lp fail!",
704f00ef863SKejian Yan 			 mac_cb->mac_id);
705f00ef863SKejian Yan 
706f00ef863SKejian Yan 		return -ENOTSUPP;
707f00ef863SKejian Yan 	}
708f00ef863SKejian Yan 
709f00ef863SKejian Yan 	ACPI_FREE(obj);
710f00ef863SKejian Yan 
711f00ef863SKejian Yan 	return 0;
712f00ef863SKejian Yan }
713f00ef863SKejian Yan 
hns_misc_op_get(struct dsaf_device * dsaf_dev)714a24274aaSKejian Yan struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device *dsaf_dev)
715a24274aaSKejian Yan {
716a24274aaSKejian Yan 	struct dsaf_misc_op *misc_op;
717a24274aaSKejian Yan 
718a24274aaSKejian Yan 	misc_op = devm_kzalloc(dsaf_dev->dev, sizeof(*misc_op), GFP_KERNEL);
719a24274aaSKejian Yan 	if (!misc_op)
720a24274aaSKejian Yan 		return NULL;
721a24274aaSKejian Yan 
7228413b3beSKejian Yan 	if (dev_of_node(dsaf_dev->dev)) {
723a24274aaSKejian Yan 		misc_op->cpld_set_led = hns_cpld_set_led;
724a24274aaSKejian Yan 		misc_op->cpld_reset_led = cpld_led_reset;
725a24274aaSKejian Yan 		misc_op->cpld_set_led_id = cpld_set_led_id;
726a24274aaSKejian Yan 
727a24274aaSKejian Yan 		misc_op->dsaf_reset = hns_dsaf_rst;
728a24274aaSKejian Yan 		misc_op->xge_srst = hns_dsaf_xge_srst_by_port;
729a24274aaSKejian Yan 		misc_op->ge_srst = hns_dsaf_ge_srst_by_port;
730a24274aaSKejian Yan 		misc_op->ppe_srst = hns_ppe_srst_by_port;
731a24274aaSKejian Yan 		misc_op->ppe_comm_srst = hns_ppe_com_srst;
732d605916bSSalil 		misc_op->hns_dsaf_srst_chns = hns_dsaf_srst_chns;
733d605916bSSalil 		misc_op->hns_dsaf_roce_srst = hns_dsaf_roce_srst;
734a24274aaSKejian Yan 
735a24274aaSKejian Yan 		misc_op->get_phy_if = hns_mac_get_phy_if;
736a24274aaSKejian Yan 		misc_op->get_sfp_prsnt = hns_mac_get_sfp_prsnt;
737a24274aaSKejian Yan 
738a24274aaSKejian Yan 		misc_op->cfg_serdes_loopback = hns_mac_config_sds_loopback;
739f00ef863SKejian Yan 	} else if (is_acpi_node(dsaf_dev->dev->fwnode)) {
7401e4babeeSLiuJian 		misc_op->cpld_set_led = hns_cpld_set_led_acpi;
7411e4babeeSLiuJian 		misc_op->cpld_reset_led = cpld_led_reset_acpi;
7423abbccccSJian Shen 		misc_op->cpld_set_led_id = cpld_set_led_id_acpi;
743f00ef863SKejian Yan 
744f00ef863SKejian Yan 		misc_op->dsaf_reset = hns_dsaf_rst_acpi;
745f00ef863SKejian Yan 		misc_op->xge_srst = hns_dsaf_xge_srst_by_port_acpi;
746f00ef863SKejian Yan 		misc_op->ge_srst = hns_dsaf_ge_srst_by_port_acpi;
747f00ef863SKejian Yan 		misc_op->ppe_srst = hns_ppe_srst_by_port_acpi;
748f00ef863SKejian Yan 		misc_op->ppe_comm_srst = hns_ppe_com_srst;
749d605916bSSalil 		misc_op->hns_dsaf_srst_chns = hns_dsaf_srst_chns_acpi;
750d605916bSSalil 		misc_op->hns_dsaf_roce_srst = hns_dsaf_roce_srst_acpi;
751f00ef863SKejian Yan 
752f00ef863SKejian Yan 		misc_op->get_phy_if = hns_mac_get_phy_if_acpi;
753b917078cSDaode Huang 		misc_op->get_sfp_prsnt = hns_mac_get_sfp_prsnt_acpi;
754f00ef863SKejian Yan 
755f00ef863SKejian Yan 		misc_op->cfg_serdes_loopback = hns_mac_config_sds_loopback_acpi;
756f00ef863SKejian Yan 	} else {
757f00ef863SKejian Yan 		devm_kfree(dsaf_dev->dev, (void *)misc_op);
758f00ef863SKejian Yan 		misc_op = NULL;
7598413b3beSKejian Yan 	}
760a24274aaSKejian Yan 
761a24274aaSKejian Yan 	return (void *)misc_op;
762a24274aaSKejian Yan }
763d605916bSSalil 
764d605916bSSalil struct
hns_dsaf_find_platform_device(struct fwnode_handle * fwnode)765d605916bSSalil platform_device *hns_dsaf_find_platform_device(struct fwnode_handle *fwnode)
766d605916bSSalil {
767d605916bSSalil 	struct device *dev;
768d605916bSSalil 
76967843bbaSSuzuki K Poulose 	dev = bus_find_device_by_fwnode(&platform_bus_type, fwnode);
770d605916bSSalil 	return dev ? to_platform_device(dev) : NULL;
771d605916bSSalil }
772