net: hns: Fix sparse: some warnings in HNS drivers
[linux-2.6-block.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                 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 __iomem *base_addr = 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 }