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