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