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