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
dsaf_write_sub(struct dsaf_device * dsaf_dev,u32 reg,u32 val)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
dsaf_read_sub(struct dsaf_device * dsaf_dev,u32 reg)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
hns_dsaf_acpi_ledctrl_by_port(struct hns_mac_cb * mac_cb,u8 op_type,u32 link,u32 port,u32 act)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
hns_dsaf_acpi_locate_ledctrl_by_port(struct hns_mac_cb * mac_cb,u8 op_type,u32 locate,u32 port)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
hns_cpld_set_led(struct hns_mac_cb * mac_cb,int link_status,u16 speed,int data)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
hns_cpld_set_led_acpi(struct hns_mac_cb * mac_cb,int link_status,u16 speed,int data)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
cpld_led_reset(struct hns_mac_cb * mac_cb)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
cpld_led_reset_acpi(struct hns_mac_cb * mac_cb)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
cpld_set_led_id(struct hns_mac_cb * mac_cb,enum hnae_led_state status)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
cpld_set_led_id_acpi(struct hns_mac_cb * mac_cb,enum hnae_led_state status)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
hns_dsaf_acpi_srst_by_port(struct dsaf_device * dsaf_dev,u8 op_type,u32 port_type,u32 port,u32 val)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
hns_dsaf_rst(struct dsaf_device * dsaf_dev,bool dereset)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
hns_dsaf_rst_acpi(struct dsaf_device * dsaf_dev,bool dereset)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
hns_dsaf_xge_srst_by_port(struct dsaf_device * dsaf_dev,u32 port,bool dereset)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
hns_dsaf_xge_srst_by_port_acpi(struct dsaf_device * dsaf_dev,u32 port,bool dereset)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
hns_dsaf_srst_chns(struct dsaf_device * dsaf_dev,u32 msk,bool dereset)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
hns_dsaf_srst_chns_acpi(struct dsaf_device * dsaf_dev,u32 msk,bool dereset)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
hns_dsaf_roce_srst(struct dsaf_device * dsaf_dev,bool dereset)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
hns_dsaf_roce_srst_acpi(struct dsaf_device * dsaf_dev,bool dereset)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
hns_dsaf_ge_srst_by_port(struct dsaf_device * dsaf_dev,u32 port,bool dereset)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
hns_dsaf_ge_srst_by_port_acpi(struct dsaf_device * dsaf_dev,u32 port,bool dereset)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
hns_ppe_srst_by_port(struct dsaf_device * dsaf_dev,u32 port,bool dereset)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
hns_ppe_srst_by_port_acpi(struct dsaf_device * dsaf_dev,u32 port,bool dereset)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
hns_ppe_com_srst(struct dsaf_device * dsaf_dev,bool dereset)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 */
hns_mac_get_phy_if(struct hns_mac_cb * mac_cb)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
hns_mac_get_phy_if_acpi(struct hns_mac_cb * mac_cb)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
hns_mac_get_sfp_prsnt(struct hns_mac_cb * mac_cb,int * sfp_prsnt)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
hns_mac_get_sfp_prsnt_acpi(struct hns_mac_cb * mac_cb,int * sfp_prsnt)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 */
hns_mac_config_sds_loopback(struct hns_mac_cb * mac_cb,bool en)621 static int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, bool en)
622 {
623 const u8 lane_id[] = {
624 0, /* mac 0 -> lane 0 */
625 1, /* mac 1 -> lane 1 */
626 2, /* mac 2 -> lane 2 */
627 3, /* mac 3 -> lane 3 */
628 2, /* mac 4 -> lane 2 */
629 3, /* mac 5 -> lane 3 */
630 0, /* mac 6 -> lane 0 */
631 1 /* mac 7 -> lane 1 */
632 };
633 #define RX_CSR(lane, reg) ((0x4080 + (reg) * 0x0002 + (lane) * 0x0200) * 2)
634 u64 reg_offset = RX_CSR(lane_id[mac_cb->mac_id], 0);
635
636 int sfp_prsnt = 0;
637 int ret = hns_mac_get_sfp_prsnt(mac_cb, &sfp_prsnt);
638
639 if (!mac_cb->phy_dev) {
640 if (ret)
641 pr_info("please confirm sfp is present or not\n");
642 else
643 if (!sfp_prsnt)
644 pr_info("no sfp in this eth\n");
645 }
646
647 if (mac_cb->serdes_ctrl) {
648 u32 origin = 0;
649
650 if (!AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver)) {
651 #define HILINK_ACCESS_SEL_CFG 0x40008
652 /* hilink4 & hilink3 use the same xge training and
653 * xge u adaptor. There is a hilink access sel cfg
654 * register to select which one to be configed
655 */
656 if ((!HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev)) &&
657 (mac_cb->mac_id <= 3))
658 dsaf_write_syscon(mac_cb->serdes_ctrl,
659 HILINK_ACCESS_SEL_CFG, 0);
660 else
661 dsaf_write_syscon(mac_cb->serdes_ctrl,
662 HILINK_ACCESS_SEL_CFG, 3);
663 }
664
665 ret = dsaf_read_syscon(mac_cb->serdes_ctrl, reg_offset,
666 &origin);
667 if (ret)
668 return ret;
669
670 dsaf_set_field(origin, 1ull << 10, 10, en);
671 dsaf_write_syscon(mac_cb->serdes_ctrl, reg_offset, origin);
672 } else {
673 u8 *base_addr = (u8 *)mac_cb->serdes_vaddr +
674 (mac_cb->mac_id <= 3 ? 0x00280000 : 0x00200000);
675 dsaf_set_reg_field(base_addr, reg_offset, 1ull << 10, 10, en);
676 }
677
678 return 0;
679 }
680
681 static int
hns_mac_config_sds_loopback_acpi(struct hns_mac_cb * mac_cb,bool en)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
hns_misc_op_get(struct dsaf_device * dsaf_dev)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
hns_dsaf_dev_match(struct device * dev,void * fwnode)761 static int hns_dsaf_dev_match(struct device *dev, void *fwnode)
762 {
763 return dev->fwnode == fwnode;
764 }
765
766 struct
hns_dsaf_find_platform_device(struct fwnode_handle * fwnode)767 platform_device *hns_dsaf_find_platform_device(struct fwnode_handle *fwnode)
768 {
769 struct device *dev;
770
771 dev = bus_find_device(&platform_bus_type, NULL,
772 fwnode, hns_dsaf_dev_match);
773 return dev ? to_platform_device(dev) : NULL;
774 }
775