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