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