0001
0002
0003
0004
0005
0006 #include "hns_dsaf_mac.h"
0007 #include "hns_dsaf_misc.h"
0008 #include "hns_dsaf_ppe.h"
0009 #include "hns_dsaf_reg.h"
0010
0011 enum _dsm_op_index {
0012 HNS_OP_RESET_FUNC = 0x1,
0013 HNS_OP_SERDES_LP_FUNC = 0x2,
0014 HNS_OP_LED_SET_FUNC = 0x3,
0015 HNS_OP_GET_PORT_TYPE_FUNC = 0x4,
0016 HNS_OP_GET_SFP_STAT_FUNC = 0x5,
0017 HNS_OP_LOCATE_LED_SET_FUNC = 0x6,
0018 };
0019
0020 enum _dsm_rst_type {
0021 HNS_DSAF_RESET_FUNC = 0x1,
0022 HNS_PPE_RESET_FUNC = 0x2,
0023 HNS_XGE_RESET_FUNC = 0x4,
0024 HNS_GE_RESET_FUNC = 0x5,
0025 HNS_DSAF_CHN_RESET_FUNC = 0x6,
0026 HNS_ROCE_RESET_FUNC = 0x7,
0027 };
0028
0029 static const guid_t hns_dsaf_acpi_dsm_guid =
0030 GUID_INIT(0x1A85AA1A, 0xE293, 0x415E,
0031 0x8E, 0x28, 0x8D, 0x69, 0x0A, 0x0F, 0x82, 0x0A);
0032
0033 static void dsaf_write_sub(struct dsaf_device *dsaf_dev, u32 reg, u32 val)
0034 {
0035 if (dsaf_dev->sub_ctrl)
0036 dsaf_write_syscon(dsaf_dev->sub_ctrl, reg, val);
0037 else
0038 dsaf_write_reg(dsaf_dev->sc_base, reg, val);
0039 }
0040
0041 static u32 dsaf_read_sub(struct dsaf_device *dsaf_dev, u32 reg)
0042 {
0043 u32 ret = 0;
0044 int err;
0045
0046 if (dsaf_dev->sub_ctrl) {
0047 err = dsaf_read_syscon(dsaf_dev->sub_ctrl, reg, &ret);
0048 if (err)
0049 dev_err(dsaf_dev->dev, "dsaf_read_syscon error %d!\n",
0050 err);
0051 } else {
0052 ret = dsaf_read_reg(dsaf_dev->sc_base, reg);
0053 }
0054
0055 return ret;
0056 }
0057
0058 static void hns_dsaf_acpi_ledctrl_by_port(struct hns_mac_cb *mac_cb, u8 op_type,
0059 u32 link, u32 port, u32 act)
0060 {
0061 union acpi_object *obj;
0062 union acpi_object obj_args[3], argv4;
0063
0064 obj_args[0].integer.type = ACPI_TYPE_INTEGER;
0065 obj_args[0].integer.value = link;
0066 obj_args[1].integer.type = ACPI_TYPE_INTEGER;
0067 obj_args[1].integer.value = port;
0068 obj_args[2].integer.type = ACPI_TYPE_INTEGER;
0069 obj_args[2].integer.value = act;
0070
0071 argv4.type = ACPI_TYPE_PACKAGE;
0072 argv4.package.count = 3;
0073 argv4.package.elements = obj_args;
0074
0075 obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev),
0076 &hns_dsaf_acpi_dsm_guid, 0, op_type, &argv4);
0077 if (!obj) {
0078 dev_warn(mac_cb->dev, "ledctrl fail, link:%d port:%d act:%d!\n",
0079 link, port, act);
0080 return;
0081 }
0082
0083 ACPI_FREE(obj);
0084 }
0085
0086 static void hns_dsaf_acpi_locate_ledctrl_by_port(struct hns_mac_cb *mac_cb,
0087 u8 op_type, u32 locate,
0088 u32 port)
0089 {
0090 union acpi_object obj_args[2], argv4;
0091 union acpi_object *obj;
0092
0093 obj_args[0].integer.type = ACPI_TYPE_INTEGER;
0094 obj_args[0].integer.value = locate;
0095 obj_args[1].integer.type = ACPI_TYPE_INTEGER;
0096 obj_args[1].integer.value = port;
0097
0098 argv4.type = ACPI_TYPE_PACKAGE;
0099 argv4.package.count = 2;
0100 argv4.package.elements = obj_args;
0101
0102 obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev),
0103 &hns_dsaf_acpi_dsm_guid, 0, op_type, &argv4);
0104 if (!obj) {
0105 dev_err(mac_cb->dev, "ledctrl fail, locate:%d port:%d!\n",
0106 locate, port);
0107 return;
0108 }
0109
0110 ACPI_FREE(obj);
0111 }
0112
0113 static void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status,
0114 u16 speed, int data)
0115 {
0116 int speed_reg = 0;
0117 u8 value;
0118
0119 if (!mac_cb) {
0120 pr_err("sfp_led_opt mac_dev is null!\n");
0121 return;
0122 }
0123 if (!mac_cb->cpld_ctrl) {
0124 dev_err(mac_cb->dev, "mac_id=%d, cpld syscon is null !\n",
0125 mac_cb->mac_id);
0126 return;
0127 }
0128
0129 if (speed == MAC_SPEED_10000)
0130 speed_reg = 1;
0131
0132 value = mac_cb->cpld_led_value;
0133
0134 if (link_status) {
0135 dsaf_set_bit(value, DSAF_LED_LINK_B, link_status);
0136 dsaf_set_field(value, DSAF_LED_SPEED_M,
0137 DSAF_LED_SPEED_S, speed_reg);
0138 dsaf_set_bit(value, DSAF_LED_DATA_B, data);
0139
0140 if (value != mac_cb->cpld_led_value) {
0141 dsaf_write_syscon(mac_cb->cpld_ctrl,
0142 mac_cb->cpld_ctrl_reg, value);
0143 mac_cb->cpld_led_value = value;
0144 }
0145 } else {
0146 value = (mac_cb->cpld_led_value) & (0x1 << DSAF_LED_ANCHOR_B);
0147 dsaf_write_syscon(mac_cb->cpld_ctrl,
0148 mac_cb->cpld_ctrl_reg, value);
0149 mac_cb->cpld_led_value = value;
0150 }
0151 }
0152
0153 static void hns_cpld_set_led_acpi(struct hns_mac_cb *mac_cb, int link_status,
0154 u16 speed, int data)
0155 {
0156 if (!mac_cb) {
0157 pr_err("cpld_led_set mac_cb is null!\n");
0158 return;
0159 }
0160
0161 hns_dsaf_acpi_ledctrl_by_port(mac_cb, HNS_OP_LED_SET_FUNC,
0162 link_status, mac_cb->mac_id, data);
0163 }
0164
0165 static void cpld_led_reset(struct hns_mac_cb *mac_cb)
0166 {
0167 if (!mac_cb || !mac_cb->cpld_ctrl)
0168 return;
0169
0170 dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg,
0171 CPLD_LED_DEFAULT_VALUE);
0172 mac_cb->cpld_led_value = CPLD_LED_DEFAULT_VALUE;
0173 }
0174
0175 static void cpld_led_reset_acpi(struct hns_mac_cb *mac_cb)
0176 {
0177 if (!mac_cb) {
0178 pr_err("cpld_led_reset mac_cb is null!\n");
0179 return;
0180 }
0181
0182 if (mac_cb->media_type != HNAE_MEDIA_TYPE_FIBER)
0183 return;
0184
0185 hns_dsaf_acpi_ledctrl_by_port(mac_cb, HNS_OP_LED_SET_FUNC,
0186 0, mac_cb->mac_id, 0);
0187 }
0188
0189 static int cpld_set_led_id(struct hns_mac_cb *mac_cb,
0190 enum hnae_led_state status)
0191 {
0192 u32 val = 0;
0193 int ret;
0194
0195 if (!mac_cb->cpld_ctrl)
0196 return 0;
0197
0198 switch (status) {
0199 case HNAE_LED_ACTIVE:
0200 ret = dsaf_read_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg,
0201 &val);
0202 if (ret)
0203 return ret;
0204
0205 dsaf_set_bit(val, DSAF_LED_ANCHOR_B, CPLD_LED_ON_VALUE);
0206 dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg,
0207 val);
0208 mac_cb->cpld_led_value = val;
0209 break;
0210 case HNAE_LED_INACTIVE:
0211 dsaf_set_bit(mac_cb->cpld_led_value, DSAF_LED_ANCHOR_B,
0212 CPLD_LED_DEFAULT_VALUE);
0213 dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg,
0214 mac_cb->cpld_led_value);
0215 break;
0216 default:
0217 dev_err(mac_cb->dev, "invalid led state: %d!", status);
0218 return -EINVAL;
0219 }
0220
0221 return 0;
0222 }
0223
0224 static int cpld_set_led_id_acpi(struct hns_mac_cb *mac_cb,
0225 enum hnae_led_state status)
0226 {
0227 switch (status) {
0228 case HNAE_LED_ACTIVE:
0229 hns_dsaf_acpi_locate_ledctrl_by_port(mac_cb,
0230 HNS_OP_LOCATE_LED_SET_FUNC,
0231 CPLD_LED_ON_VALUE,
0232 mac_cb->mac_id);
0233 break;
0234 case HNAE_LED_INACTIVE:
0235 hns_dsaf_acpi_locate_ledctrl_by_port(mac_cb,
0236 HNS_OP_LOCATE_LED_SET_FUNC,
0237 CPLD_LED_DEFAULT_VALUE,
0238 mac_cb->mac_id);
0239 break;
0240 default:
0241 dev_err(mac_cb->dev, "invalid led state: %d!", status);
0242 return -EINVAL;
0243 }
0244
0245 return 0;
0246 }
0247
0248 #define RESET_REQ_OR_DREQ 1
0249
0250 static void hns_dsaf_acpi_srst_by_port(struct dsaf_device *dsaf_dev, u8 op_type,
0251 u32 port_type, u32 port, u32 val)
0252 {
0253 union acpi_object *obj;
0254 union acpi_object obj_args[3], argv4;
0255
0256 obj_args[0].integer.type = ACPI_TYPE_INTEGER;
0257 obj_args[0].integer.value = port_type;
0258 obj_args[1].integer.type = ACPI_TYPE_INTEGER;
0259 obj_args[1].integer.value = port;
0260 obj_args[2].integer.type = ACPI_TYPE_INTEGER;
0261 obj_args[2].integer.value = val;
0262
0263 argv4.type = ACPI_TYPE_PACKAGE;
0264 argv4.package.count = 3;
0265 argv4.package.elements = obj_args;
0266
0267 obj = acpi_evaluate_dsm(ACPI_HANDLE(dsaf_dev->dev),
0268 &hns_dsaf_acpi_dsm_guid, 0, op_type, &argv4);
0269 if (!obj) {
0270 dev_warn(dsaf_dev->dev, "reset port_type%d port%d fail!",
0271 port_type, port);
0272 return;
0273 }
0274
0275 ACPI_FREE(obj);
0276 }
0277
0278 static void hns_dsaf_rst(struct dsaf_device *dsaf_dev, bool dereset)
0279 {
0280 u32 xbar_reg_addr;
0281 u32 nt_reg_addr;
0282
0283 if (!dereset) {
0284 xbar_reg_addr = DSAF_SUB_SC_XBAR_RESET_REQ_REG;
0285 nt_reg_addr = DSAF_SUB_SC_NT_RESET_REQ_REG;
0286 } else {
0287 xbar_reg_addr = DSAF_SUB_SC_XBAR_RESET_DREQ_REG;
0288 nt_reg_addr = DSAF_SUB_SC_NT_RESET_DREQ_REG;
0289 }
0290
0291 dsaf_write_sub(dsaf_dev, xbar_reg_addr, RESET_REQ_OR_DREQ);
0292 dsaf_write_sub(dsaf_dev, nt_reg_addr, RESET_REQ_OR_DREQ);
0293 }
0294
0295 static void hns_dsaf_rst_acpi(struct dsaf_device *dsaf_dev, bool dereset)
0296 {
0297 hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
0298 HNS_DSAF_RESET_FUNC,
0299 0, dereset);
0300 }
0301
0302 static void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
0303 bool dereset)
0304 {
0305 u32 reg_val = 0;
0306 u32 reg_addr;
0307
0308 if (port >= DSAF_XGE_NUM)
0309 return;
0310
0311 reg_val |= RESET_REQ_OR_DREQ;
0312 reg_val |= 0x2082082 << dsaf_dev->mac_cb[port]->port_rst_off;
0313
0314 if (!dereset)
0315 reg_addr = DSAF_SUB_SC_XGE_RESET_REQ_REG;
0316 else
0317 reg_addr = DSAF_SUB_SC_XGE_RESET_DREQ_REG;
0318
0319 dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
0320 }
0321
0322 static void hns_dsaf_xge_srst_by_port_acpi(struct dsaf_device *dsaf_dev,
0323 u32 port, bool dereset)
0324 {
0325 hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
0326 HNS_XGE_RESET_FUNC, port, dereset);
0327 }
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340 static void
0341 hns_dsaf_srst_chns(struct dsaf_device *dsaf_dev, u32 msk, bool dereset)
0342 {
0343 u32 reg_addr;
0344
0345 if (!dereset)
0346 reg_addr = DSAF_SUB_SC_DSAF_RESET_REQ_REG;
0347 else
0348 reg_addr = DSAF_SUB_SC_DSAF_RESET_DREQ_REG;
0349
0350 dsaf_write_sub(dsaf_dev, reg_addr, msk);
0351 }
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364 static void
0365 hns_dsaf_srst_chns_acpi(struct dsaf_device *dsaf_dev, u32 msk, bool dereset)
0366 {
0367 hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
0368 HNS_DSAF_CHN_RESET_FUNC,
0369 msk, dereset);
0370 }
0371
0372 static void hns_dsaf_roce_srst(struct dsaf_device *dsaf_dev, bool dereset)
0373 {
0374 if (!dereset) {
0375 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_ROCEE_RESET_REQ_REG, 1);
0376 } else {
0377 dsaf_write_sub(dsaf_dev,
0378 DSAF_SUB_SC_ROCEE_CLK_DIS_REG, 1);
0379 dsaf_write_sub(dsaf_dev,
0380 DSAF_SUB_SC_ROCEE_RESET_DREQ_REG, 1);
0381 msleep(20);
0382 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_ROCEE_CLK_EN_REG, 1);
0383 }
0384 }
0385
0386 static void hns_dsaf_roce_srst_acpi(struct dsaf_device *dsaf_dev, bool dereset)
0387 {
0388 hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
0389 HNS_ROCE_RESET_FUNC, 0, dereset);
0390 }
0391
0392 static void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
0393 bool dereset)
0394 {
0395 u32 reg_val_1;
0396 u32 reg_val_2;
0397 u32 port_rst_off;
0398
0399 if (port >= DSAF_GE_NUM)
0400 return;
0401
0402 if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) {
0403
0404
0405 if (port >= DSAF_MAX_PORT_NUM)
0406 return;
0407 reg_val_1 = 0x1 << port;
0408 port_rst_off = dsaf_dev->mac_cb[port]->port_rst_off;
0409
0410 reg_val_2 = AE_IS_VER1(dsaf_dev->dsaf_ver) ?
0411 0x1041041 : 0x2082082;
0412 reg_val_2 <<= port_rst_off;
0413
0414 if (!dereset) {
0415 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG,
0416 reg_val_1);
0417
0418 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ0_REG,
0419 reg_val_2);
0420 } else {
0421 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ0_REG,
0422 reg_val_2);
0423
0424 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ1_REG,
0425 reg_val_1);
0426 }
0427 } else {
0428 reg_val_1 = 0x15540;
0429 reg_val_2 = AE_IS_VER1(dsaf_dev->dsaf_ver) ? 0x100 : 0x40;
0430
0431 reg_val_1 <<= dsaf_dev->reset_offset;
0432 reg_val_2 <<= dsaf_dev->reset_offset;
0433
0434 if (!dereset) {
0435 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG,
0436 reg_val_1);
0437
0438 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_PPE_RESET_REQ_REG,
0439 reg_val_2);
0440 } else {
0441 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ1_REG,
0442 reg_val_1);
0443
0444 dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_PPE_RESET_DREQ_REG,
0445 reg_val_2);
0446 }
0447 }
0448 }
0449
0450 static void hns_dsaf_ge_srst_by_port_acpi(struct dsaf_device *dsaf_dev,
0451 u32 port, bool dereset)
0452 {
0453 hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
0454 HNS_GE_RESET_FUNC, port, dereset);
0455 }
0456
0457 static void hns_ppe_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
0458 bool dereset)
0459 {
0460 u32 reg_val = 0;
0461 u32 reg_addr;
0462
0463 reg_val |= RESET_REQ_OR_DREQ << dsaf_dev->mac_cb[port]->port_rst_off;
0464
0465 if (!dereset)
0466 reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG;
0467 else
0468 reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG;
0469
0470 dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
0471 }
0472
0473 static void
0474 hns_ppe_srst_by_port_acpi(struct dsaf_device *dsaf_dev, u32 port, bool dereset)
0475 {
0476 hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
0477 HNS_PPE_RESET_FUNC, port, dereset);
0478 }
0479
0480 static void hns_ppe_com_srst(struct dsaf_device *dsaf_dev, bool dereset)
0481 {
0482 u32 reg_val;
0483 u32 reg_addr;
0484
0485 if (!(dev_of_node(dsaf_dev->dev)))
0486 return;
0487
0488 if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) {
0489 reg_val = RESET_REQ_OR_DREQ;
0490 if (!dereset)
0491 reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_REQ_REG;
0492 else
0493 reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_DREQ_REG;
0494
0495 } else {
0496 reg_val = 0x100 << dsaf_dev->reset_offset;
0497
0498 if (!dereset)
0499 reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG;
0500 else
0501 reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG;
0502 }
0503
0504 dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
0505 }
0506
0507
0508
0509
0510
0511
0512 static phy_interface_t hns_mac_get_phy_if(struct hns_mac_cb *mac_cb)
0513 {
0514 u32 mode;
0515 u32 reg;
0516 bool is_ver1 = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver);
0517 int mac_id = mac_cb->mac_id;
0518 phy_interface_t phy_if;
0519
0520 if (is_ver1) {
0521 if (HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev))
0522 return PHY_INTERFACE_MODE_SGMII;
0523
0524 if (mac_id >= 0 && mac_id <= 3)
0525 reg = HNS_MAC_HILINK4_REG;
0526 else
0527 reg = HNS_MAC_HILINK3_REG;
0528 } else {
0529 if (!HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev) && mac_id <= 3)
0530 reg = HNS_MAC_HILINK4V2_REG;
0531 else
0532 reg = HNS_MAC_HILINK3V2_REG;
0533 }
0534
0535 mode = dsaf_read_sub(mac_cb->dsaf_dev, reg);
0536 if (dsaf_get_bit(mode, mac_cb->port_mode_off))
0537 phy_if = PHY_INTERFACE_MODE_XGMII;
0538 else
0539 phy_if = PHY_INTERFACE_MODE_SGMII;
0540
0541 return phy_if;
0542 }
0543
0544 static phy_interface_t hns_mac_get_phy_if_acpi(struct hns_mac_cb *mac_cb)
0545 {
0546 phy_interface_t phy_if = PHY_INTERFACE_MODE_NA;
0547 union acpi_object *obj;
0548 union acpi_object obj_args, argv4;
0549
0550 obj_args.integer.type = ACPI_TYPE_INTEGER;
0551 obj_args.integer.value = mac_cb->mac_id;
0552
0553 argv4.type = ACPI_TYPE_PACKAGE;
0554 argv4.package.count = 1;
0555 argv4.package.elements = &obj_args;
0556
0557 obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev),
0558 &hns_dsaf_acpi_dsm_guid, 0,
0559 HNS_OP_GET_PORT_TYPE_FUNC, &argv4);
0560
0561 if (!obj || obj->type != ACPI_TYPE_INTEGER)
0562 return phy_if;
0563
0564 phy_if = obj->integer.value ?
0565 PHY_INTERFACE_MODE_XGMII : PHY_INTERFACE_MODE_SGMII;
0566
0567 dev_dbg(mac_cb->dev, "mac_id=%d, phy_if=%d\n", mac_cb->mac_id, phy_if);
0568
0569 ACPI_FREE(obj);
0570
0571 return phy_if;
0572 }
0573
0574 static int hns_mac_get_sfp_prsnt(struct hns_mac_cb *mac_cb, int *sfp_prsnt)
0575 {
0576 u32 val = 0;
0577 int ret;
0578
0579 if (!mac_cb->cpld_ctrl)
0580 return -ENODEV;
0581
0582 ret = dsaf_read_syscon(mac_cb->cpld_ctrl,
0583 mac_cb->cpld_ctrl_reg + MAC_SFP_PORT_OFFSET,
0584 &val);
0585 if (ret)
0586 return ret;
0587
0588 *sfp_prsnt = !val;
0589 return 0;
0590 }
0591
0592 static int hns_mac_get_sfp_prsnt_acpi(struct hns_mac_cb *mac_cb, int *sfp_prsnt)
0593 {
0594 union acpi_object *obj;
0595 union acpi_object obj_args, argv4;
0596
0597 obj_args.integer.type = ACPI_TYPE_INTEGER;
0598 obj_args.integer.value = mac_cb->mac_id;
0599
0600 argv4.type = ACPI_TYPE_PACKAGE;
0601 argv4.package.count = 1;
0602 argv4.package.elements = &obj_args;
0603
0604 obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev),
0605 &hns_dsaf_acpi_dsm_guid, 0,
0606 HNS_OP_GET_SFP_STAT_FUNC, &argv4);
0607
0608 if (!obj || obj->type != ACPI_TYPE_INTEGER)
0609 return -ENODEV;
0610
0611 *sfp_prsnt = obj->integer.value;
0612
0613 ACPI_FREE(obj);
0614
0615 return 0;
0616 }
0617
0618
0619
0620
0621
0622
0623
0624 static int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, bool en)
0625 {
0626 const u8 lane_id[] = {
0627 0,
0628 1,
0629 2,
0630 3,
0631 2,
0632 3,
0633 0,
0634 1
0635 };
0636 #define RX_CSR(lane, reg) ((0x4080 + (reg) * 0x0002 + (lane) * 0x0200) * 2)
0637 u64 reg_offset = RX_CSR(lane_id[mac_cb->mac_id], 0);
0638
0639 int sfp_prsnt = 0;
0640 int ret = hns_mac_get_sfp_prsnt(mac_cb, &sfp_prsnt);
0641
0642 if (!mac_cb->phy_dev) {
0643 if (ret)
0644 pr_info("please confirm sfp is present or not\n");
0645 else
0646 if (!sfp_prsnt)
0647 pr_info("no sfp in this eth\n");
0648 }
0649
0650 if (mac_cb->serdes_ctrl) {
0651 u32 origin = 0;
0652
0653 if (!AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver)) {
0654 #define HILINK_ACCESS_SEL_CFG 0x40008
0655
0656
0657
0658
0659 if ((!HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev)) &&
0660 (mac_cb->mac_id <= 3))
0661 dsaf_write_syscon(mac_cb->serdes_ctrl,
0662 HILINK_ACCESS_SEL_CFG, 0);
0663 else
0664 dsaf_write_syscon(mac_cb->serdes_ctrl,
0665 HILINK_ACCESS_SEL_CFG, 3);
0666 }
0667
0668 ret = dsaf_read_syscon(mac_cb->serdes_ctrl, reg_offset,
0669 &origin);
0670 if (ret)
0671 return ret;
0672
0673 dsaf_set_field(origin, 1ull << 10, 10, en);
0674 dsaf_write_syscon(mac_cb->serdes_ctrl, reg_offset, origin);
0675 } else {
0676 u8 __iomem *base_addr = mac_cb->serdes_vaddr +
0677 (mac_cb->mac_id <= 3 ? 0x00280000 : 0x00200000);
0678 dsaf_set_reg_field(base_addr, reg_offset, 1ull << 10, 10, en);
0679 }
0680
0681 return 0;
0682 }
0683
0684 static int
0685 hns_mac_config_sds_loopback_acpi(struct hns_mac_cb *mac_cb, bool en)
0686 {
0687 union acpi_object *obj;
0688 union acpi_object obj_args[3], argv4;
0689
0690 obj_args[0].integer.type = ACPI_TYPE_INTEGER;
0691 obj_args[0].integer.value = mac_cb->mac_id;
0692 obj_args[1].integer.type = ACPI_TYPE_INTEGER;
0693 obj_args[1].integer.value = en;
0694
0695 argv4.type = ACPI_TYPE_PACKAGE;
0696 argv4.package.count = 2;
0697 argv4.package.elements = obj_args;
0698
0699 obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dsaf_dev->dev),
0700 &hns_dsaf_acpi_dsm_guid, 0,
0701 HNS_OP_SERDES_LP_FUNC, &argv4);
0702 if (!obj) {
0703 dev_warn(mac_cb->dsaf_dev->dev, "set port%d serdes lp fail!",
0704 mac_cb->mac_id);
0705
0706 return -ENOTSUPP;
0707 }
0708
0709 ACPI_FREE(obj);
0710
0711 return 0;
0712 }
0713
0714 struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device *dsaf_dev)
0715 {
0716 struct dsaf_misc_op *misc_op;
0717
0718 misc_op = devm_kzalloc(dsaf_dev->dev, sizeof(*misc_op), GFP_KERNEL);
0719 if (!misc_op)
0720 return NULL;
0721
0722 if (dev_of_node(dsaf_dev->dev)) {
0723 misc_op->cpld_set_led = hns_cpld_set_led;
0724 misc_op->cpld_reset_led = cpld_led_reset;
0725 misc_op->cpld_set_led_id = cpld_set_led_id;
0726
0727 misc_op->dsaf_reset = hns_dsaf_rst;
0728 misc_op->xge_srst = hns_dsaf_xge_srst_by_port;
0729 misc_op->ge_srst = hns_dsaf_ge_srst_by_port;
0730 misc_op->ppe_srst = hns_ppe_srst_by_port;
0731 misc_op->ppe_comm_srst = hns_ppe_com_srst;
0732 misc_op->hns_dsaf_srst_chns = hns_dsaf_srst_chns;
0733 misc_op->hns_dsaf_roce_srst = hns_dsaf_roce_srst;
0734
0735 misc_op->get_phy_if = hns_mac_get_phy_if;
0736 misc_op->get_sfp_prsnt = hns_mac_get_sfp_prsnt;
0737
0738 misc_op->cfg_serdes_loopback = hns_mac_config_sds_loopback;
0739 } else if (is_acpi_node(dsaf_dev->dev->fwnode)) {
0740 misc_op->cpld_set_led = hns_cpld_set_led_acpi;
0741 misc_op->cpld_reset_led = cpld_led_reset_acpi;
0742 misc_op->cpld_set_led_id = cpld_set_led_id_acpi;
0743
0744 misc_op->dsaf_reset = hns_dsaf_rst_acpi;
0745 misc_op->xge_srst = hns_dsaf_xge_srst_by_port_acpi;
0746 misc_op->ge_srst = hns_dsaf_ge_srst_by_port_acpi;
0747 misc_op->ppe_srst = hns_ppe_srst_by_port_acpi;
0748 misc_op->ppe_comm_srst = hns_ppe_com_srst;
0749 misc_op->hns_dsaf_srst_chns = hns_dsaf_srst_chns_acpi;
0750 misc_op->hns_dsaf_roce_srst = hns_dsaf_roce_srst_acpi;
0751
0752 misc_op->get_phy_if = hns_mac_get_phy_if_acpi;
0753 misc_op->get_sfp_prsnt = hns_mac_get_sfp_prsnt_acpi;
0754
0755 misc_op->cfg_serdes_loopback = hns_mac_config_sds_loopback_acpi;
0756 } else {
0757 devm_kfree(dsaf_dev->dev, (void *)misc_op);
0758 misc_op = NULL;
0759 }
0760
0761 return (void *)misc_op;
0762 }
0763
0764 struct
0765 platform_device *hns_dsaf_find_platform_device(struct fwnode_handle *fwnode)
0766 {
0767 struct device *dev;
0768
0769 dev = bus_find_device_by_fwnode(&platform_bus_type, fwnode);
0770 return dev ? to_platform_device(dev) : NULL;
0771 }