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