1
2
3
4
5
6
7
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
15enum _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
24enum _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
33static const guid_t hns_dsaf_acpi_dsm_guid =
34 GUID_INIT(0x1A85AA1A, 0xE293, 0x415E,
35 0x8E, 0x28, 0x8D, 0x69, 0x0A, 0x0F, 0x82, 0x0A);
36
37static 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
45static 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
62static 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
90static 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
117static 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
157static 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
169static 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
179static 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
193static 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
228static 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
254static 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
282static 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
299static 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
306static 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
326static 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
335
336
337
338
339
340
341
342
343void 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
357
358
359
360
361
362
363
364
365void
366hns_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
373void 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
387void 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
393static 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
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
447static 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
454static 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
470static void
471hns_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
477static 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
506
507
508
509static 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
541static 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
571int 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
589int 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
617
618
619
620static int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, bool en)
621{
622 const u8 lane_id[] = {
623 0,
624 1,
625 2,
626 3,
627 2,
628 3,
629 0,
630 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
652
653
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
680static int
681hns_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
710struct 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
760static int hns_dsaf_dev_match(struct device *dev, void *fwnode)
761{
762 return dev->fwnode == fwnode;
763}
764
765struct
766platform_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