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