xref: /openbmc/linux/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c (revision 9dae47aba0a055f761176d9297371d5bb24289ec)
1 /*
2  * Copyright (c) 2014-2015 Hisilicon Limited.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  */
9 
10 #include "hns_dsaf_mac.h"
11 #include "hns_dsaf_misc.h"
12 #include "hns_dsaf_ppe.h"
13 #include "hns_dsaf_reg.h"
14 
15 enum _dsm_op_index {
16 	HNS_OP_RESET_FUNC               = 0x1,
17 	HNS_OP_SERDES_LP_FUNC           = 0x2,
18 	HNS_OP_LED_SET_FUNC             = 0x3,
19 	HNS_OP_GET_PORT_TYPE_FUNC       = 0x4,
20 	HNS_OP_GET_SFP_STAT_FUNC        = 0x5,
21 	HNS_OP_LOCATE_LED_SET_FUNC      = 0x6,
22 };
23 
24 enum _dsm_rst_type {
25 	HNS_DSAF_RESET_FUNC     = 0x1,
26 	HNS_PPE_RESET_FUNC      = 0x2,
27 	HNS_XGE_RESET_FUNC      = 0x4,
28 	HNS_GE_RESET_FUNC       = 0x5,
29 	HNS_DSAF_CHN_RESET_FUNC = 0x6,
30 	HNS_ROCE_RESET_FUNC     = 0x7,
31 };
32 
33 static const guid_t hns_dsaf_acpi_dsm_guid =
34 	GUID_INIT(0x1A85AA1A, 0xE293, 0x415E,
35 		  0x8E, 0x28, 0x8D, 0x69, 0x0A, 0x0F, 0x82, 0x0A);
36 
37 static void dsaf_write_sub(struct dsaf_device *dsaf_dev, u32 reg, u32 val)
38 {
39 	if (dsaf_dev->sub_ctrl)
40 		dsaf_write_syscon(dsaf_dev->sub_ctrl, reg, val);
41 	else
42 		dsaf_write_reg(dsaf_dev->sc_base, reg, val);
43 }
44 
45 static u32 dsaf_read_sub(struct dsaf_device *dsaf_dev, u32 reg)
46 {
47 	u32 ret;
48 
49 	if (dsaf_dev->sub_ctrl)
50 		ret = dsaf_read_syscon(dsaf_dev->sub_ctrl, reg);
51 	else
52 		ret = dsaf_read_reg(dsaf_dev->sc_base, reg);
53 
54 	return ret;
55 }
56 
57 static void hns_dsaf_acpi_ledctrl_by_port(struct hns_mac_cb *mac_cb, u8 op_type,
58                                       u32 link, u32 port, u32 act)
59 {
60        union acpi_object *obj;
61        union acpi_object obj_args[3], argv4;
62 
63        obj_args[0].integer.type = ACPI_TYPE_INTEGER;
64        obj_args[0].integer.value = link;
65        obj_args[1].integer.type = ACPI_TYPE_INTEGER;
66        obj_args[1].integer.value = port;
67        obj_args[2].integer.type = ACPI_TYPE_INTEGER;
68        obj_args[2].integer.value = act;
69 
70        argv4.type = ACPI_TYPE_PACKAGE;
71        argv4.package.count = 3;
72        argv4.package.elements = obj_args;
73 
74        obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev),
75                                &hns_dsaf_acpi_dsm_guid, 0, op_type, &argv4);
76        if (!obj) {
77                dev_warn(mac_cb->dev, "ledctrl fail, link:%d port:%d act:%d!\n",
78                         link, port, act);
79                return;
80        }
81 
82        ACPI_FREE(obj);
83 }
84 
85 static void hns_dsaf_acpi_locate_ledctrl_by_port(struct hns_mac_cb *mac_cb,
86 						 u8 op_type, u32 locate,
87 						 u32 port)
88 {
89 	union acpi_object obj_args[2], argv4;
90 	union acpi_object *obj;
91 
92 	obj_args[0].integer.type = ACPI_TYPE_INTEGER;
93 	obj_args[0].integer.value = locate;
94 	obj_args[1].integer.type = ACPI_TYPE_INTEGER;
95 	obj_args[1].integer.value = port;
96 
97 	argv4.type = ACPI_TYPE_PACKAGE;
98 	argv4.package.count = 2;
99 	argv4.package.elements = obj_args;
100 
101 	obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev),
102 				&hns_dsaf_acpi_dsm_guid, 0, op_type, &argv4);
103 	if (!obj) {
104 		dev_err(mac_cb->dev, "ledctrl fail, locate:%d port:%d!\n",
105 			locate, port);
106 		return;
107 	}
108 
109 	ACPI_FREE(obj);
110 }
111 
112 static void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status,
113 			     u16 speed, int data)
114 {
115 	int speed_reg = 0;
116 	u8 value;
117 
118 	if (!mac_cb) {
119 		pr_err("sfp_led_opt mac_dev is null!\n");
120 		return;
121 	}
122 	if (!mac_cb->cpld_ctrl) {
123 		dev_err(mac_cb->dev, "mac_id=%d, cpld syscon is null !\n",
124 			mac_cb->mac_id);
125 		return;
126 	}
127 
128 	if (speed == MAC_SPEED_10000)
129 		speed_reg = 1;
130 
131 	value = mac_cb->cpld_led_value;
132 
133 	if (link_status) {
134 		dsaf_set_bit(value, DSAF_LED_LINK_B, link_status);
135 		dsaf_set_field(value, DSAF_LED_SPEED_M,
136 			       DSAF_LED_SPEED_S, speed_reg);
137 		dsaf_set_bit(value, DSAF_LED_DATA_B, data);
138 
139 		if (value != mac_cb->cpld_led_value) {
140 			dsaf_write_syscon(mac_cb->cpld_ctrl,
141 					  mac_cb->cpld_ctrl_reg, value);
142 			mac_cb->cpld_led_value = value;
143 		}
144 	} else {
145 		value = (mac_cb->cpld_led_value) & (0x1 << DSAF_LED_ANCHOR_B);
146 		dsaf_write_syscon(mac_cb->cpld_ctrl,
147 				  mac_cb->cpld_ctrl_reg, value);
148 		mac_cb->cpld_led_value = value;
149 	}
150 }
151 
152 static void hns_cpld_set_led_acpi(struct hns_mac_cb *mac_cb, int link_status,
153                             u16 speed, int data)
154 {
155        if (!mac_cb) {
156                pr_err("cpld_led_set mac_cb is null!\n");
157                return;
158        }
159 
160        hns_dsaf_acpi_ledctrl_by_port(mac_cb, HNS_OP_LED_SET_FUNC,
161                link_status, mac_cb->mac_id, data);
162 }
163 
164 static void cpld_led_reset(struct hns_mac_cb *mac_cb)
165 {
166 	if (!mac_cb || !mac_cb->cpld_ctrl)
167 		return;
168 
169 	dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg,
170 			  CPLD_LED_DEFAULT_VALUE);
171 	mac_cb->cpld_led_value = CPLD_LED_DEFAULT_VALUE;
172 }
173 
174 static void cpld_led_reset_acpi(struct hns_mac_cb *mac_cb)
175 {
176        if (!mac_cb) {
177                pr_err("cpld_led_reset mac_cb is null!\n");
178                return;
179        }
180 
181        if (mac_cb->media_type != HNAE_MEDIA_TYPE_FIBER)
182                 return;
183 
184        hns_dsaf_acpi_ledctrl_by_port(mac_cb, HNS_OP_LED_SET_FUNC,
185                0, mac_cb->mac_id, 0);
186 }
187 
188 static int cpld_set_led_id(struct hns_mac_cb *mac_cb,
189 			   enum hnae_led_state status)
190 {
191 	if (!mac_cb->cpld_ctrl)
192 		return 0;
193 
194 	switch (status) {
195 	case HNAE_LED_ACTIVE:
196 		mac_cb->cpld_led_value =
197 			dsaf_read_syscon(mac_cb->cpld_ctrl,
198 					 mac_cb->cpld_ctrl_reg);
199 		dsaf_set_bit(mac_cb->cpld_led_value, DSAF_LED_ANCHOR_B,
200 			     CPLD_LED_ON_VALUE);
201 		dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg,
202 				  mac_cb->cpld_led_value);
203 		break;
204 	case HNAE_LED_INACTIVE:
205 		dsaf_set_bit(mac_cb->cpld_led_value, DSAF_LED_ANCHOR_B,
206 			     CPLD_LED_DEFAULT_VALUE);
207 		dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg,
208 				  mac_cb->cpld_led_value);
209 		break;
210 	default:
211 		dev_err(mac_cb->dev, "invalid led state: %d!", status);
212 		return -EINVAL;
213 	}
214 
215 	return 0;
216 }
217 
218 static int cpld_set_led_id_acpi(struct hns_mac_cb *mac_cb,
219 				enum hnae_led_state status)
220 {
221 	switch (status) {
222 	case HNAE_LED_ACTIVE:
223 		hns_dsaf_acpi_locate_ledctrl_by_port(mac_cb,
224 						     HNS_OP_LOCATE_LED_SET_FUNC,
225 						     CPLD_LED_ON_VALUE,
226 						     mac_cb->mac_id);
227 		break;
228 	case HNAE_LED_INACTIVE:
229 		hns_dsaf_acpi_locate_ledctrl_by_port(mac_cb,
230 						     HNS_OP_LOCATE_LED_SET_FUNC,
231 						     CPLD_LED_DEFAULT_VALUE,
232 						     mac_cb->mac_id);
233 		break;
234 	default:
235 		dev_err(mac_cb->dev, "invalid led state: %d!", status);
236 		return -EINVAL;
237 	}
238 
239 	return 0;
240 }
241 
242 #define RESET_REQ_OR_DREQ 1
243 
244 static void hns_dsaf_acpi_srst_by_port(struct dsaf_device *dsaf_dev, u8 op_type,
245 				       u32 port_type, u32 port, u32 val)
246 {
247 	union acpi_object *obj;
248 	union acpi_object obj_args[3], argv4;
249 
250 	obj_args[0].integer.type = ACPI_TYPE_INTEGER;
251 	obj_args[0].integer.value = port_type;
252 	obj_args[1].integer.type = ACPI_TYPE_INTEGER;
253 	obj_args[1].integer.value = port;
254 	obj_args[2].integer.type = ACPI_TYPE_INTEGER;
255 	obj_args[2].integer.value = val;
256 
257 	argv4.type = ACPI_TYPE_PACKAGE;
258 	argv4.package.count = 3;
259 	argv4.package.elements = obj_args;
260 
261 	obj = acpi_evaluate_dsm(ACPI_HANDLE(dsaf_dev->dev),
262 				&hns_dsaf_acpi_dsm_guid, 0, op_type, &argv4);
263 	if (!obj) {
264 		dev_warn(dsaf_dev->dev, "reset port_type%d port%d fail!",
265 			 port_type, port);
266 		return;
267 	}
268 
269 	ACPI_FREE(obj);
270 }
271 
272 static void hns_dsaf_rst(struct dsaf_device *dsaf_dev, bool dereset)
273 {
274 	u32 xbar_reg_addr;
275 	u32 nt_reg_addr;
276 
277 	if (!dereset) {
278 		xbar_reg_addr = DSAF_SUB_SC_XBAR_RESET_REQ_REG;
279 		nt_reg_addr = DSAF_SUB_SC_NT_RESET_REQ_REG;
280 	} else {
281 		xbar_reg_addr = DSAF_SUB_SC_XBAR_RESET_DREQ_REG;
282 		nt_reg_addr = DSAF_SUB_SC_NT_RESET_DREQ_REG;
283 	}
284 
285 	dsaf_write_sub(dsaf_dev, xbar_reg_addr, RESET_REQ_OR_DREQ);
286 	dsaf_write_sub(dsaf_dev, nt_reg_addr, RESET_REQ_OR_DREQ);
287 }
288 
289 static void hns_dsaf_rst_acpi(struct dsaf_device *dsaf_dev, bool dereset)
290 {
291 	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
292 				   HNS_DSAF_RESET_FUNC,
293 				   0, dereset);
294 }
295 
296 static void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
297 				      bool dereset)
298 {
299 	u32 reg_val = 0;
300 	u32 reg_addr;
301 
302 	if (port >= DSAF_XGE_NUM)
303 		return;
304 
305 	reg_val |= RESET_REQ_OR_DREQ;
306 	reg_val |= 0x2082082 << dsaf_dev->mac_cb[port]->port_rst_off;
307 
308 	if (!dereset)
309 		reg_addr = DSAF_SUB_SC_XGE_RESET_REQ_REG;
310 	else
311 		reg_addr = DSAF_SUB_SC_XGE_RESET_DREQ_REG;
312 
313 	dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
314 }
315 
316 static void hns_dsaf_xge_srst_by_port_acpi(struct dsaf_device *dsaf_dev,
317 					   u32 port, bool dereset)
318 {
319 	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
320 				   HNS_XGE_RESET_FUNC, port, dereset);
321 }
322 
323 /**
324  * hns_dsaf_srst_chns - reset dsaf channels
325  * @dsaf_dev: dsaf device struct pointer
326  * @msk: xbar channels mask value:
327  * bit0-5 for xge0-5
328  * bit6-11 for ppe0-5
329  * bit12-17 for roce0-5
330  * bit18-19 for com/dfx
331  * @enable: false - request reset , true - drop reset
332  */
333 void hns_dsaf_srst_chns(struct dsaf_device *dsaf_dev, u32 msk, bool dereset)
334 {
335 	u32 reg_addr;
336 
337 	if (!dereset)
338 		reg_addr = DSAF_SUB_SC_DSAF_RESET_REQ_REG;
339 	else
340 		reg_addr = DSAF_SUB_SC_DSAF_RESET_DREQ_REG;
341 
342 	dsaf_write_sub(dsaf_dev, reg_addr, msk);
343 }
344 
345 /**
346  * hns_dsaf_srst_chns - reset dsaf channels
347  * @dsaf_dev: dsaf device struct pointer
348  * @msk: xbar channels mask value:
349  * bit0-5 for xge0-5
350  * bit6-11 for ppe0-5
351  * bit12-17 for roce0-5
352  * bit18-19 for com/dfx
353  * @enable: false - request reset , true - drop reset
354  */
355 void
356 hns_dsaf_srst_chns_acpi(struct dsaf_device *dsaf_dev, u32 msk, bool dereset)
357 {
358 	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
359 				   HNS_DSAF_CHN_RESET_FUNC,
360 				   msk, dereset);
361 }
362 
363 void hns_dsaf_roce_srst(struct dsaf_device *dsaf_dev, bool dereset)
364 {
365 	if (!dereset) {
366 		dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_ROCEE_RESET_REQ_REG, 1);
367 	} else {
368 		dsaf_write_sub(dsaf_dev,
369 			       DSAF_SUB_SC_ROCEE_CLK_DIS_REG, 1);
370 		dsaf_write_sub(dsaf_dev,
371 			       DSAF_SUB_SC_ROCEE_RESET_DREQ_REG, 1);
372 		msleep(20);
373 		dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_ROCEE_CLK_EN_REG, 1);
374 	}
375 }
376 
377 void hns_dsaf_roce_srst_acpi(struct dsaf_device *dsaf_dev, bool dereset)
378 {
379 	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
380 				   HNS_ROCE_RESET_FUNC, 0, dereset);
381 }
382 
383 static void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
384 				     bool dereset)
385 {
386 	u32 reg_val_1;
387 	u32 reg_val_2;
388 	u32 port_rst_off;
389 
390 	if (port >= DSAF_GE_NUM)
391 		return;
392 
393 	if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) {
394 		reg_val_1  = 0x1 << port;
395 		port_rst_off = dsaf_dev->mac_cb[port]->port_rst_off;
396 		/* there is difference between V1 and V2 in register.*/
397 		reg_val_2 = AE_IS_VER1(dsaf_dev->dsaf_ver) ?
398 				0x1041041 : 0x2082082;
399 		reg_val_2 <<= port_rst_off;
400 
401 		if (!dereset) {
402 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG,
403 				       reg_val_1);
404 
405 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ0_REG,
406 				       reg_val_2);
407 		} else {
408 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ0_REG,
409 				       reg_val_2);
410 
411 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ1_REG,
412 				       reg_val_1);
413 		}
414 	} else {
415 		reg_val_1 = 0x15540;
416 		reg_val_2 = AE_IS_VER1(dsaf_dev->dsaf_ver) ? 0x100 : 0x40;
417 
418 		reg_val_1 <<= dsaf_dev->reset_offset;
419 		reg_val_2 <<= dsaf_dev->reset_offset;
420 
421 		if (!dereset) {
422 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG,
423 				       reg_val_1);
424 
425 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_PPE_RESET_REQ_REG,
426 				       reg_val_2);
427 		} else {
428 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ1_REG,
429 				       reg_val_1);
430 
431 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_PPE_RESET_DREQ_REG,
432 				       reg_val_2);
433 		}
434 	}
435 }
436 
437 static void hns_dsaf_ge_srst_by_port_acpi(struct dsaf_device *dsaf_dev,
438 					  u32 port, bool dereset)
439 {
440 	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
441 				   HNS_GE_RESET_FUNC, port, dereset);
442 }
443 
444 static void hns_ppe_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
445 				 bool dereset)
446 {
447 	u32 reg_val = 0;
448 	u32 reg_addr;
449 
450 	reg_val |= RESET_REQ_OR_DREQ <<	dsaf_dev->mac_cb[port]->port_rst_off;
451 
452 	if (!dereset)
453 		reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG;
454 	else
455 		reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG;
456 
457 	dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
458 }
459 
460 static void
461 hns_ppe_srst_by_port_acpi(struct dsaf_device *dsaf_dev, u32 port, bool dereset)
462 {
463 	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
464 				   HNS_PPE_RESET_FUNC, port, dereset);
465 }
466 
467 static void hns_ppe_com_srst(struct dsaf_device *dsaf_dev, bool dereset)
468 {
469 	u32 reg_val;
470 	u32 reg_addr;
471 
472 	if (!(dev_of_node(dsaf_dev->dev)))
473 		return;
474 
475 	if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) {
476 		reg_val = RESET_REQ_OR_DREQ;
477 		if (!dereset)
478 			reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_REQ_REG;
479 		else
480 			reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_DREQ_REG;
481 
482 	} else {
483 		reg_val = 0x100 << dsaf_dev->reset_offset;
484 
485 		if (!dereset)
486 			reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG;
487 		else
488 			reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG;
489 	}
490 
491 	dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
492 }
493 
494 /**
495  * hns_mac_get_sds_mode - get phy ifterface form serdes mode
496  * @mac_cb: mac control block
497  * retuen phy interface
498  */
499 static phy_interface_t hns_mac_get_phy_if(struct hns_mac_cb *mac_cb)
500 {
501 	u32 mode;
502 	u32 reg;
503 	bool is_ver1 = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver);
504 	int mac_id = mac_cb->mac_id;
505 	phy_interface_t phy_if;
506 
507 	if (is_ver1) {
508 		if (HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev))
509 			return PHY_INTERFACE_MODE_SGMII;
510 
511 		if (mac_id >= 0 && mac_id <= 3)
512 			reg = HNS_MAC_HILINK4_REG;
513 		else
514 			reg = HNS_MAC_HILINK3_REG;
515 	} else{
516 		if (!HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev) && mac_id <= 3)
517 			reg = HNS_MAC_HILINK4V2_REG;
518 		else
519 			reg = HNS_MAC_HILINK3V2_REG;
520 	}
521 
522 	mode = dsaf_read_sub(mac_cb->dsaf_dev, reg);
523 	if (dsaf_get_bit(mode, mac_cb->port_mode_off))
524 		phy_if = PHY_INTERFACE_MODE_XGMII;
525 	else
526 		phy_if = PHY_INTERFACE_MODE_SGMII;
527 
528 	return phy_if;
529 }
530 
531 static phy_interface_t hns_mac_get_phy_if_acpi(struct hns_mac_cb *mac_cb)
532 {
533 	phy_interface_t phy_if = PHY_INTERFACE_MODE_NA;
534 	union acpi_object *obj;
535 	union acpi_object obj_args, argv4;
536 
537 	obj_args.integer.type = ACPI_TYPE_INTEGER;
538 	obj_args.integer.value = mac_cb->mac_id;
539 
540 	argv4.type = ACPI_TYPE_PACKAGE,
541 	argv4.package.count = 1,
542 	argv4.package.elements = &obj_args,
543 
544 	obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev),
545 				&hns_dsaf_acpi_dsm_guid, 0,
546 				HNS_OP_GET_PORT_TYPE_FUNC, &argv4);
547 
548 	if (!obj || obj->type != ACPI_TYPE_INTEGER)
549 		return phy_if;
550 
551 	phy_if = obj->integer.value ?
552 		PHY_INTERFACE_MODE_XGMII : PHY_INTERFACE_MODE_SGMII;
553 
554 	dev_dbg(mac_cb->dev, "mac_id=%d, phy_if=%d\n", mac_cb->mac_id, phy_if);
555 
556 	ACPI_FREE(obj);
557 
558 	return phy_if;
559 }
560 
561 int hns_mac_get_sfp_prsnt(struct hns_mac_cb *mac_cb, int *sfp_prsnt)
562 {
563 	if (!mac_cb->cpld_ctrl)
564 		return -ENODEV;
565 
566 	*sfp_prsnt = !dsaf_read_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg
567 					+ MAC_SFP_PORT_OFFSET);
568 
569 	return 0;
570 }
571 
572 int hns_mac_get_sfp_prsnt_acpi(struct hns_mac_cb *mac_cb, int *sfp_prsnt)
573 {
574 	union acpi_object *obj;
575 	union acpi_object obj_args, argv4;
576 
577 	obj_args.integer.type = ACPI_TYPE_INTEGER;
578 	obj_args.integer.value = mac_cb->mac_id;
579 
580 	argv4.type = ACPI_TYPE_PACKAGE,
581 	argv4.package.count = 1,
582 	argv4.package.elements = &obj_args,
583 
584 	obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev),
585 				&hns_dsaf_acpi_dsm_guid, 0,
586 				HNS_OP_GET_SFP_STAT_FUNC, &argv4);
587 
588 	if (!obj || obj->type != ACPI_TYPE_INTEGER)
589 		return -ENODEV;
590 
591 	*sfp_prsnt = obj->integer.value;
592 
593 	ACPI_FREE(obj);
594 
595 	return 0;
596 }
597 
598 /**
599  * hns_mac_config_sds_loopback - set loop back for serdes
600  * @mac_cb: mac control block
601  * retuen 0 == success
602  */
603 static int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, bool en)
604 {
605 	const u8 lane_id[] = {
606 		0,	/* mac 0 -> lane 0 */
607 		1,	/* mac 1 -> lane 1 */
608 		2,	/* mac 2 -> lane 2 */
609 		3,	/* mac 3 -> lane 3 */
610 		2,	/* mac 4 -> lane 2 */
611 		3,	/* mac 5 -> lane 3 */
612 		0,	/* mac 6 -> lane 0 */
613 		1	/* mac 7 -> lane 1 */
614 	};
615 #define RX_CSR(lane, reg) ((0x4080 + (reg) * 0x0002 + (lane) * 0x0200) * 2)
616 	u64 reg_offset = RX_CSR(lane_id[mac_cb->mac_id], 0);
617 
618 	int sfp_prsnt;
619 	int ret = hns_mac_get_sfp_prsnt(mac_cb, &sfp_prsnt);
620 
621 	if (!mac_cb->phy_dev) {
622 		if (ret)
623 			pr_info("please confirm sfp is present or not\n");
624 		else
625 			if (!sfp_prsnt)
626 				pr_info("no sfp in this eth\n");
627 	}
628 
629 	if (mac_cb->serdes_ctrl) {
630 		u32 origin;
631 
632 		if (!AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver)) {
633 #define HILINK_ACCESS_SEL_CFG		0x40008
634 			/* hilink4 & hilink3 use the same xge training and
635 			 * xge u adaptor. There is a hilink access sel cfg
636 			 * register to select which one to be configed
637 			 */
638 			if ((!HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev)) &&
639 			    (mac_cb->mac_id <= 3))
640 				dsaf_write_syscon(mac_cb->serdes_ctrl,
641 						  HILINK_ACCESS_SEL_CFG, 0);
642 			else
643 				dsaf_write_syscon(mac_cb->serdes_ctrl,
644 						  HILINK_ACCESS_SEL_CFG, 3);
645 		}
646 
647 		origin = dsaf_read_syscon(mac_cb->serdes_ctrl, reg_offset);
648 
649 		dsaf_set_field(origin, 1ull << 10, 10, en);
650 		dsaf_write_syscon(mac_cb->serdes_ctrl, reg_offset, origin);
651 	} else {
652 		u8 *base_addr = (u8 *)mac_cb->serdes_vaddr +
653 				(mac_cb->mac_id <= 3 ? 0x00280000 : 0x00200000);
654 		dsaf_set_reg_field(base_addr, reg_offset, 1ull << 10, 10, en);
655 	}
656 
657 	return 0;
658 }
659 
660 static int
661 hns_mac_config_sds_loopback_acpi(struct hns_mac_cb *mac_cb, bool en)
662 {
663 	union acpi_object *obj;
664 	union acpi_object obj_args[3], argv4;
665 
666 	obj_args[0].integer.type = ACPI_TYPE_INTEGER;
667 	obj_args[0].integer.value = mac_cb->mac_id;
668 	obj_args[1].integer.type = ACPI_TYPE_INTEGER;
669 	obj_args[1].integer.value = !!en;
670 
671 	argv4.type = ACPI_TYPE_PACKAGE;
672 	argv4.package.count = 2;
673 	argv4.package.elements = obj_args;
674 
675 	obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dsaf_dev->dev),
676 				&hns_dsaf_acpi_dsm_guid, 0,
677 				HNS_OP_SERDES_LP_FUNC, &argv4);
678 	if (!obj) {
679 		dev_warn(mac_cb->dsaf_dev->dev, "set port%d serdes lp fail!",
680 			 mac_cb->mac_id);
681 
682 		return -ENOTSUPP;
683 	}
684 
685 	ACPI_FREE(obj);
686 
687 	return 0;
688 }
689 
690 struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device *dsaf_dev)
691 {
692 	struct dsaf_misc_op *misc_op;
693 
694 	misc_op = devm_kzalloc(dsaf_dev->dev, sizeof(*misc_op), GFP_KERNEL);
695 	if (!misc_op)
696 		return NULL;
697 
698 	if (dev_of_node(dsaf_dev->dev)) {
699 		misc_op->cpld_set_led = hns_cpld_set_led;
700 		misc_op->cpld_reset_led = cpld_led_reset;
701 		misc_op->cpld_set_led_id = cpld_set_led_id;
702 
703 		misc_op->dsaf_reset = hns_dsaf_rst;
704 		misc_op->xge_srst = hns_dsaf_xge_srst_by_port;
705 		misc_op->ge_srst = hns_dsaf_ge_srst_by_port;
706 		misc_op->ppe_srst = hns_ppe_srst_by_port;
707 		misc_op->ppe_comm_srst = hns_ppe_com_srst;
708 		misc_op->hns_dsaf_srst_chns = hns_dsaf_srst_chns;
709 		misc_op->hns_dsaf_roce_srst = hns_dsaf_roce_srst;
710 
711 		misc_op->get_phy_if = hns_mac_get_phy_if;
712 		misc_op->get_sfp_prsnt = hns_mac_get_sfp_prsnt;
713 
714 		misc_op->cfg_serdes_loopback = hns_mac_config_sds_loopback;
715 	} else if (is_acpi_node(dsaf_dev->dev->fwnode)) {
716 		misc_op->cpld_set_led = hns_cpld_set_led_acpi;
717 		misc_op->cpld_reset_led = cpld_led_reset_acpi;
718 		misc_op->cpld_set_led_id = cpld_set_led_id_acpi;
719 
720 		misc_op->dsaf_reset = hns_dsaf_rst_acpi;
721 		misc_op->xge_srst = hns_dsaf_xge_srst_by_port_acpi;
722 		misc_op->ge_srst = hns_dsaf_ge_srst_by_port_acpi;
723 		misc_op->ppe_srst = hns_ppe_srst_by_port_acpi;
724 		misc_op->ppe_comm_srst = hns_ppe_com_srst;
725 		misc_op->hns_dsaf_srst_chns = hns_dsaf_srst_chns_acpi;
726 		misc_op->hns_dsaf_roce_srst = hns_dsaf_roce_srst_acpi;
727 
728 		misc_op->get_phy_if = hns_mac_get_phy_if_acpi;
729 		misc_op->get_sfp_prsnt = hns_mac_get_sfp_prsnt_acpi;
730 
731 		misc_op->cfg_serdes_loopback = hns_mac_config_sds_loopback_acpi;
732 	} else {
733 		devm_kfree(dsaf_dev->dev, (void *)misc_op);
734 		misc_op = NULL;
735 	}
736 
737 	return (void *)misc_op;
738 }
739 
740 static int hns_dsaf_dev_match(struct device *dev, void *fwnode)
741 {
742 	return dev->fwnode == fwnode;
743 }
744 
745 struct
746 platform_device *hns_dsaf_find_platform_device(struct fwnode_handle *fwnode)
747 {
748 	struct device *dev;
749 
750 	dev = bus_find_device(&platform_bus_type, NULL,
751 			      fwnode, hns_dsaf_dev_match);
752 	return dev ? to_platform_device(dev) : NULL;
753 }
754