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