Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (c) 2014-2015 Hisilicon Limited.
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  * hns_dsaf_srst_chns - reset dsaf channels
0331  * @dsaf_dev: dsaf device struct pointer
0332  * @msk: xbar channels mask value:
0333  * @dereset: false - request reset , true - drop reset
0334  *
0335  * bit0-5 for xge0-5
0336  * bit6-11 for ppe0-5
0337  * bit12-17 for roce0-5
0338  * bit18-19 for com/dfx
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  * hns_dsaf_srst_chns_acpi - reset dsaf channels
0355  * @dsaf_dev: dsaf device struct pointer
0356  * @msk: xbar channels mask value:
0357  * @dereset: false - request reset , true - drop reset
0358  *
0359  * bit0-5 for xge0-5
0360  * bit6-11 for ppe0-5
0361  * bit12-17 for roce0-5
0362  * bit18-19 for com/dfx
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         /* DSAF_MAX_PORT_NUM is 6, but DSAF_GE_NUM is 8.
0404            We need check to prevent array overflow */
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         /* there is difference between V1 and V2 in register.*/
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  * hns_mac_get_phy_if - get phy ifterface form serdes mode
0509  * @mac_cb: mac control block
0510  * retuen phy interface
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  * hns_mac_config_sds_loopback - set loop back for serdes
0620  * @mac_cb: mac control block
0621  * @en: enable or disable
0622  * return 0 == success
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,  /* mac 0 -> lane 0 */
0628         1,  /* mac 1 -> lane 1 */
0629         2,  /* mac 2 -> lane 2 */
0630         3,  /* mac 3 -> lane 3 */
0631         2,  /* mac 4 -> lane 2 */
0632         3,  /* mac 5 -> lane 3 */
0633         0,  /* mac 6 -> lane 0 */
0634         1   /* mac 7 -> lane 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             /* hilink4 & hilink3 use the same xge training and
0656              * xge u adaptor. There is a hilink access sel cfg
0657              * register to select which one to be configed
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 }