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 } 775