]> git.ipfire.org Git - thirdparty/kernel/linux.git/blame - drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
net: hns: Fix sparse: some warnings in HNS drivers
[thirdparty/kernel/linux.git] / drivers / net / ethernet / hisilicon / hns / hns_dsaf_misc.c
CommitLineData
511e6bc0 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
511e6bc0 10#include "hns_dsaf_mac.h"
2e2591b1 11#include "hns_dsaf_misc.h"
511e6bc0 12#include "hns_dsaf_ppe.h"
2e2591b1 13#include "hns_dsaf_reg.h"
511e6bc0 14
f00ef863
KY
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,
3abbcccc 21 HNS_OP_LOCATE_LED_SET_FUNC = 0x6,
f00ef863
KY
22};
23
24enum _dsm_rst_type {
25 HNS_DSAF_RESET_FUNC = 0x1,
26 HNS_PPE_RESET_FUNC = 0x2,
f00ef863
KY
27 HNS_XGE_RESET_FUNC = 0x4,
28 HNS_GE_RESET_FUNC = 0x5,
d605916b
S
29 HNS_DSAF_CHN_RESET_FUNC = 0x6,
30 HNS_ROCE_RESET_FUNC = 0x7,
f00ef863
KY
31};
32
b86a496a 33static const guid_t hns_dsaf_acpi_dsm_guid =
94116f81
AS
34 GUID_INIT(0x1A85AA1A, 0xE293, 0x415E,
35 0x8E, 0x28, 0x8D, 0x69, 0x0A, 0x0F, 0x82, 0x0A);
f00ef863 36
831d828b
YZZ
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{
5e89cfac
HT
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 {
831d828b 56 ret = dsaf_read_reg(dsaf_dev->sc_base, reg);
5e89cfac 57 }
831d828b
YZZ
58
59 return ret;
60}
61
1e4babee
L
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
3abbcccc
JS
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
a24274aa
KY
117static void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status,
118 u16 speed, int data)
511e6bc0 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 }
31d4446d
YZZ
127 if (!mac_cb->cpld_ctrl) {
128 dev_err(mac_cb->dev, "mac_id=%d, cpld syscon is null !\n",
511e6bc0 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) {
31d4446d
YZZ
145 dsaf_write_syscon(mac_cb->cpld_ctrl,
146 mac_cb->cpld_ctrl_reg, value);
511e6bc0 147 mac_cb->cpld_led_value = value;
148 }
149 } else {
d8a8371e
DH
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;
511e6bc0 154 }
155}
156
1e4babee
L
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
a24274aa 169static void cpld_led_reset(struct hns_mac_cb *mac_cb)
511e6bc0 170{
31d4446d 171 if (!mac_cb || !mac_cb->cpld_ctrl)
511e6bc0 172 return;
173
31d4446d
YZZ
174 dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg,
175 CPLD_LED_DEFAULT_VALUE);
511e6bc0 176 mac_cb->cpld_led_value = CPLD_LED_DEFAULT_VALUE;
177}
178
1e4babee
L
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
a24274aa
KY
193static int cpld_set_led_id(struct hns_mac_cb *mac_cb,
194 enum hnae_led_state status)
511e6bc0 195{
5e89cfac
HT
196 u32 val = 0;
197 int ret;
198
3abbcccc
JS
199 if (!mac_cb->cpld_ctrl)
200 return 0;
201
511e6bc0 202 switch (status) {
203 case HNAE_LED_ACTIVE:
5e89cfac
HT
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);
31d4446d 210 dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg,
5e89cfac
HT
211 val);
212 mac_cb->cpld_led_value = val;
d8a8371e 213 break;
511e6bc0 214 case HNAE_LED_INACTIVE:
215 dsaf_set_bit(mac_cb->cpld_led_value, DSAF_LED_ANCHOR_B,
216 CPLD_LED_DEFAULT_VALUE);
31d4446d
YZZ
217 dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg,
218 mac_cb->cpld_led_value);
511e6bc0 219 break;
220 default:
d8a8371e
DH
221 dev_err(mac_cb->dev, "invalid led state: %d!", status);
222 return -EINVAL;
511e6bc0 223 }
224
225 return 0;
226}
227
3abbcccc
JS
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
511e6bc0 252#define RESET_REQ_OR_DREQ 1
253
f00ef863
KY
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),
94116f81 272 &hns_dsaf_acpi_dsm_guid, 0, op_type, &argv4);
f00ef863
KY
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
a24274aa 282static void hns_dsaf_rst(struct dsaf_device *dsaf_dev, bool dereset)
511e6bc0 283{
284 u32 xbar_reg_addr;
285 u32 nt_reg_addr;
286
a24274aa 287 if (!dereset) {
511e6bc0 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
831d828b
YZZ
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);
511e6bc0 297}
298
f00ef863
KY
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
a24274aa
KY
306static void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
307 bool dereset)
511e6bc0 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;
850bfa3b 316 reg_val |= 0x2082082 << dsaf_dev->mac_cb[port]->port_rst_off;
511e6bc0 317
a24274aa 318 if (!dereset)
511e6bc0 319 reg_addr = DSAF_SUB_SC_XGE_RESET_REQ_REG;
320 else
321 reg_addr = DSAF_SUB_SC_XGE_RESET_DREQ_REG;
322
831d828b 323 dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
511e6bc0 324}
325
f00ef863
KY
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
e0180688 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 */
336a443b
Y
343static void
344hns_dsaf_srst_chns(struct dsaf_device *dsaf_dev, u32 msk, bool dereset)
e0180688 345{
346 u32 reg_addr;
347
d605916b 348 if (!dereset)
e0180688 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
d605916b
S
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 */
336a443b 366static void
d605916b 367hns_dsaf_srst_chns_acpi(struct dsaf_device *dsaf_dev, u32 msk, bool dereset)
e0180688 368{
d605916b
S
369 hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
370 HNS_DSAF_CHN_RESET_FUNC,
371 msk, dereset);
372}
373
336a443b 374static void hns_dsaf_roce_srst(struct dsaf_device *dsaf_dev, bool dereset)
d605916b
S
375{
376 if (!dereset) {
e0180688 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
336a443b 388static void hns_dsaf_roce_srst_acpi(struct dsaf_device *dsaf_dev, bool dereset)
d605916b
S
389{
390 hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
391 HNS_ROCE_RESET_FUNC, 0, dereset);
392}
393
a24274aa
KY
394static void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
395 bool dereset)
511e6bc0 396{
397 u32 reg_val_1;
398 u32 reg_val_2;
850bfa3b 399 u32 port_rst_off;
511e6bc0 400
401 if (port >= DSAF_GE_NUM)
402 return;
403
89a44093 404 if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) {
511e6bc0 405 reg_val_1 = 0x1 << port;
850bfa3b 406 port_rst_off = dsaf_dev->mac_cb[port]->port_rst_off;
13ac695e 407 /* there is difference between V1 and V2 in register.*/
d9fdb4ed
DH
408 reg_val_2 = AE_IS_VER1(dsaf_dev->dsaf_ver) ?
409 0x1041041 : 0x2082082;
410 reg_val_2 <<= port_rst_off;
511e6bc0 411
a24274aa 412 if (!dereset) {
831d828b 413 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG,
511e6bc0 414 reg_val_1);
415
831d828b 416 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ0_REG,
511e6bc0 417 reg_val_2);
418 } else {
831d828b 419 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ0_REG,
511e6bc0 420 reg_val_2);
421
831d828b 422 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ1_REG,
511e6bc0 423 reg_val_1);
424 }
425 } else {
d9fdb4ed
DH
426 reg_val_1 = 0x15540;
427 reg_val_2 = AE_IS_VER1(dsaf_dev->dsaf_ver) ? 0x100 : 0x40;
0b03fd85 428
d9fdb4ed
DH
429 reg_val_1 <<= dsaf_dev->reset_offset;
430 reg_val_2 <<= dsaf_dev->reset_offset;
511e6bc0 431
a24274aa 432 if (!dereset) {
831d828b 433 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG,
511e6bc0 434 reg_val_1);
435
831d828b 436 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_PPE_RESET_REQ_REG,
511e6bc0 437 reg_val_2);
438 } else {
831d828b 439 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ1_REG,
511e6bc0 440 reg_val_1);
441
831d828b 442 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_PPE_RESET_DREQ_REG,
511e6bc0 443 reg_val_2);
444 }
445 }
446}
447
f00ef863
KY
448static 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
a24274aa
KY
455static void hns_ppe_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
456 bool dereset)
511e6bc0 457{
458 u32 reg_val = 0;
459 u32 reg_addr;
460
850bfa3b 461 reg_val |= RESET_REQ_OR_DREQ << dsaf_dev->mac_cb[port]->port_rst_off;
511e6bc0 462
a24274aa 463 if (!dereset)
511e6bc0 464 reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG;
465 else
466 reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG;
467
831d828b 468 dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
511e6bc0 469}
470
f00ef863
KY
471static void
472hns_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
a24274aa 478static void hns_ppe_com_srst(struct dsaf_device *dsaf_dev, bool dereset)
511e6bc0 479{
511e6bc0 480 u32 reg_val;
481 u32 reg_addr;
482
f00ef863
KY
483 if (!(dev_of_node(dsaf_dev->dev)))
484 return;
485
89a44093 486 if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) {
511e6bc0 487 reg_val = RESET_REQ_OR_DREQ;
a24274aa 488 if (!dereset)
511e6bc0 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 {
422c3107 494 reg_val = 0x100 << dsaf_dev->reset_offset;
511e6bc0 495
a24274aa 496 if (!dereset)
511e6bc0 497 reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG;
498 else
499 reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG;
500 }
501
831d828b 502 dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
511e6bc0 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 */
a24274aa 510static phy_interface_t hns_mac_get_phy_if(struct hns_mac_cb *mac_cb)
511e6bc0 511{
c1203fe7
SL
512 u32 mode;
513 u32 reg;
c1203fe7 514 bool is_ver1 = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver);
c1203fe7 515 int mac_id = mac_cb->mac_id;
0d768fc6 516 phy_interface_t phy_if;
511e6bc0 517
0d768fc6
YZZ
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;
511e6bc0 524 else
0d768fc6
YZZ
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;
c1203fe7 529 else
0d768fc6 530 reg = HNS_MAC_HILINK3V2_REG;
511e6bc0 531 }
0d768fc6
YZZ
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
511e6bc0 539 return phy_if;
540}
541
f00ef863
KY
542static 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),
94116f81 556 &hns_dsaf_acpi_dsm_guid, 0,
f00ef863
KY
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
336a443b 572static int hns_mac_get_sfp_prsnt(struct hns_mac_cb *mac_cb, int *sfp_prsnt)
31d4446d 573{
5e89cfac
HT
574 u32 val = 0;
575 int ret;
576
31d4446d
YZZ
577 if (!mac_cb->cpld_ctrl)
578 return -ENODEV;
579
5e89cfac
HT
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;
31d4446d 585
5e89cfac 586 *sfp_prsnt = !val;
31d4446d
YZZ
587 return 0;
588}
589
336a443b 590static int hns_mac_get_sfp_prsnt_acpi(struct hns_mac_cb *mac_cb, int *sfp_prsnt)
b917078c
DH
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),
94116f81 603 &hns_dsaf_acpi_dsm_guid, 0,
b917078c
DH
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
511e6bc0 616/**
617 * hns_mac_config_sds_loopback - set loop back for serdes
618 * @mac_cb: mac control block
619 * retuen 0 == success
620 */
a24274aa 621static int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, bool en)
511e6bc0 622{
511e6bc0 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
5e89cfac 636 int sfp_prsnt = 0;
511e6bc0 637 int ret = hns_mac_get_sfp_prsnt(mac_cb, &sfp_prsnt);
638
652d39b0 639 if (!mac_cb->phy_dev) {
511e6bc0 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
831d828b 647 if (mac_cb->serdes_ctrl) {
5e89cfac 648 u32 origin = 0;
89a6b1aa
KY
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
5e89cfac
HT
665 ret = dsaf_read_syscon(mac_cb->serdes_ctrl, reg_offset,
666 &origin);
667 if (ret)
668 return ret;
831d828b 669
a24274aa 670 dsaf_set_field(origin, 1ull << 10, 10, en);
831d828b
YZZ
671 dsaf_write_syscon(mac_cb->serdes_ctrl, reg_offset, origin);
672 } else {
15400663 673 u8 __iomem *base_addr = mac_cb->serdes_vaddr +
89a6b1aa 674 (mac_cb->mac_id <= 3 ? 0x00280000 : 0x00200000);
a24274aa 675 dsaf_set_reg_field(base_addr, reg_offset, 1ull << 10, 10, en);
831d828b 676 }
511e6bc0 677
678 return 0;
679}
a24274aa 680
f00ef863
KY
681static int
682hns_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),
94116f81 697 &hns_dsaf_acpi_dsm_guid, 0,
f00ef863
KY
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
a24274aa
KY
711struct 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
8413b3be
KY
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;
8413b3be
KY
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;
d605916b
S
729 misc_op->hns_dsaf_srst_chns = hns_dsaf_srst_chns;
730 misc_op->hns_dsaf_roce_srst = hns_dsaf_roce_srst;
8413b3be
KY
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;
f00ef863 736 } else if (is_acpi_node(dsaf_dev->dev->fwnode)) {
1e4babee
L
737 misc_op->cpld_set_led = hns_cpld_set_led_acpi;
738 misc_op->cpld_reset_led = cpld_led_reset_acpi;
3abbcccc 739 misc_op->cpld_set_led_id = cpld_set_led_id_acpi;
f00ef863
KY
740
741 misc_op->dsaf_reset = hns_dsaf_rst_acpi;
742 misc_op->xge_srst = hns_dsaf_xge_srst_by_port_acpi;
f00ef863
KY
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;
d605916b
S
746 misc_op->hns_dsaf_srst_chns = hns_dsaf_srst_chns_acpi;
747 misc_op->hns_dsaf_roce_srst = hns_dsaf_roce_srst_acpi;
f00ef863
KY
748
749 misc_op->get_phy_if = hns_mac_get_phy_if_acpi;
b917078c 750 misc_op->get_sfp_prsnt = hns_mac_get_sfp_prsnt_acpi;
f00ef863
KY
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;
8413b3be 756 }
a24274aa
KY
757
758 return (void *)misc_op;
759}
d605916b
S
760
761static int hns_dsaf_dev_match(struct device *dev, void *fwnode)
762{
763 return dev->fwnode == fwnode;
764}
765
766struct
767platform_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}