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 void hns_dsaf_srst_chns(struct dsaf_device *dsaf_dev, u32 msk, bool dereset)
344 {
345 	u32 reg_addr;
346 
347 	if (!dereset)
348 		reg_addr = DSAF_SUB_SC_DSAF_RESET_REQ_REG;
349 	else
350 		reg_addr = DSAF_SUB_SC_DSAF_RESET_DREQ_REG;
351 
352 	dsaf_write_sub(dsaf_dev, reg_addr, msk);
353 }
354 
355 /**
356  * hns_dsaf_srst_chns - reset dsaf channels
357  * @dsaf_dev: dsaf device struct pointer
358  * @msk: xbar channels mask value:
359  * bit0-5 for xge0-5
360  * bit6-11 for ppe0-5
361  * bit12-17 for roce0-5
362  * bit18-19 for com/dfx
363  * @enable: false - request reset , true - drop reset
364  */
365 void
366 hns_dsaf_srst_chns_acpi(struct dsaf_device *dsaf_dev, u32 msk, bool dereset)
367 {
368 	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
369 				   HNS_DSAF_CHN_RESET_FUNC,
370 				   msk, dereset);
371 }
372 
373 void hns_dsaf_roce_srst(struct dsaf_device *dsaf_dev, bool dereset)
374 {
375 	if (!dereset) {
376 		dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_ROCEE_RESET_REQ_REG, 1);
377 	} else {
378 		dsaf_write_sub(dsaf_dev,
379 			       DSAF_SUB_SC_ROCEE_CLK_DIS_REG, 1);
380 		dsaf_write_sub(dsaf_dev,
381 			       DSAF_SUB_SC_ROCEE_RESET_DREQ_REG, 1);
382 		msleep(20);
383 		dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_ROCEE_CLK_EN_REG, 1);
384 	}
385 }
386 
387 void hns_dsaf_roce_srst_acpi(struct dsaf_device *dsaf_dev, bool dereset)
388 {
389 	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
390 				   HNS_ROCE_RESET_FUNC, 0, dereset);
391 }
392 
393 static void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
394 				     bool dereset)
395 {
396 	u32 reg_val_1;
397 	u32 reg_val_2;
398 	u32 port_rst_off;
399 
400 	if (port >= DSAF_GE_NUM)
401 		return;
402 
403 	if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) {
404 		reg_val_1  = 0x1 << port;
405 		port_rst_off = dsaf_dev->mac_cb[port]->port_rst_off;
406 		/* there is difference between V1 and V2 in register.*/
407 		reg_val_2 = AE_IS_VER1(dsaf_dev->dsaf_ver) ?
408 				0x1041041 : 0x2082082;
409 		reg_val_2 <<= port_rst_off;
410 
411 		if (!dereset) {
412 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG,
413 				       reg_val_1);
414 
415 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ0_REG,
416 				       reg_val_2);
417 		} else {
418 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ0_REG,
419 				       reg_val_2);
420 
421 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ1_REG,
422 				       reg_val_1);
423 		}
424 	} else {
425 		reg_val_1 = 0x15540;
426 		reg_val_2 = AE_IS_VER1(dsaf_dev->dsaf_ver) ? 0x100 : 0x40;
427 
428 		reg_val_1 <<= dsaf_dev->reset_offset;
429 		reg_val_2 <<= dsaf_dev->reset_offset;
430 
431 		if (!dereset) {
432 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG,
433 				       reg_val_1);
434 
435 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_PPE_RESET_REQ_REG,
436 				       reg_val_2);
437 		} else {
438 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ1_REG,
439 				       reg_val_1);
440 
441 			dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_PPE_RESET_DREQ_REG,
442 				       reg_val_2);
443 		}
444 	}
445 }
446 
447 static void hns_dsaf_ge_srst_by_port_acpi(struct dsaf_device *dsaf_dev,
448 					  u32 port, bool dereset)
449 {
450 	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
451 				   HNS_GE_RESET_FUNC, port, dereset);
452 }
453 
454 static void hns_ppe_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
455 				 bool dereset)
456 {
457 	u32 reg_val = 0;
458 	u32 reg_addr;
459 
460 	reg_val |= RESET_REQ_OR_DREQ <<	dsaf_dev->mac_cb[port]->port_rst_off;
461 
462 	if (!dereset)
463 		reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG;
464 	else
465 		reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG;
466 
467 	dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
468 }
469 
470 static void
471 hns_ppe_srst_by_port_acpi(struct dsaf_device *dsaf_dev, u32 port, bool dereset)
472 {
473 	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
474 				   HNS_PPE_RESET_FUNC, port, dereset);
475 }
476 
477 static void hns_ppe_com_srst(struct dsaf_device *dsaf_dev, bool dereset)
478 {
479 	u32 reg_val;
480 	u32 reg_addr;
481 
482 	if (!(dev_of_node(dsaf_dev->dev)))
483 		return;
484 
485 	if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) {
486 		reg_val = RESET_REQ_OR_DREQ;
487 		if (!dereset)
488 			reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_REQ_REG;
489 		else
490 			reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_DREQ_REG;
491 
492 	} else {
493 		reg_val = 0x100 << dsaf_dev->reset_offset;
494 
495 		if (!dereset)
496 			reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG;
497 		else
498 			reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG;
499 	}
500 
501 	dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
502 }
503 
504 /**
505  * hns_mac_get_sds_mode - get phy ifterface form serdes mode
506  * @mac_cb: mac control block
507  * retuen phy interface
508  */
509 static phy_interface_t hns_mac_get_phy_if(struct hns_mac_cb *mac_cb)
510 {
511 	u32 mode;
512 	u32 reg;
513 	bool is_ver1 = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver);
514 	int mac_id = mac_cb->mac_id;
515 	phy_interface_t phy_if;
516 
517 	if (is_ver1) {
518 		if (HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev))
519 			return PHY_INTERFACE_MODE_SGMII;
520 
521 		if (mac_id >= 0 && mac_id <= 3)
522 			reg = HNS_MAC_HILINK4_REG;
523 		else
524 			reg = HNS_MAC_HILINK3_REG;
525 	} else{
526 		if (!HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev) && mac_id <= 3)
527 			reg = HNS_MAC_HILINK4V2_REG;
528 		else
529 			reg = HNS_MAC_HILINK3V2_REG;
530 	}
531 
532 	mode = dsaf_read_sub(mac_cb->dsaf_dev, reg);
533 	if (dsaf_get_bit(mode, mac_cb->port_mode_off))
534 		phy_if = PHY_INTERFACE_MODE_XGMII;
535 	else
536 		phy_if = PHY_INTERFACE_MODE_SGMII;
537 
538 	return phy_if;
539 }
540 
541 static phy_interface_t hns_mac_get_phy_if_acpi(struct hns_mac_cb *mac_cb)
542 {
543 	phy_interface_t phy_if = PHY_INTERFACE_MODE_NA;
544 	union acpi_object *obj;
545 	union acpi_object obj_args, argv4;
546 
547 	obj_args.integer.type = ACPI_TYPE_INTEGER;
548 	obj_args.integer.value = mac_cb->mac_id;
549 
550 	argv4.type = ACPI_TYPE_PACKAGE,
551 	argv4.package.count = 1,
552 	argv4.package.elements = &obj_args,
553 
554 	obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev),
555 				&hns_dsaf_acpi_dsm_guid, 0,
556 				HNS_OP_GET_PORT_TYPE_FUNC, &argv4);
557 
558 	if (!obj || obj->type != ACPI_TYPE_INTEGER)
559 		return phy_if;
560 
561 	phy_if = obj->integer.value ?
562 		PHY_INTERFACE_MODE_XGMII : PHY_INTERFACE_MODE_SGMII;
563 
564 	dev_dbg(mac_cb->dev, "mac_id=%d, phy_if=%d\n", mac_cb->mac_id, phy_if);
565 
566 	ACPI_FREE(obj);
567 
568 	return phy_if;
569 }
570 
571 int hns_mac_get_sfp_prsnt(struct hns_mac_cb *mac_cb, int *sfp_prsnt)
572 {
573 	u32 val = 0;
574 	int ret;
575 
576 	if (!mac_cb->cpld_ctrl)
577 		return -ENODEV;
578 
579 	ret = dsaf_read_syscon(mac_cb->cpld_ctrl,
580 			       mac_cb->cpld_ctrl_reg + MAC_SFP_PORT_OFFSET,
581 			       &val);
582 	if (ret)
583 		return ret;
584 
585 	*sfp_prsnt = !val;
586 	return 0;
587 }
588 
589 int hns_mac_get_sfp_prsnt_acpi(struct hns_mac_cb *mac_cb, int *sfp_prsnt)
590 {
591 	union acpi_object *obj;
592 	union acpi_object obj_args, argv4;
593 
594 	obj_args.integer.type = ACPI_TYPE_INTEGER;
595 	obj_args.integer.value = mac_cb->mac_id;
596 
597 	argv4.type = ACPI_TYPE_PACKAGE,
598 	argv4.package.count = 1,
599 	argv4.package.elements = &obj_args,
600 
601 	obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev),
602 				&hns_dsaf_acpi_dsm_guid, 0,
603 				HNS_OP_GET_SFP_STAT_FUNC, &argv4);
604 
605 	if (!obj || obj->type != ACPI_TYPE_INTEGER)
606 		return -ENODEV;
607 
608 	*sfp_prsnt = obj->integer.value;
609 
610 	ACPI_FREE(obj);
611 
612 	return 0;
613 }
614 
615 /**
616  * hns_mac_config_sds_loopback - set loop back for serdes
617  * @mac_cb: mac control block
618  * retuen 0 == success
619  */
620 static int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, bool en)
621 {
622 	const u8 lane_id[] = {
623 		0,	/* mac 0 -> lane 0 */
624 		1,	/* mac 1 -> lane 1 */
625 		2,	/* mac 2 -> lane 2 */
626 		3,	/* mac 3 -> lane 3 */
627 		2,	/* mac 4 -> lane 2 */
628 		3,	/* mac 5 -> lane 3 */
629 		0,	/* mac 6 -> lane 0 */
630 		1	/* mac 7 -> lane 1 */
631 	};
632 #define RX_CSR(lane, reg) ((0x4080 + (reg) * 0x0002 + (lane) * 0x0200) * 2)
633 	u64 reg_offset = RX_CSR(lane_id[mac_cb->mac_id], 0);
634 
635 	int sfp_prsnt = 0;
636 	int ret = hns_mac_get_sfp_prsnt(mac_cb, &sfp_prsnt);
637 
638 	if (!mac_cb->phy_dev) {
639 		if (ret)
640 			pr_info("please confirm sfp is present or not\n");
641 		else
642 			if (!sfp_prsnt)
643 				pr_info("no sfp in this eth\n");
644 	}
645 
646 	if (mac_cb->serdes_ctrl) {
647 		u32 origin = 0;
648 
649 		if (!AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver)) {
650 #define HILINK_ACCESS_SEL_CFG		0x40008
651 			/* hilink4 & hilink3 use the same xge training and
652 			 * xge u adaptor. There is a hilink access sel cfg
653 			 * register to select which one to be configed
654 			 */
655 			if ((!HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev)) &&
656 			    (mac_cb->mac_id <= 3))
657 				dsaf_write_syscon(mac_cb->serdes_ctrl,
658 						  HILINK_ACCESS_SEL_CFG, 0);
659 			else
660 				dsaf_write_syscon(mac_cb->serdes_ctrl,
661 						  HILINK_ACCESS_SEL_CFG, 3);
662 		}
663 
664 		ret = dsaf_read_syscon(mac_cb->serdes_ctrl, reg_offset,
665 				       &origin);
666 		if (ret)
667 			return ret;
668 
669 		dsaf_set_field(origin, 1ull << 10, 10, en);
670 		dsaf_write_syscon(mac_cb->serdes_ctrl, reg_offset, origin);
671 	} else {
672 		u8 *base_addr = (u8 *)mac_cb->serdes_vaddr +
673 				(mac_cb->mac_id <= 3 ? 0x00280000 : 0x00200000);
674 		dsaf_set_reg_field(base_addr, reg_offset, 1ull << 10, 10, en);
675 	}
676 
677 	return 0;
678 }
679 
680 static int
681 hns_mac_config_sds_loopback_acpi(struct hns_mac_cb *mac_cb, bool en)
682 {
683 	union acpi_object *obj;
684 	union acpi_object obj_args[3], argv4;
685 
686 	obj_args[0].integer.type = ACPI_TYPE_INTEGER;
687 	obj_args[0].integer.value = mac_cb->mac_id;
688 	obj_args[1].integer.type = ACPI_TYPE_INTEGER;
689 	obj_args[1].integer.value = !!en;
690 
691 	argv4.type = ACPI_TYPE_PACKAGE;
692 	argv4.package.count = 2;
693 	argv4.package.elements = obj_args;
694 
695 	obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dsaf_dev->dev),
696 				&hns_dsaf_acpi_dsm_guid, 0,
697 				HNS_OP_SERDES_LP_FUNC, &argv4);
698 	if (!obj) {
699 		dev_warn(mac_cb->dsaf_dev->dev, "set port%d serdes lp fail!",
700 			 mac_cb->mac_id);
701 
702 		return -ENOTSUPP;
703 	}
704 
705 	ACPI_FREE(obj);
706 
707 	return 0;
708 }
709 
710 struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device *dsaf_dev)
711 {
712 	struct dsaf_misc_op *misc_op;
713 
714 	misc_op = devm_kzalloc(dsaf_dev->dev, sizeof(*misc_op), GFP_KERNEL);
715 	if (!misc_op)
716 		return NULL;
717 
718 	if (dev_of_node(dsaf_dev->dev)) {
719 		misc_op->cpld_set_led = hns_cpld_set_led;
720 		misc_op->cpld_reset_led = cpld_led_reset;
721 		misc_op->cpld_set_led_id = cpld_set_led_id;
722 
723 		misc_op->dsaf_reset = hns_dsaf_rst;
724 		misc_op->xge_srst = hns_dsaf_xge_srst_by_port;
725 		misc_op->ge_srst = hns_dsaf_ge_srst_by_port;
726 		misc_op->ppe_srst = hns_ppe_srst_by_port;
727 		misc_op->ppe_comm_srst = hns_ppe_com_srst;
728 		misc_op->hns_dsaf_srst_chns = hns_dsaf_srst_chns;
729 		misc_op->hns_dsaf_roce_srst = hns_dsaf_roce_srst;
730 
731 		misc_op->get_phy_if = hns_mac_get_phy_if;
732 		misc_op->get_sfp_prsnt = hns_mac_get_sfp_prsnt;
733 
734 		misc_op->cfg_serdes_loopback = hns_mac_config_sds_loopback;
735 	} else if (is_acpi_node(dsaf_dev->dev->fwnode)) {
736 		misc_op->cpld_set_led = hns_cpld_set_led_acpi;
737 		misc_op->cpld_reset_led = cpld_led_reset_acpi;
738 		misc_op->cpld_set_led_id = cpld_set_led_id_acpi;
739 
740 		misc_op->dsaf_reset = hns_dsaf_rst_acpi;
741 		misc_op->xge_srst = hns_dsaf_xge_srst_by_port_acpi;
742 		misc_op->ge_srst = hns_dsaf_ge_srst_by_port_acpi;
743 		misc_op->ppe_srst = hns_ppe_srst_by_port_acpi;
744 		misc_op->ppe_comm_srst = hns_ppe_com_srst;
745 		misc_op->hns_dsaf_srst_chns = hns_dsaf_srst_chns_acpi;
746 		misc_op->hns_dsaf_roce_srst = hns_dsaf_roce_srst_acpi;
747 
748 		misc_op->get_phy_if = hns_mac_get_phy_if_acpi;
749 		misc_op->get_sfp_prsnt = hns_mac_get_sfp_prsnt_acpi;
750 
751 		misc_op->cfg_serdes_loopback = hns_mac_config_sds_loopback_acpi;
752 	} else {
753 		devm_kfree(dsaf_dev->dev, (void *)misc_op);
754 		misc_op = NULL;
755 	}
756 
757 	return (void *)misc_op;
758 }
759 
760 static int hns_dsaf_dev_match(struct device *dev, void *fwnode)
761 {
762 	return dev->fwnode == fwnode;
763 }
764 
765 struct
766 platform_device *hns_dsaf_find_platform_device(struct fwnode_handle *fwnode)
767 {
768 	struct device *dev;
769 
770 	dev = bus_find_device(&platform_bus_type, NULL,
771 			      fwnode, hns_dsaf_dev_match);
772 	return dev ? to_platform_device(dev) : NULL;
773 }
774