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; 48 49 if (dsaf_dev->sub_ctrl) 50 ret = dsaf_read_syscon(dsaf_dev->sub_ctrl, reg); 51 else 52 ret = dsaf_read_reg(dsaf_dev->sc_base, reg); 53 54 return ret; 55 } 56 57 static void hns_dsaf_acpi_ledctrl_by_port(struct hns_mac_cb *mac_cb, u8 op_type, 58 u32 link, u32 port, u32 act) 59 { 60 union acpi_object *obj; 61 union acpi_object obj_args[3], argv4; 62 63 obj_args[0].integer.type = ACPI_TYPE_INTEGER; 64 obj_args[0].integer.value = link; 65 obj_args[1].integer.type = ACPI_TYPE_INTEGER; 66 obj_args[1].integer.value = port; 67 obj_args[2].integer.type = ACPI_TYPE_INTEGER; 68 obj_args[2].integer.value = act; 69 70 argv4.type = ACPI_TYPE_PACKAGE; 71 argv4.package.count = 3; 72 argv4.package.elements = obj_args; 73 74 obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev), 75 &hns_dsaf_acpi_dsm_guid, 0, op_type, &argv4); 76 if (!obj) { 77 dev_warn(mac_cb->dev, "ledctrl fail, link:%d port:%d act:%d!\n", 78 link, port, act); 79 return; 80 } 81 82 ACPI_FREE(obj); 83 } 84 85 static void hns_dsaf_acpi_locate_ledctrl_by_port(struct hns_mac_cb *mac_cb, 86 u8 op_type, u32 locate, 87 u32 port) 88 { 89 union acpi_object obj_args[2], argv4; 90 union acpi_object *obj; 91 92 obj_args[0].integer.type = ACPI_TYPE_INTEGER; 93 obj_args[0].integer.value = locate; 94 obj_args[1].integer.type = ACPI_TYPE_INTEGER; 95 obj_args[1].integer.value = port; 96 97 argv4.type = ACPI_TYPE_PACKAGE; 98 argv4.package.count = 2; 99 argv4.package.elements = obj_args; 100 101 obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev), 102 &hns_dsaf_acpi_dsm_guid, 0, op_type, &argv4); 103 if (!obj) { 104 dev_err(mac_cb->dev, "ledctrl fail, locate:%d port:%d!\n", 105 locate, port); 106 return; 107 } 108 109 ACPI_FREE(obj); 110 } 111 112 static void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status, 113 u16 speed, int data) 114 { 115 int speed_reg = 0; 116 u8 value; 117 118 if (!mac_cb) { 119 pr_err("sfp_led_opt mac_dev is null!\n"); 120 return; 121 } 122 if (!mac_cb->cpld_ctrl) { 123 dev_err(mac_cb->dev, "mac_id=%d, cpld syscon is null !\n", 124 mac_cb->mac_id); 125 return; 126 } 127 128 if (speed == MAC_SPEED_10000) 129 speed_reg = 1; 130 131 value = mac_cb->cpld_led_value; 132 133 if (link_status) { 134 dsaf_set_bit(value, DSAF_LED_LINK_B, link_status); 135 dsaf_set_field(value, DSAF_LED_SPEED_M, 136 DSAF_LED_SPEED_S, speed_reg); 137 dsaf_set_bit(value, DSAF_LED_DATA_B, data); 138 139 if (value != mac_cb->cpld_led_value) { 140 dsaf_write_syscon(mac_cb->cpld_ctrl, 141 mac_cb->cpld_ctrl_reg, value); 142 mac_cb->cpld_led_value = value; 143 } 144 } else { 145 value = (mac_cb->cpld_led_value) & (0x1 << DSAF_LED_ANCHOR_B); 146 dsaf_write_syscon(mac_cb->cpld_ctrl, 147 mac_cb->cpld_ctrl_reg, value); 148 mac_cb->cpld_led_value = value; 149 } 150 } 151 152 static void hns_cpld_set_led_acpi(struct hns_mac_cb *mac_cb, int link_status, 153 u16 speed, int data) 154 { 155 if (!mac_cb) { 156 pr_err("cpld_led_set mac_cb is null!\n"); 157 return; 158 } 159 160 hns_dsaf_acpi_ledctrl_by_port(mac_cb, HNS_OP_LED_SET_FUNC, 161 link_status, mac_cb->mac_id, data); 162 } 163 164 static void cpld_led_reset(struct hns_mac_cb *mac_cb) 165 { 166 if (!mac_cb || !mac_cb->cpld_ctrl) 167 return; 168 169 dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg, 170 CPLD_LED_DEFAULT_VALUE); 171 mac_cb->cpld_led_value = CPLD_LED_DEFAULT_VALUE; 172 } 173 174 static void cpld_led_reset_acpi(struct hns_mac_cb *mac_cb) 175 { 176 if (!mac_cb) { 177 pr_err("cpld_led_reset mac_cb is null!\n"); 178 return; 179 } 180 181 if (mac_cb->media_type != HNAE_MEDIA_TYPE_FIBER) 182 return; 183 184 hns_dsaf_acpi_ledctrl_by_port(mac_cb, HNS_OP_LED_SET_FUNC, 185 0, mac_cb->mac_id, 0); 186 } 187 188 static int cpld_set_led_id(struct hns_mac_cb *mac_cb, 189 enum hnae_led_state status) 190 { 191 if (!mac_cb->cpld_ctrl) 192 return 0; 193 194 switch (status) { 195 case HNAE_LED_ACTIVE: 196 mac_cb->cpld_led_value = 197 dsaf_read_syscon(mac_cb->cpld_ctrl, 198 mac_cb->cpld_ctrl_reg); 199 dsaf_set_bit(mac_cb->cpld_led_value, DSAF_LED_ANCHOR_B, 200 CPLD_LED_ON_VALUE); 201 dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg, 202 mac_cb->cpld_led_value); 203 break; 204 case HNAE_LED_INACTIVE: 205 dsaf_set_bit(mac_cb->cpld_led_value, DSAF_LED_ANCHOR_B, 206 CPLD_LED_DEFAULT_VALUE); 207 dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg, 208 mac_cb->cpld_led_value); 209 break; 210 default: 211 dev_err(mac_cb->dev, "invalid led state: %d!", status); 212 return -EINVAL; 213 } 214 215 return 0; 216 } 217 218 static int cpld_set_led_id_acpi(struct hns_mac_cb *mac_cb, 219 enum hnae_led_state status) 220 { 221 switch (status) { 222 case HNAE_LED_ACTIVE: 223 hns_dsaf_acpi_locate_ledctrl_by_port(mac_cb, 224 HNS_OP_LOCATE_LED_SET_FUNC, 225 CPLD_LED_ON_VALUE, 226 mac_cb->mac_id); 227 break; 228 case HNAE_LED_INACTIVE: 229 hns_dsaf_acpi_locate_ledctrl_by_port(mac_cb, 230 HNS_OP_LOCATE_LED_SET_FUNC, 231 CPLD_LED_DEFAULT_VALUE, 232 mac_cb->mac_id); 233 break; 234 default: 235 dev_err(mac_cb->dev, "invalid led state: %d!", status); 236 return -EINVAL; 237 } 238 239 return 0; 240 } 241 242 #define RESET_REQ_OR_DREQ 1 243 244 static void hns_dsaf_acpi_srst_by_port(struct dsaf_device *dsaf_dev, u8 op_type, 245 u32 port_type, u32 port, u32 val) 246 { 247 union acpi_object *obj; 248 union acpi_object obj_args[3], argv4; 249 250 obj_args[0].integer.type = ACPI_TYPE_INTEGER; 251 obj_args[0].integer.value = port_type; 252 obj_args[1].integer.type = ACPI_TYPE_INTEGER; 253 obj_args[1].integer.value = port; 254 obj_args[2].integer.type = ACPI_TYPE_INTEGER; 255 obj_args[2].integer.value = val; 256 257 argv4.type = ACPI_TYPE_PACKAGE; 258 argv4.package.count = 3; 259 argv4.package.elements = obj_args; 260 261 obj = acpi_evaluate_dsm(ACPI_HANDLE(dsaf_dev->dev), 262 &hns_dsaf_acpi_dsm_guid, 0, op_type, &argv4); 263 if (!obj) { 264 dev_warn(dsaf_dev->dev, "reset port_type%d port%d fail!", 265 port_type, port); 266 return; 267 } 268 269 ACPI_FREE(obj); 270 } 271 272 static void hns_dsaf_rst(struct dsaf_device *dsaf_dev, bool dereset) 273 { 274 u32 xbar_reg_addr; 275 u32 nt_reg_addr; 276 277 if (!dereset) { 278 xbar_reg_addr = DSAF_SUB_SC_XBAR_RESET_REQ_REG; 279 nt_reg_addr = DSAF_SUB_SC_NT_RESET_REQ_REG; 280 } else { 281 xbar_reg_addr = DSAF_SUB_SC_XBAR_RESET_DREQ_REG; 282 nt_reg_addr = DSAF_SUB_SC_NT_RESET_DREQ_REG; 283 } 284 285 dsaf_write_sub(dsaf_dev, xbar_reg_addr, RESET_REQ_OR_DREQ); 286 dsaf_write_sub(dsaf_dev, nt_reg_addr, RESET_REQ_OR_DREQ); 287 } 288 289 static void hns_dsaf_rst_acpi(struct dsaf_device *dsaf_dev, bool dereset) 290 { 291 hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC, 292 HNS_DSAF_RESET_FUNC, 293 0, dereset); 294 } 295 296 static void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, 297 bool dereset) 298 { 299 u32 reg_val = 0; 300 u32 reg_addr; 301 302 if (port >= DSAF_XGE_NUM) 303 return; 304 305 reg_val |= RESET_REQ_OR_DREQ; 306 reg_val |= 0x2082082 << dsaf_dev->mac_cb[port]->port_rst_off; 307 308 if (!dereset) 309 reg_addr = DSAF_SUB_SC_XGE_RESET_REQ_REG; 310 else 311 reg_addr = DSAF_SUB_SC_XGE_RESET_DREQ_REG; 312 313 dsaf_write_sub(dsaf_dev, reg_addr, reg_val); 314 } 315 316 static void hns_dsaf_xge_srst_by_port_acpi(struct dsaf_device *dsaf_dev, 317 u32 port, bool dereset) 318 { 319 hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC, 320 HNS_XGE_RESET_FUNC, port, dereset); 321 } 322 323 /** 324 * hns_dsaf_srst_chns - reset dsaf channels 325 * @dsaf_dev: dsaf device struct pointer 326 * @msk: xbar channels mask value: 327 * bit0-5 for xge0-5 328 * bit6-11 for ppe0-5 329 * bit12-17 for roce0-5 330 * bit18-19 for com/dfx 331 * @enable: false - request reset , true - drop reset 332 */ 333 void hns_dsaf_srst_chns(struct dsaf_device *dsaf_dev, u32 msk, bool dereset) 334 { 335 u32 reg_addr; 336 337 if (!dereset) 338 reg_addr = DSAF_SUB_SC_DSAF_RESET_REQ_REG; 339 else 340 reg_addr = DSAF_SUB_SC_DSAF_RESET_DREQ_REG; 341 342 dsaf_write_sub(dsaf_dev, reg_addr, msk); 343 } 344 345 /** 346 * hns_dsaf_srst_chns - reset dsaf channels 347 * @dsaf_dev: dsaf device struct pointer 348 * @msk: xbar channels mask value: 349 * bit0-5 for xge0-5 350 * bit6-11 for ppe0-5 351 * bit12-17 for roce0-5 352 * bit18-19 for com/dfx 353 * @enable: false - request reset , true - drop reset 354 */ 355 void 356 hns_dsaf_srst_chns_acpi(struct dsaf_device *dsaf_dev, u32 msk, bool dereset) 357 { 358 hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC, 359 HNS_DSAF_CHN_RESET_FUNC, 360 msk, dereset); 361 } 362 363 void hns_dsaf_roce_srst(struct dsaf_device *dsaf_dev, bool dereset) 364 { 365 if (!dereset) { 366 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_ROCEE_RESET_REQ_REG, 1); 367 } else { 368 dsaf_write_sub(dsaf_dev, 369 DSAF_SUB_SC_ROCEE_CLK_DIS_REG, 1); 370 dsaf_write_sub(dsaf_dev, 371 DSAF_SUB_SC_ROCEE_RESET_DREQ_REG, 1); 372 msleep(20); 373 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_ROCEE_CLK_EN_REG, 1); 374 } 375 } 376 377 void hns_dsaf_roce_srst_acpi(struct dsaf_device *dsaf_dev, bool dereset) 378 { 379 hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC, 380 HNS_ROCE_RESET_FUNC, 0, dereset); 381 } 382 383 static void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, 384 bool dereset) 385 { 386 u32 reg_val_1; 387 u32 reg_val_2; 388 u32 port_rst_off; 389 390 if (port >= DSAF_GE_NUM) 391 return; 392 393 if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) { 394 reg_val_1 = 0x1 << port; 395 port_rst_off = dsaf_dev->mac_cb[port]->port_rst_off; 396 /* there is difference between V1 and V2 in register.*/ 397 reg_val_2 = AE_IS_VER1(dsaf_dev->dsaf_ver) ? 398 0x1041041 : 0x2082082; 399 reg_val_2 <<= port_rst_off; 400 401 if (!dereset) { 402 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG, 403 reg_val_1); 404 405 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ0_REG, 406 reg_val_2); 407 } else { 408 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ0_REG, 409 reg_val_2); 410 411 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ1_REG, 412 reg_val_1); 413 } 414 } else { 415 reg_val_1 = 0x15540; 416 reg_val_2 = AE_IS_VER1(dsaf_dev->dsaf_ver) ? 0x100 : 0x40; 417 418 reg_val_1 <<= dsaf_dev->reset_offset; 419 reg_val_2 <<= dsaf_dev->reset_offset; 420 421 if (!dereset) { 422 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG, 423 reg_val_1); 424 425 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_PPE_RESET_REQ_REG, 426 reg_val_2); 427 } else { 428 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ1_REG, 429 reg_val_1); 430 431 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_PPE_RESET_DREQ_REG, 432 reg_val_2); 433 } 434 } 435 } 436 437 static void hns_dsaf_ge_srst_by_port_acpi(struct dsaf_device *dsaf_dev, 438 u32 port, bool dereset) 439 { 440 hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC, 441 HNS_GE_RESET_FUNC, port, dereset); 442 } 443 444 static void hns_ppe_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, 445 bool dereset) 446 { 447 u32 reg_val = 0; 448 u32 reg_addr; 449 450 reg_val |= RESET_REQ_OR_DREQ << dsaf_dev->mac_cb[port]->port_rst_off; 451 452 if (!dereset) 453 reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG; 454 else 455 reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG; 456 457 dsaf_write_sub(dsaf_dev, reg_addr, reg_val); 458 } 459 460 static void 461 hns_ppe_srst_by_port_acpi(struct dsaf_device *dsaf_dev, u32 port, bool dereset) 462 { 463 hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC, 464 HNS_PPE_RESET_FUNC, port, dereset); 465 } 466 467 static void hns_ppe_com_srst(struct dsaf_device *dsaf_dev, bool dereset) 468 { 469 u32 reg_val; 470 u32 reg_addr; 471 472 if (!(dev_of_node(dsaf_dev->dev))) 473 return; 474 475 if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) { 476 reg_val = RESET_REQ_OR_DREQ; 477 if (!dereset) 478 reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_REQ_REG; 479 else 480 reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_DREQ_REG; 481 482 } else { 483 reg_val = 0x100 << dsaf_dev->reset_offset; 484 485 if (!dereset) 486 reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG; 487 else 488 reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG; 489 } 490 491 dsaf_write_sub(dsaf_dev, reg_addr, reg_val); 492 } 493 494 /** 495 * hns_mac_get_sds_mode - get phy ifterface form serdes mode 496 * @mac_cb: mac control block 497 * retuen phy interface 498 */ 499 static phy_interface_t hns_mac_get_phy_if(struct hns_mac_cb *mac_cb) 500 { 501 u32 mode; 502 u32 reg; 503 bool is_ver1 = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver); 504 int mac_id = mac_cb->mac_id; 505 phy_interface_t phy_if; 506 507 if (is_ver1) { 508 if (HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev)) 509 return PHY_INTERFACE_MODE_SGMII; 510 511 if (mac_id >= 0 && mac_id <= 3) 512 reg = HNS_MAC_HILINK4_REG; 513 else 514 reg = HNS_MAC_HILINK3_REG; 515 } else{ 516 if (!HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev) && mac_id <= 3) 517 reg = HNS_MAC_HILINK4V2_REG; 518 else 519 reg = HNS_MAC_HILINK3V2_REG; 520 } 521 522 mode = dsaf_read_sub(mac_cb->dsaf_dev, reg); 523 if (dsaf_get_bit(mode, mac_cb->port_mode_off)) 524 phy_if = PHY_INTERFACE_MODE_XGMII; 525 else 526 phy_if = PHY_INTERFACE_MODE_SGMII; 527 528 return phy_if; 529 } 530 531 static phy_interface_t hns_mac_get_phy_if_acpi(struct hns_mac_cb *mac_cb) 532 { 533 phy_interface_t phy_if = PHY_INTERFACE_MODE_NA; 534 union acpi_object *obj; 535 union acpi_object obj_args, argv4; 536 537 obj_args.integer.type = ACPI_TYPE_INTEGER; 538 obj_args.integer.value = mac_cb->mac_id; 539 540 argv4.type = ACPI_TYPE_PACKAGE, 541 argv4.package.count = 1, 542 argv4.package.elements = &obj_args, 543 544 obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev), 545 &hns_dsaf_acpi_dsm_guid, 0, 546 HNS_OP_GET_PORT_TYPE_FUNC, &argv4); 547 548 if (!obj || obj->type != ACPI_TYPE_INTEGER) 549 return phy_if; 550 551 phy_if = obj->integer.value ? 552 PHY_INTERFACE_MODE_XGMII : PHY_INTERFACE_MODE_SGMII; 553 554 dev_dbg(mac_cb->dev, "mac_id=%d, phy_if=%d\n", mac_cb->mac_id, phy_if); 555 556 ACPI_FREE(obj); 557 558 return phy_if; 559 } 560 561 int hns_mac_get_sfp_prsnt(struct hns_mac_cb *mac_cb, int *sfp_prsnt) 562 { 563 if (!mac_cb->cpld_ctrl) 564 return -ENODEV; 565 566 *sfp_prsnt = !dsaf_read_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg 567 + MAC_SFP_PORT_OFFSET); 568 569 return 0; 570 } 571 572 int hns_mac_get_sfp_prsnt_acpi(struct hns_mac_cb *mac_cb, int *sfp_prsnt) 573 { 574 union acpi_object *obj; 575 union acpi_object obj_args, argv4; 576 577 obj_args.integer.type = ACPI_TYPE_INTEGER; 578 obj_args.integer.value = mac_cb->mac_id; 579 580 argv4.type = ACPI_TYPE_PACKAGE, 581 argv4.package.count = 1, 582 argv4.package.elements = &obj_args, 583 584 obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev), 585 &hns_dsaf_acpi_dsm_guid, 0, 586 HNS_OP_GET_SFP_STAT_FUNC, &argv4); 587 588 if (!obj || obj->type != ACPI_TYPE_INTEGER) 589 return -ENODEV; 590 591 *sfp_prsnt = obj->integer.value; 592 593 ACPI_FREE(obj); 594 595 return 0; 596 } 597 598 /** 599 * hns_mac_config_sds_loopback - set loop back for serdes 600 * @mac_cb: mac control block 601 * retuen 0 == success 602 */ 603 static int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, bool en) 604 { 605 const u8 lane_id[] = { 606 0, /* mac 0 -> lane 0 */ 607 1, /* mac 1 -> lane 1 */ 608 2, /* mac 2 -> lane 2 */ 609 3, /* mac 3 -> lane 3 */ 610 2, /* mac 4 -> lane 2 */ 611 3, /* mac 5 -> lane 3 */ 612 0, /* mac 6 -> lane 0 */ 613 1 /* mac 7 -> lane 1 */ 614 }; 615 #define RX_CSR(lane, reg) ((0x4080 + (reg) * 0x0002 + (lane) * 0x0200) * 2) 616 u64 reg_offset = RX_CSR(lane_id[mac_cb->mac_id], 0); 617 618 int sfp_prsnt; 619 int ret = hns_mac_get_sfp_prsnt(mac_cb, &sfp_prsnt); 620 621 if (!mac_cb->phy_dev) { 622 if (ret) 623 pr_info("please confirm sfp is present or not\n"); 624 else 625 if (!sfp_prsnt) 626 pr_info("no sfp in this eth\n"); 627 } 628 629 if (mac_cb->serdes_ctrl) { 630 u32 origin; 631 632 if (!AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver)) { 633 #define HILINK_ACCESS_SEL_CFG 0x40008 634 /* hilink4 & hilink3 use the same xge training and 635 * xge u adaptor. There is a hilink access sel cfg 636 * register to select which one to be configed 637 */ 638 if ((!HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev)) && 639 (mac_cb->mac_id <= 3)) 640 dsaf_write_syscon(mac_cb->serdes_ctrl, 641 HILINK_ACCESS_SEL_CFG, 0); 642 else 643 dsaf_write_syscon(mac_cb->serdes_ctrl, 644 HILINK_ACCESS_SEL_CFG, 3); 645 } 646 647 origin = dsaf_read_syscon(mac_cb->serdes_ctrl, reg_offset); 648 649 dsaf_set_field(origin, 1ull << 10, 10, en); 650 dsaf_write_syscon(mac_cb->serdes_ctrl, reg_offset, origin); 651 } else { 652 u8 *base_addr = (u8 *)mac_cb->serdes_vaddr + 653 (mac_cb->mac_id <= 3 ? 0x00280000 : 0x00200000); 654 dsaf_set_reg_field(base_addr, reg_offset, 1ull << 10, 10, en); 655 } 656 657 return 0; 658 } 659 660 static int 661 hns_mac_config_sds_loopback_acpi(struct hns_mac_cb *mac_cb, bool en) 662 { 663 union acpi_object *obj; 664 union acpi_object obj_args[3], argv4; 665 666 obj_args[0].integer.type = ACPI_TYPE_INTEGER; 667 obj_args[0].integer.value = mac_cb->mac_id; 668 obj_args[1].integer.type = ACPI_TYPE_INTEGER; 669 obj_args[1].integer.value = !!en; 670 671 argv4.type = ACPI_TYPE_PACKAGE; 672 argv4.package.count = 2; 673 argv4.package.elements = obj_args; 674 675 obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dsaf_dev->dev), 676 &hns_dsaf_acpi_dsm_guid, 0, 677 HNS_OP_SERDES_LP_FUNC, &argv4); 678 if (!obj) { 679 dev_warn(mac_cb->dsaf_dev->dev, "set port%d serdes lp fail!", 680 mac_cb->mac_id); 681 682 return -ENOTSUPP; 683 } 684 685 ACPI_FREE(obj); 686 687 return 0; 688 } 689 690 struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device *dsaf_dev) 691 { 692 struct dsaf_misc_op *misc_op; 693 694 misc_op = devm_kzalloc(dsaf_dev->dev, sizeof(*misc_op), GFP_KERNEL); 695 if (!misc_op) 696 return NULL; 697 698 if (dev_of_node(dsaf_dev->dev)) { 699 misc_op->cpld_set_led = hns_cpld_set_led; 700 misc_op->cpld_reset_led = cpld_led_reset; 701 misc_op->cpld_set_led_id = cpld_set_led_id; 702 703 misc_op->dsaf_reset = hns_dsaf_rst; 704 misc_op->xge_srst = hns_dsaf_xge_srst_by_port; 705 misc_op->ge_srst = hns_dsaf_ge_srst_by_port; 706 misc_op->ppe_srst = hns_ppe_srst_by_port; 707 misc_op->ppe_comm_srst = hns_ppe_com_srst; 708 misc_op->hns_dsaf_srst_chns = hns_dsaf_srst_chns; 709 misc_op->hns_dsaf_roce_srst = hns_dsaf_roce_srst; 710 711 misc_op->get_phy_if = hns_mac_get_phy_if; 712 misc_op->get_sfp_prsnt = hns_mac_get_sfp_prsnt; 713 714 misc_op->cfg_serdes_loopback = hns_mac_config_sds_loopback; 715 } else if (is_acpi_node(dsaf_dev->dev->fwnode)) { 716 misc_op->cpld_set_led = hns_cpld_set_led_acpi; 717 misc_op->cpld_reset_led = cpld_led_reset_acpi; 718 misc_op->cpld_set_led_id = cpld_set_led_id_acpi; 719 720 misc_op->dsaf_reset = hns_dsaf_rst_acpi; 721 misc_op->xge_srst = hns_dsaf_xge_srst_by_port_acpi; 722 misc_op->ge_srst = hns_dsaf_ge_srst_by_port_acpi; 723 misc_op->ppe_srst = hns_ppe_srst_by_port_acpi; 724 misc_op->ppe_comm_srst = hns_ppe_com_srst; 725 misc_op->hns_dsaf_srst_chns = hns_dsaf_srst_chns_acpi; 726 misc_op->hns_dsaf_roce_srst = hns_dsaf_roce_srst_acpi; 727 728 misc_op->get_phy_if = hns_mac_get_phy_if_acpi; 729 misc_op->get_sfp_prsnt = hns_mac_get_sfp_prsnt_acpi; 730 731 misc_op->cfg_serdes_loopback = hns_mac_config_sds_loopback_acpi; 732 } else { 733 devm_kfree(dsaf_dev->dev, (void *)misc_op); 734 misc_op = NULL; 735 } 736 737 return (void *)misc_op; 738 } 739 740 static int hns_dsaf_dev_match(struct device *dev, void *fwnode) 741 { 742 return dev->fwnode == fwnode; 743 } 744 745 struct 746 platform_device *hns_dsaf_find_platform_device(struct fwnode_handle *fwnode) 747 { 748 struct device *dev; 749 750 dev = bus_find_device(&platform_bus_type, NULL, 751 fwnode, hns_dsaf_dev_match); 752 return dev ? to_platform_device(dev) : NULL; 753 } 754