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 * bit0-5 for xge0-5
 334 * bit6-11 for ppe0-5
 335 * bit12-17 for roce0-5
 336 * bit18-19 for com/dfx
 337 * @dereset: false - request reset , true - drop reset
 338 */
 339static void
 340hns_dsaf_srst_chns(struct dsaf_device *dsaf_dev, u32 msk, bool dereset)
 341{
 342        u32 reg_addr;
 343
 344        if (!dereset)
 345                reg_addr = DSAF_SUB_SC_DSAF_RESET_REQ_REG;
 346        else
 347                reg_addr = DSAF_SUB_SC_DSAF_RESET_DREQ_REG;
 348
 349        dsaf_write_sub(dsaf_dev, reg_addr, msk);
 350}
 351
 352/**
 353 * hns_dsaf_srst_chns - reset dsaf channels
 354 * @dsaf_dev: dsaf device struct pointer
 355 * @msk: xbar channels mask value:
 356 * bit0-5 for xge0-5
 357 * bit6-11 for ppe0-5
 358 * bit12-17 for roce0-5
 359 * bit18-19 for com/dfx
 360 * @dereset: false - request reset , true - drop reset
 361 */
 362static void
 363hns_dsaf_srst_chns_acpi(struct dsaf_device *dsaf_dev, u32 msk, bool dereset)
 364{
 365        hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
 366                                   HNS_DSAF_CHN_RESET_FUNC,
 367                                   msk, dereset);
 368}
 369
 370static void hns_dsaf_roce_srst(struct dsaf_device *dsaf_dev, bool dereset)
 371{
 372        if (!dereset) {
 373                dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_ROCEE_RESET_REQ_REG, 1);
 374        } else {
 375                dsaf_write_sub(dsaf_dev,
 376                               DSAF_SUB_SC_ROCEE_CLK_DIS_REG, 1);
 377                dsaf_write_sub(dsaf_dev,
 378                               DSAF_SUB_SC_ROCEE_RESET_DREQ_REG, 1);
 379                msleep(20);
 380                dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_ROCEE_CLK_EN_REG, 1);
 381        }
 382}
 383
 384static void hns_dsaf_roce_srst_acpi(struct dsaf_device *dsaf_dev, bool dereset)
 385{
 386        hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
 387                                   HNS_ROCE_RESET_FUNC, 0, dereset);
 388}
 389
 390static void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
 391                                     bool dereset)
 392{
 393        u32 reg_val_1;
 394        u32 reg_val_2;
 395        u32 port_rst_off;
 396
 397        if (port >= DSAF_GE_NUM)
 398                return;
 399
 400        if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) {
 401                reg_val_1  = 0x1 << port;
 402                port_rst_off = dsaf_dev->mac_cb[port]->port_rst_off;
 403                /* there is difference between V1 and V2 in register.*/
 404                reg_val_2 = AE_IS_VER1(dsaf_dev->dsaf_ver) ?
 405                                0x1041041 : 0x2082082;
 406                reg_val_2 <<= port_rst_off;
 407
 408                if (!dereset) {
 409                        dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG,
 410                                       reg_val_1);
 411
 412                        dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ0_REG,
 413                                       reg_val_2);
 414                } else {
 415                        dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ0_REG,
 416                                       reg_val_2);
 417
 418                        dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ1_REG,
 419                                       reg_val_1);
 420                }
 421        } else {
 422                reg_val_1 = 0x15540;
 423                reg_val_2 = AE_IS_VER1(dsaf_dev->dsaf_ver) ? 0x100 : 0x40;
 424
 425                reg_val_1 <<= dsaf_dev->reset_offset;
 426                reg_val_2 <<= dsaf_dev->reset_offset;
 427
 428                if (!dereset) {
 429                        dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG,
 430                                       reg_val_1);
 431
 432                        dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_PPE_RESET_REQ_REG,
 433                                       reg_val_2);
 434                } else {
 435                        dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_DREQ1_REG,
 436                                       reg_val_1);
 437
 438                        dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_PPE_RESET_DREQ_REG,
 439                                       reg_val_2);
 440                }
 441        }
 442}
 443
 444static void hns_dsaf_ge_srst_by_port_acpi(struct dsaf_device *dsaf_dev,
 445                                          u32 port, bool dereset)
 446{
 447        hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
 448                                   HNS_GE_RESET_FUNC, port, dereset);
 449}
 450
 451static void hns_ppe_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
 452                                 bool dereset)
 453{
 454        u32 reg_val = 0;
 455        u32 reg_addr;
 456
 457        reg_val |= RESET_REQ_OR_DREQ << dsaf_dev->mac_cb[port]->port_rst_off;
 458
 459        if (!dereset)
 460                reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG;
 461        else
 462                reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG;
 463
 464        dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
 465}
 466
 467static void
 468hns_ppe_srst_by_port_acpi(struct dsaf_device *dsaf_dev, u32 port, bool dereset)
 469{
 470        hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
 471                                   HNS_PPE_RESET_FUNC, port, dereset);
 472}
 473
 474static void hns_ppe_com_srst(struct dsaf_device *dsaf_dev, bool dereset)
 475{
 476        u32 reg_val;
 477        u32 reg_addr;
 478
 479        if (!(dev_of_node(dsaf_dev->dev)))
 480                return;
 481
 482        if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) {
 483                reg_val = RESET_REQ_OR_DREQ;
 484                if (!dereset)
 485                        reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_REQ_REG;
 486                else
 487                        reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_DREQ_REG;
 488
 489        } else {
 490                reg_val = 0x100 << dsaf_dev->reset_offset;
 491
 492                if (!dereset)
 493                        reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG;
 494                else
 495                        reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG;
 496        }
 497
 498        dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
 499}
 500
 501/**
 502 * hns_mac_get_sds_mode - get phy ifterface form serdes mode
 503 * @mac_cb: mac control block
 504 * retuen phy interface
 505 */
 506static phy_interface_t hns_mac_get_phy_if(struct hns_mac_cb *mac_cb)
 507{
 508        u32 mode;
 509        u32 reg;
 510        bool is_ver1 = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver);
 511        int mac_id = mac_cb->mac_id;
 512        phy_interface_t phy_if;
 513
 514        if (is_ver1) {
 515                if (HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev))
 516                        return PHY_INTERFACE_MODE_SGMII;
 517
 518                if (mac_id >= 0 && mac_id <= 3)
 519                        reg = HNS_MAC_HILINK4_REG;
 520                else
 521                        reg = HNS_MAC_HILINK3_REG;
 522        } else{
 523                if (!HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev) && mac_id <= 3)
 524                        reg = HNS_MAC_HILINK4V2_REG;
 525                else
 526                        reg = HNS_MAC_HILINK3V2_REG;
 527        }
 528
 529        mode = dsaf_read_sub(mac_cb->dsaf_dev, reg);
 530        if (dsaf_get_bit(mode, mac_cb->port_mode_off))
 531                phy_if = PHY_INTERFACE_MODE_XGMII;
 532        else
 533                phy_if = PHY_INTERFACE_MODE_SGMII;
 534
 535        return phy_if;
 536}
 537
 538static phy_interface_t hns_mac_get_phy_if_acpi(struct hns_mac_cb *mac_cb)
 539{
 540        phy_interface_t phy_if = PHY_INTERFACE_MODE_NA;
 541        union acpi_object *obj;
 542        union acpi_object obj_args, argv4;
 543
 544        obj_args.integer.type = ACPI_TYPE_INTEGER;
 545        obj_args.integer.value = mac_cb->mac_id;
 546
 547        argv4.type = ACPI_TYPE_PACKAGE,
 548        argv4.package.count = 1,
 549        argv4.package.elements = &obj_args,
 550
 551        obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev),
 552                                &hns_dsaf_acpi_dsm_guid, 0,
 553                                HNS_OP_GET_PORT_TYPE_FUNC, &argv4);
 554
 555        if (!obj || obj->type != ACPI_TYPE_INTEGER)
 556                return phy_if;
 557
 558        phy_if = obj->integer.value ?
 559                PHY_INTERFACE_MODE_XGMII : PHY_INTERFACE_MODE_SGMII;
 560
 561        dev_dbg(mac_cb->dev, "mac_id=%d, phy_if=%d\n", mac_cb->mac_id, phy_if);
 562
 563        ACPI_FREE(obj);
 564
 565        return phy_if;
 566}
 567
 568static int hns_mac_get_sfp_prsnt(struct hns_mac_cb *mac_cb, int *sfp_prsnt)
 569{
 570        u32 val = 0;
 571        int ret;
 572
 573        if (!mac_cb->cpld_ctrl)
 574                return -ENODEV;
 575
 576        ret = dsaf_read_syscon(mac_cb->cpld_ctrl,
 577                               mac_cb->cpld_ctrl_reg + MAC_SFP_PORT_OFFSET,
 578                               &val);
 579        if (ret)
 580                return ret;
 581
 582        *sfp_prsnt = !val;
 583        return 0;
 584}
 585
 586static int hns_mac_get_sfp_prsnt_acpi(struct hns_mac_cb *mac_cb, int *sfp_prsnt)
 587{
 588        union acpi_object *obj;
 589        union acpi_object obj_args, argv4;
 590
 591        obj_args.integer.type = ACPI_TYPE_INTEGER;
 592        obj_args.integer.value = mac_cb->mac_id;
 593
 594        argv4.type = ACPI_TYPE_PACKAGE,
 595        argv4.package.count = 1,
 596        argv4.package.elements = &obj_args,
 597
 598        obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev),
 599                                &hns_dsaf_acpi_dsm_guid, 0,
 600                                HNS_OP_GET_SFP_STAT_FUNC, &argv4);
 601
 602        if (!obj || obj->type != ACPI_TYPE_INTEGER)
 603                return -ENODEV;
 604
 605        *sfp_prsnt = obj->integer.value;
 606
 607        ACPI_FREE(obj);
 608
 609        return 0;
 610}
 611
 612/**
 613 * hns_mac_config_sds_loopback - set loop back for serdes
 614 * @mac_cb: mac control block
 615 * retuen 0 == success
 616 */
 617static int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, bool en)
 618{
 619        const u8 lane_id[] = {
 620                0,      /* mac 0 -> lane 0 */
 621                1,      /* mac 1 -> lane 1 */
 622                2,      /* mac 2 -> lane 2 */
 623                3,      /* mac 3 -> lane 3 */
 624                2,      /* mac 4 -> lane 2 */
 625                3,      /* mac 5 -> lane 3 */
 626                0,      /* mac 6 -> lane 0 */
 627                1       /* mac 7 -> lane 1 */
 628        };
 629#define RX_CSR(lane, reg) ((0x4080 + (reg) * 0x0002 + (lane) * 0x0200) * 2)
 630        u64 reg_offset = RX_CSR(lane_id[mac_cb->mac_id], 0);
 631
 632        int sfp_prsnt = 0;
 633        int ret = hns_mac_get_sfp_prsnt(mac_cb, &sfp_prsnt);
 634
 635        if (!mac_cb->phy_dev) {
 636                if (ret)
 637                        pr_info("please confirm sfp is present or not\n");
 638                else
 639                        if (!sfp_prsnt)
 640                                pr_info("no sfp in this eth\n");
 641        }
 642
 643        if (mac_cb->serdes_ctrl) {
 644                u32 origin = 0;
 645
 646                if (!AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver)) {
 647#define HILINK_ACCESS_SEL_CFG           0x40008
 648                        /* hilink4 & hilink3 use the same xge training and
 649                         * xge u adaptor. There is a hilink access sel cfg
 650                         * register to select which one to be configed
 651                         */
 652                        if ((!HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev)) &&
 653                            (mac_cb->mac_id <= 3))
 654                                dsaf_write_syscon(mac_cb->serdes_ctrl,
 655                                                  HILINK_ACCESS_SEL_CFG, 0);
 656                        else
 657                                dsaf_write_syscon(mac_cb->serdes_ctrl,
 658                                                  HILINK_ACCESS_SEL_CFG, 3);
 659                }
 660
 661                ret = dsaf_read_syscon(mac_cb->serdes_ctrl, reg_offset,
 662                                       &origin);
 663                if (ret)
 664                        return ret;
 665
 666                dsaf_set_field(origin, 1ull << 10, 10, en);
 667                dsaf_write_syscon(mac_cb->serdes_ctrl, reg_offset, origin);
 668        } else {
 669                u8 __iomem *base_addr = mac_cb->serdes_vaddr +
 670                                (mac_cb->mac_id <= 3 ? 0x00280000 : 0x00200000);
 671                dsaf_set_reg_field(base_addr, reg_offset, 1ull << 10, 10, en);
 672        }
 673
 674        return 0;
 675}
 676
 677static int
 678hns_mac_config_sds_loopback_acpi(struct hns_mac_cb *mac_cb, bool en)
 679{
 680        union acpi_object *obj;
 681        union acpi_object obj_args[3], argv4;
 682
 683        obj_args[0].integer.type = ACPI_TYPE_INTEGER;
 684        obj_args[0].integer.value = mac_cb->mac_id;
 685        obj_args[1].integer.type = ACPI_TYPE_INTEGER;
 686        obj_args[1].integer.value = !!en;
 687
 688        argv4.type = ACPI_TYPE_PACKAGE;
 689        argv4.package.count = 2;
 690        argv4.package.elements = obj_args;
 691
 692        obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dsaf_dev->dev),
 693                                &hns_dsaf_acpi_dsm_guid, 0,
 694                                HNS_OP_SERDES_LP_FUNC, &argv4);
 695        if (!obj) {
 696                dev_warn(mac_cb->dsaf_dev->dev, "set port%d serdes lp fail!",
 697                         mac_cb->mac_id);
 698
 699                return -ENOTSUPP;
 700        }
 701
 702        ACPI_FREE(obj);
 703
 704        return 0;
 705}
 706
 707struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device *dsaf_dev)
 708{
 709        struct dsaf_misc_op *misc_op;
 710
 711        misc_op = devm_kzalloc(dsaf_dev->dev, sizeof(*misc_op), GFP_KERNEL);
 712        if (!misc_op)
 713                return NULL;
 714
 715        if (dev_of_node(dsaf_dev->dev)) {
 716                misc_op->cpld_set_led = hns_cpld_set_led;
 717                misc_op->cpld_reset_led = cpld_led_reset;
 718                misc_op->cpld_set_led_id = cpld_set_led_id;
 719
 720                misc_op->dsaf_reset = hns_dsaf_rst;
 721                misc_op->xge_srst = hns_dsaf_xge_srst_by_port;
 722                misc_op->ge_srst = hns_dsaf_ge_srst_by_port;
 723                misc_op->ppe_srst = hns_ppe_srst_by_port;
 724                misc_op->ppe_comm_srst = hns_ppe_com_srst;
 725                misc_op->hns_dsaf_srst_chns = hns_dsaf_srst_chns;
 726                misc_op->hns_dsaf_roce_srst = hns_dsaf_roce_srst;
 727
 728                misc_op->get_phy_if = hns_mac_get_phy_if;
 729                misc_op->get_sfp_prsnt = hns_mac_get_sfp_prsnt;
 730
 731                misc_op->cfg_serdes_loopback = hns_mac_config_sds_loopback;
 732        } else if (is_acpi_node(dsaf_dev->dev->fwnode)) {
 733                misc_op->cpld_set_led = hns_cpld_set_led_acpi;
 734                misc_op->cpld_reset_led = cpld_led_reset_acpi;
 735                misc_op->cpld_set_led_id = cpld_set_led_id_acpi;
 736
 737                misc_op->dsaf_reset = hns_dsaf_rst_acpi;
 738                misc_op->xge_srst = hns_dsaf_xge_srst_by_port_acpi;
 739                misc_op->ge_srst = hns_dsaf_ge_srst_by_port_acpi;
 740                misc_op->ppe_srst = hns_ppe_srst_by_port_acpi;
 741                misc_op->ppe_comm_srst = hns_ppe_com_srst;
 742                misc_op->hns_dsaf_srst_chns = hns_dsaf_srst_chns_acpi;
 743                misc_op->hns_dsaf_roce_srst = hns_dsaf_roce_srst_acpi;
 744
 745                misc_op->get_phy_if = hns_mac_get_phy_if_acpi;
 746                misc_op->get_sfp_prsnt = hns_mac_get_sfp_prsnt_acpi;
 747
 748                misc_op->cfg_serdes_loopback = hns_mac_config_sds_loopback_acpi;
 749        } else {
 750                devm_kfree(dsaf_dev->dev, (void *)misc_op);
 751                misc_op = NULL;
 752        }
 753
 754        return (void *)misc_op;
 755}
 756
 757struct
 758platform_device *hns_dsaf_find_platform_device(struct fwnode_handle *fwnode)
 759{
 760        struct device *dev;
 761
 762        dev = bus_find_device_by_fwnode(&platform_bus_type, fwnode);
 763        return dev ? to_platform_device(dev) : NULL;
 764}
 765