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