linux/drivers/net/ethernet/hisilicon/hns/hns_ethtool.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 <linux/etherdevice.h>
  11#include <linux/interrupt.h>
  12#include <linux/module.h>
  13#include <linux/platform_device.h>
  14#include "hns_enet.h"
  15
  16#define HNS_PHY_PAGE_MDIX       0
  17#define HNS_PHY_PAGE_LED        3
  18#define HNS_PHY_PAGE_COPPER     0
  19
  20#define HNS_PHY_PAGE_REG        22      /* Page Selection Reg. */
  21#define HNS_PHY_CSC_REG         16      /* Copper Specific Control Register */
  22#define HNS_PHY_CSS_REG         17      /* Copper Specific Status Register */
  23#define HNS_LED_FC_REG          16      /* LED Function Control Reg. */
  24#define HNS_LED_PC_REG          17      /* LED Polarity Control Reg. */
  25
  26#define HNS_LED_FORCE_ON        9
  27#define HNS_LED_FORCE_OFF       8
  28
  29#define HNS_CHIP_VERSION 660
  30#define HNS_NET_STATS_CNT 26
  31
  32#define PHY_MDIX_CTRL_S         (5)
  33#define PHY_MDIX_CTRL_M         (3 << PHY_MDIX_CTRL_S)
  34
  35#define PHY_MDIX_STATUS_B       (6)
  36#define PHY_SPEED_DUP_RESOLVE_B (11)
  37
  38/**
  39 *hns_nic_get_link - get current link status
  40 *@net_dev: net_device
  41 *retuen 0 - success , negative --fail
  42 */
  43static u32 hns_nic_get_link(struct net_device *net_dev)
  44{
  45        struct hns_nic_priv *priv = netdev_priv(net_dev);
  46        u32 link_stat = priv->link;
  47        struct hnae_handle *h;
  48
  49        assert(priv && priv->ae_handle);
  50        h = priv->ae_handle;
  51
  52        if (priv->phy) {
  53                if (!genphy_update_link(priv->phy))
  54                        link_stat = priv->phy->link;
  55                else
  56                        link_stat = 0;
  57        }
  58
  59        if (h->dev && h->dev->ops && h->dev->ops->get_status)
  60                link_stat = link_stat && h->dev->ops->get_status(h);
  61        else
  62                link_stat = 0;
  63
  64        return link_stat;
  65}
  66
  67static void hns_get_mdix_mode(struct net_device *net_dev,
  68                              struct ethtool_cmd *cmd)
  69{
  70        int mdix_ctrl, mdix, retval, is_resolved;
  71        struct hns_nic_priv *priv = netdev_priv(net_dev);
  72        struct phy_device *phy_dev = priv->phy;
  73
  74        if (!phy_dev || !phy_dev->mdio.bus) {
  75                cmd->eth_tp_mdix_ctrl = ETH_TP_MDI_INVALID;
  76                cmd->eth_tp_mdix = ETH_TP_MDI_INVALID;
  77                return;
  78        }
  79
  80        phy_write(phy_dev, HNS_PHY_PAGE_REG, HNS_PHY_PAGE_MDIX);
  81
  82        retval = phy_read(phy_dev, HNS_PHY_CSC_REG);
  83        mdix_ctrl = hnae_get_field(retval, PHY_MDIX_CTRL_M, PHY_MDIX_CTRL_S);
  84
  85        retval = phy_read(phy_dev, HNS_PHY_CSS_REG);
  86        mdix = hnae_get_bit(retval, PHY_MDIX_STATUS_B);
  87        is_resolved = hnae_get_bit(retval, PHY_SPEED_DUP_RESOLVE_B);
  88
  89        phy_write(phy_dev, HNS_PHY_PAGE_REG, HNS_PHY_PAGE_COPPER);
  90
  91        switch (mdix_ctrl) {
  92        case 0x0:
  93                cmd->eth_tp_mdix_ctrl = ETH_TP_MDI;
  94                break;
  95        case 0x1:
  96                cmd->eth_tp_mdix_ctrl = ETH_TP_MDI_X;
  97                break;
  98        case 0x3:
  99                cmd->eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;
 100                break;
 101        default:
 102                cmd->eth_tp_mdix_ctrl = ETH_TP_MDI_INVALID;
 103                break;
 104        }
 105
 106        if (!is_resolved)
 107                cmd->eth_tp_mdix = ETH_TP_MDI_INVALID;
 108        else if (mdix)
 109                cmd->eth_tp_mdix = ETH_TP_MDI_X;
 110        else
 111                cmd->eth_tp_mdix = ETH_TP_MDI;
 112}
 113
 114/**
 115 *hns_nic_get_settings - implement ethtool get settings
 116 *@net_dev: net_device
 117 *@cmd: ethtool_cmd
 118 *retuen 0 - success , negative --fail
 119 */
 120static int hns_nic_get_settings(struct net_device *net_dev,
 121                                struct ethtool_cmd *cmd)
 122{
 123        struct hns_nic_priv *priv = netdev_priv(net_dev);
 124        struct hnae_handle *h;
 125        u32 link_stat;
 126        int ret;
 127        u8 duplex;
 128        u16 speed;
 129
 130        if (!priv || !priv->ae_handle)
 131                return -ESRCH;
 132
 133        h = priv->ae_handle;
 134        if (!h->dev || !h->dev->ops || !h->dev->ops->get_info)
 135                return -ESRCH;
 136
 137        ret = h->dev->ops->get_info(h, NULL, &speed, &duplex);
 138        if (ret < 0) {
 139                netdev_err(net_dev, "%s get_info error!\n", __func__);
 140                return -EINVAL;
 141        }
 142
 143        /* When there is no phy, autoneg is off. */
 144        cmd->autoneg = false;
 145        ethtool_cmd_speed_set(cmd, speed);
 146        cmd->duplex = duplex;
 147
 148        if (priv->phy)
 149                (void)phy_ethtool_gset(priv->phy, cmd);
 150
 151        link_stat = hns_nic_get_link(net_dev);
 152        if (!link_stat) {
 153                ethtool_cmd_speed_set(cmd, (u32)SPEED_UNKNOWN);
 154                cmd->duplex = DUPLEX_UNKNOWN;
 155        }
 156
 157        if (cmd->autoneg)
 158                cmd->advertising |= ADVERTISED_Autoneg;
 159
 160        cmd->supported |= h->if_support;
 161        if (h->phy_if == PHY_INTERFACE_MODE_SGMII) {
 162                cmd->supported |= SUPPORTED_TP;
 163                cmd->advertising |= ADVERTISED_1000baseT_Full;
 164        } else if (h->phy_if == PHY_INTERFACE_MODE_XGMII) {
 165                cmd->supported |= SUPPORTED_FIBRE;
 166                cmd->advertising |= ADVERTISED_10000baseKR_Full;
 167        }
 168
 169        if (h->port_type == HNAE_PORT_SERVICE) {
 170                cmd->port = PORT_FIBRE;
 171                cmd->supported |= SUPPORTED_Pause;
 172        } else {
 173                cmd->port = PORT_TP;
 174        }
 175
 176        cmd->transceiver = XCVR_EXTERNAL;
 177        cmd->mdio_support = (ETH_MDIO_SUPPORTS_C45 | ETH_MDIO_SUPPORTS_C22);
 178        hns_get_mdix_mode(net_dev, cmd);
 179
 180        return 0;
 181}
 182
 183/**
 184 *hns_nic_set_settings - implement ethtool set settings
 185 *@net_dev: net_device
 186 *@cmd: ethtool_cmd
 187 *retuen 0 - success , negative --fail
 188 */
 189static int hns_nic_set_settings(struct net_device *net_dev,
 190                                struct ethtool_cmd *cmd)
 191{
 192        struct hns_nic_priv *priv = netdev_priv(net_dev);
 193        struct hnae_handle *h;
 194        u32 speed;
 195
 196        if (!netif_running(net_dev))
 197                return -ESRCH;
 198
 199        if (!priv || !priv->ae_handle || !priv->ae_handle->dev ||
 200            !priv->ae_handle->dev->ops)
 201                return -ENODEV;
 202
 203        h = priv->ae_handle;
 204        speed = ethtool_cmd_speed(cmd);
 205
 206        if (h->phy_if == PHY_INTERFACE_MODE_XGMII) {
 207                if (cmd->autoneg == AUTONEG_ENABLE || speed != SPEED_10000 ||
 208                    cmd->duplex != DUPLEX_FULL)
 209                        return -EINVAL;
 210        } else if (h->phy_if == PHY_INTERFACE_MODE_SGMII) {
 211                if (!priv->phy && cmd->autoneg == AUTONEG_ENABLE)
 212                        return -EINVAL;
 213
 214                if (speed == SPEED_1000 && cmd->duplex == DUPLEX_HALF)
 215                        return -EINVAL;
 216                if (priv->phy)
 217                        return phy_ethtool_sset(priv->phy, cmd);
 218
 219                if ((speed != SPEED_10 && speed != SPEED_100 &&
 220                     speed != SPEED_1000) || (cmd->duplex != DUPLEX_HALF &&
 221                     cmd->duplex != DUPLEX_FULL))
 222                        return -EINVAL;
 223        } else {
 224                netdev_err(net_dev, "Not supported!");
 225                return -ENOTSUPP;
 226        }
 227
 228        if (h->dev->ops->adjust_link) {
 229                h->dev->ops->adjust_link(h, (int)speed, cmd->duplex);
 230                return 0;
 231        }
 232
 233        netdev_err(net_dev, "Not supported!");
 234        return -ENOTSUPP;
 235}
 236
 237static const char hns_nic_test_strs[][ETH_GSTRING_LEN] = {
 238        "Mac    Loopback test",
 239        "Serdes Loopback test",
 240        "Phy    Loopback test"
 241};
 242
 243static int hns_nic_config_phy_loopback(struct phy_device *phy_dev, u8 en)
 244{
 245#define COPPER_CONTROL_REG 0
 246#define PHY_LOOP_BACK BIT(14)
 247        u16 val = 0;
 248
 249        if (phy_dev->is_c45) /* c45 branch adding for XGE PHY */
 250                return -ENOTSUPP;
 251
 252        if (en) {
 253                /* speed : 1000M */
 254                phy_write(phy_dev, HNS_PHY_PAGE_REG, 2);
 255                phy_write(phy_dev, 21, 0x1046);
 256                /* Force Master */
 257                phy_write(phy_dev, 9, 0x1F00);
 258                /* Soft-reset */
 259                phy_write(phy_dev, 0, 0x9140);
 260                /* If autoneg disabled,two soft-reset operations */
 261                phy_write(phy_dev, 0, 0x9140);
 262                phy_write(phy_dev, 22, 0xFA);
 263
 264                /* Default is 0x0400 */
 265                phy_write(phy_dev, 1, 0x418);
 266
 267                /* Force 1000M Link, Default is 0x0200 */
 268                phy_write(phy_dev, 7, 0x20C);
 269                phy_write(phy_dev, 22, 0);
 270
 271                /* Enable MAC loop-back */
 272                val = phy_read(phy_dev, COPPER_CONTROL_REG);
 273                val |= PHY_LOOP_BACK;
 274                phy_write(phy_dev, COPPER_CONTROL_REG, val);
 275        } else {
 276                phy_write(phy_dev, 22, 0xFA);
 277                phy_write(phy_dev, 1, 0x400);
 278                phy_write(phy_dev, 7, 0x200);
 279                phy_write(phy_dev, 22, 0);
 280
 281                val = phy_read(phy_dev, COPPER_CONTROL_REG);
 282                val &= ~PHY_LOOP_BACK;
 283                phy_write(phy_dev, COPPER_CONTROL_REG, val);
 284        }
 285        return 0;
 286}
 287
 288static int __lb_setup(struct net_device *ndev,
 289                      enum hnae_loop loop)
 290{
 291        int ret = 0;
 292        struct hns_nic_priv *priv = netdev_priv(ndev);
 293        struct phy_device *phy_dev = priv->phy;
 294        struct hnae_handle *h = priv->ae_handle;
 295
 296        switch (loop) {
 297        case MAC_INTERNALLOOP_PHY:
 298                if ((phy_dev) && (!phy_dev->is_c45)) {
 299                        ret = hns_nic_config_phy_loopback(phy_dev, 0x1);
 300                        ret |= h->dev->ops->set_loopback(h, loop, 0x1);
 301                }
 302                break;
 303        case MAC_INTERNALLOOP_MAC:
 304                if ((h->dev->ops->set_loopback) &&
 305                    (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII))
 306                        ret = h->dev->ops->set_loopback(h, loop, 0x1);
 307                break;
 308        case MAC_INTERNALLOOP_SERDES:
 309                if (h->dev->ops->set_loopback)
 310                        ret = h->dev->ops->set_loopback(h, loop, 0x1);
 311                break;
 312        case MAC_LOOP_NONE:
 313                if ((phy_dev) && (!phy_dev->is_c45))
 314                        ret |= hns_nic_config_phy_loopback(phy_dev, 0x0);
 315
 316                if (h->dev->ops->set_loopback) {
 317                        if (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII)
 318                                ret |= h->dev->ops->set_loopback(h,
 319                                        MAC_INTERNALLOOP_MAC, 0x0);
 320
 321                        ret |= h->dev->ops->set_loopback(h,
 322                                MAC_INTERNALLOOP_SERDES, 0x0);
 323                }
 324                break;
 325        default:
 326                ret = -EINVAL;
 327                break;
 328        }
 329
 330        return ret;
 331}
 332
 333static int __lb_up(struct net_device *ndev,
 334                   enum hnae_loop loop_mode)
 335{
 336        struct hns_nic_priv *priv = netdev_priv(ndev);
 337        struct hnae_handle *h = priv->ae_handle;
 338        int speed, duplex;
 339        int ret;
 340
 341        hns_nic_net_reset(ndev);
 342
 343        if (priv->phy) {
 344                phy_disconnect(priv->phy);
 345                msleep(100);
 346
 347                ret = hns_nic_init_phy(ndev, h);
 348                if (ret)
 349                        return ret;
 350        }
 351
 352        ret = __lb_setup(ndev, loop_mode);
 353        if (ret)
 354                return ret;
 355
 356        msleep(100);
 357
 358        ret = h->dev->ops->start ? h->dev->ops->start(h) : 0;
 359        if (ret)
 360                return ret;
 361
 362        if (priv->phy)
 363                phy_start(priv->phy);
 364
 365        /* link adjust duplex*/
 366        if (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII)
 367                speed = 1000;
 368        else
 369                speed = 10000;
 370        duplex = 1;
 371
 372        h->dev->ops->adjust_link(h, speed, duplex);
 373
 374        return 0;
 375}
 376
 377static void __lb_other_process(struct hns_nic_ring_data *ring_data,
 378                               struct sk_buff *skb)
 379{
 380        struct net_device *ndev;
 381        struct hns_nic_priv *priv;
 382        struct hnae_ring *ring;
 383        struct netdev_queue *dev_queue;
 384        struct sk_buff *new_skb;
 385        unsigned int frame_size;
 386        int check_ok;
 387        u32 i;
 388        char buff[33]; /* 32B data and the last character '\0' */
 389
 390        if (!ring_data) { /* Just for doing create frame*/
 391                ndev = skb->dev;
 392                priv = netdev_priv(ndev);
 393
 394                frame_size = skb->len;
 395                memset(skb->data, 0xFF, frame_size);
 396                if ((!AE_IS_VER1(priv->enet_ver)) &&
 397                    (priv->ae_handle->port_type == HNAE_PORT_SERVICE)) {
 398                        memcpy(skb->data, ndev->dev_addr, 6);
 399                        skb->data[5] += 0x1f;
 400                }
 401
 402                frame_size &= ~1ul;
 403                memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1);
 404                memset(&skb->data[frame_size / 2 + 10], 0xBE,
 405                       frame_size / 2 - 11);
 406                memset(&skb->data[frame_size / 2 + 12], 0xAF,
 407                       frame_size / 2 - 13);
 408                return;
 409        }
 410
 411        ring = ring_data->ring;
 412        ndev = ring_data->napi.dev;
 413        if (is_tx_ring(ring)) { /* for tx queue reset*/
 414                dev_queue = netdev_get_tx_queue(ndev, ring_data->queue_index);
 415                netdev_tx_reset_queue(dev_queue);
 416                return;
 417        }
 418
 419        frame_size = skb->len;
 420        frame_size &= ~1ul;
 421        /* for mutl buffer*/
 422        new_skb = skb_copy(skb, GFP_ATOMIC);
 423        dev_kfree_skb_any(skb);
 424        skb = new_skb;
 425
 426        check_ok = 0;
 427        if (*(skb->data + 10) == 0xFF) { /* for rx check frame*/
 428                if ((*(skb->data + frame_size / 2 + 10) == 0xBE) &&
 429                    (*(skb->data + frame_size / 2 + 12) == 0xAF))
 430                        check_ok = 1;
 431        }
 432
 433        if (check_ok) {
 434                ndev->stats.rx_packets++;
 435                ndev->stats.rx_bytes += skb->len;
 436        } else {
 437                ndev->stats.rx_frame_errors++;
 438                for (i = 0; i < skb->len; i++) {
 439                        snprintf(buff + i % 16 * 2, 3, /* tailing \0*/
 440                                 "%02x", *(skb->data + i));
 441                        if ((i % 16 == 15) || (i == skb->len - 1))
 442                                pr_info("%s\n", buff);
 443                }
 444        }
 445        dev_kfree_skb_any(skb);
 446}
 447
 448static int __lb_clean_rings(struct hns_nic_priv *priv,
 449                            int ringid0, int ringid1, int budget)
 450{
 451        int i, ret;
 452        struct hns_nic_ring_data *ring_data;
 453        struct net_device *ndev = priv->netdev;
 454        unsigned long rx_packets = ndev->stats.rx_packets;
 455        unsigned long rx_bytes = ndev->stats.rx_bytes;
 456        unsigned long rx_frame_errors = ndev->stats.rx_frame_errors;
 457
 458        for (i = ringid0; i <= ringid1; i++) {
 459                ring_data = &priv->ring_data[i];
 460                (void)ring_data->poll_one(ring_data,
 461                                          budget, __lb_other_process);
 462        }
 463        ret = (int)(ndev->stats.rx_packets - rx_packets);
 464        ndev->stats.rx_packets = rx_packets;
 465        ndev->stats.rx_bytes = rx_bytes;
 466        ndev->stats.rx_frame_errors = rx_frame_errors;
 467        return ret;
 468}
 469
 470/**
 471 * nic_run_loopback_test -  run loopback test
 472 * @nic_dev: net device
 473 * @loopback_type: loopback type
 474 */
 475static int __lb_run_test(struct net_device *ndev,
 476                         enum hnae_loop loop_mode)
 477{
 478#define NIC_LB_TEST_PKT_NUM_PER_CYCLE 1
 479#define NIC_LB_TEST_RING_ID 0
 480#define NIC_LB_TEST_FRAME_SIZE 128
 481/* nic loopback test err  */
 482#define NIC_LB_TEST_NO_MEM_ERR 1
 483#define NIC_LB_TEST_TX_CNT_ERR 2
 484#define NIC_LB_TEST_RX_CNT_ERR 3
 485#define NIC_LB_TEST_RX_PKG_ERR 4
 486        struct hns_nic_priv *priv = netdev_priv(ndev);
 487        struct hnae_handle *h = priv->ae_handle;
 488        int i, j, lc, good_cnt, ret_val = 0;
 489        unsigned int size;
 490        netdev_tx_t tx_ret_val;
 491        struct sk_buff *skb;
 492
 493        size = NIC_LB_TEST_FRAME_SIZE;
 494        /* allocate test skb */
 495        skb = alloc_skb(size, GFP_KERNEL);
 496        if (!skb)
 497                return NIC_LB_TEST_NO_MEM_ERR;
 498
 499        /* place data into test skb */
 500        (void)skb_put(skb, size);
 501        skb->dev = ndev;
 502        __lb_other_process(NULL, skb);
 503        skb->queue_mapping = NIC_LB_TEST_RING_ID;
 504
 505        lc = 1;
 506        for (j = 0; j < lc; j++) {
 507                /* reset count of good packets */
 508                good_cnt = 0;
 509                /* place 64 packets on the transmit queue*/
 510                for (i = 0; i < NIC_LB_TEST_PKT_NUM_PER_CYCLE; i++) {
 511                        (void)skb_get(skb);
 512
 513                        tx_ret_val = (netdev_tx_t)hns_nic_net_xmit_hw(
 514                                ndev, skb,
 515                                &tx_ring_data(priv, skb->queue_mapping));
 516                        if (tx_ret_val == NETDEV_TX_OK)
 517                                good_cnt++;
 518                        else
 519                                break;
 520                }
 521                if (good_cnt != NIC_LB_TEST_PKT_NUM_PER_CYCLE) {
 522                        ret_val = NIC_LB_TEST_TX_CNT_ERR;
 523                        dev_err(priv->dev, "%s sent fail, cnt=0x%x, budget=0x%x\n",
 524                                hns_nic_test_strs[loop_mode], good_cnt,
 525                                NIC_LB_TEST_PKT_NUM_PER_CYCLE);
 526                        break;
 527                }
 528
 529                /* allow 100 milliseconds for packets to go from Tx to Rx */
 530                msleep(100);
 531
 532                good_cnt = __lb_clean_rings(priv,
 533                                            h->q_num, h->q_num * 2 - 1,
 534                                            NIC_LB_TEST_PKT_NUM_PER_CYCLE);
 535                if (good_cnt != NIC_LB_TEST_PKT_NUM_PER_CYCLE) {
 536                        ret_val = NIC_LB_TEST_RX_CNT_ERR;
 537                        dev_err(priv->dev, "%s recv fail, cnt=0x%x, budget=0x%x\n",
 538                                hns_nic_test_strs[loop_mode], good_cnt,
 539                                NIC_LB_TEST_PKT_NUM_PER_CYCLE);
 540                        break;
 541                }
 542                (void)__lb_clean_rings(priv,
 543                                       NIC_LB_TEST_RING_ID, NIC_LB_TEST_RING_ID,
 544                                       NIC_LB_TEST_PKT_NUM_PER_CYCLE);
 545        }
 546
 547        /* free the original skb */
 548        kfree_skb(skb);
 549
 550        return ret_val;
 551}
 552
 553static int __lb_down(struct net_device *ndev)
 554{
 555        struct hns_nic_priv *priv = netdev_priv(ndev);
 556        struct hnae_handle *h = priv->ae_handle;
 557        int ret;
 558
 559        ret = __lb_setup(ndev, MAC_LOOP_NONE);
 560        if (ret)
 561                netdev_err(ndev, "%s: __lb_setup return error(%d)!\n",
 562                           __func__,
 563                           ret);
 564
 565        if (priv->phy)
 566                phy_stop(priv->phy);
 567
 568        if (h->dev->ops->stop)
 569                h->dev->ops->stop(h);
 570
 571        usleep_range(10000, 20000);
 572        (void)__lb_clean_rings(priv, 0, h->q_num - 1, 256);
 573
 574        hns_nic_net_reset(ndev);
 575
 576        return 0;
 577}
 578
 579/**
 580 * hns_nic_self_test - self test
 581 * @dev: net device
 582 * @eth_test: test cmd
 583 * @data: test result
 584 */
 585static void hns_nic_self_test(struct net_device *ndev,
 586                              struct ethtool_test *eth_test, u64 *data)
 587{
 588        struct hns_nic_priv *priv = netdev_priv(ndev);
 589        bool if_running = netif_running(ndev);
 590#define SELF_TEST_TPYE_NUM 3
 591        int st_param[SELF_TEST_TPYE_NUM][2];
 592        int i;
 593        int test_index = 0;
 594
 595        st_param[0][0] = MAC_INTERNALLOOP_MAC; /* XGE not supported lb */
 596        st_param[0][1] = (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII);
 597        st_param[1][0] = MAC_INTERNALLOOP_SERDES;
 598        st_param[1][1] = 1; /*serdes must exist*/
 599        st_param[2][0] = MAC_INTERNALLOOP_PHY; /* only supporte phy node*/
 600        st_param[2][1] = ((!!(priv->ae_handle->phy_node)) &&
 601                (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII));
 602
 603        if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
 604                set_bit(NIC_STATE_TESTING, &priv->state);
 605
 606                if (if_running)
 607                        (void)dev_close(ndev);
 608
 609                for (i = 0; i < SELF_TEST_TPYE_NUM; i++) {
 610                        if (!st_param[i][1])
 611                                continue;       /* NEXT testing */
 612
 613                        data[test_index] = __lb_up(ndev,
 614                                (enum hnae_loop)st_param[i][0]);
 615                        if (!data[test_index]) {
 616                                data[test_index] = __lb_run_test(
 617                                        ndev, (enum hnae_loop)st_param[i][0]);
 618                                (void)__lb_down(ndev);
 619                        }
 620
 621                        if (data[test_index])
 622                                eth_test->flags |= ETH_TEST_FL_FAILED;
 623
 624                        test_index++;
 625                }
 626
 627                hns_nic_net_reset(priv->netdev);
 628
 629                clear_bit(NIC_STATE_TESTING, &priv->state);
 630
 631                if (if_running)
 632                        (void)dev_open(ndev);
 633        }
 634        /* Online tests aren't run; pass by default */
 635
 636        (void)msleep_interruptible(4 * 1000);
 637}
 638
 639/**
 640 * hns_nic_get_drvinfo - get net driver info
 641 * @dev: net device
 642 * @drvinfo: driver info
 643 */
 644static void hns_nic_get_drvinfo(struct net_device *net_dev,
 645                                struct ethtool_drvinfo *drvinfo)
 646{
 647        struct hns_nic_priv *priv = netdev_priv(net_dev);
 648
 649        assert(priv);
 650
 651        strncpy(drvinfo->version, HNAE_DRIVER_VERSION,
 652                sizeof(drvinfo->version));
 653        drvinfo->version[sizeof(drvinfo->version) - 1] = '\0';
 654
 655        strncpy(drvinfo->driver, HNAE_DRIVER_NAME, sizeof(drvinfo->driver));
 656        drvinfo->driver[sizeof(drvinfo->driver) - 1] = '\0';
 657
 658        strncpy(drvinfo->bus_info, priv->dev->bus->name,
 659                sizeof(drvinfo->bus_info));
 660        drvinfo->bus_info[ETHTOOL_BUSINFO_LEN - 1] = '\0';
 661
 662        strncpy(drvinfo->fw_version, "N/A", ETHTOOL_FWVERS_LEN);
 663        drvinfo->eedump_len = 0;
 664}
 665
 666/**
 667 * hns_get_ringparam - get ring parameter
 668 * @dev: net device
 669 * @param: ethtool parameter
 670 */
 671void hns_get_ringparam(struct net_device *net_dev,
 672                       struct ethtool_ringparam *param)
 673{
 674        struct hns_nic_priv *priv = netdev_priv(net_dev);
 675        struct hnae_ae_ops *ops;
 676        struct hnae_queue *queue;
 677        u32 uplimit = 0;
 678
 679        queue = priv->ae_handle->qs[0];
 680        ops = priv->ae_handle->dev->ops;
 681
 682        if (ops->get_ring_bdnum_limit)
 683                ops->get_ring_bdnum_limit(queue, &uplimit);
 684
 685        param->rx_max_pending = uplimit;
 686        param->tx_max_pending = uplimit;
 687        param->rx_pending = queue->rx_ring.desc_num;
 688        param->tx_pending = queue->tx_ring.desc_num;
 689}
 690
 691/**
 692 * hns_get_pauseparam - get pause parameter
 693 * @dev: net device
 694 * @param: pause parameter
 695 */
 696static void hns_get_pauseparam(struct net_device *net_dev,
 697                               struct ethtool_pauseparam *param)
 698{
 699        struct hns_nic_priv *priv = netdev_priv(net_dev);
 700        struct hnae_ae_ops *ops;
 701
 702        ops = priv->ae_handle->dev->ops;
 703
 704        if (ops->get_pauseparam)
 705                ops->get_pauseparam(priv->ae_handle, &param->autoneg,
 706                                            &param->rx_pause, &param->tx_pause);
 707}
 708
 709/**
 710 * hns_set_pauseparam - set pause parameter
 711 * @dev: net device
 712 * @param: pause parameter
 713 *
 714 * Return 0 on success, negative on failure
 715 */
 716static int hns_set_pauseparam(struct net_device *net_dev,
 717                              struct ethtool_pauseparam *param)
 718{
 719        struct hns_nic_priv *priv = netdev_priv(net_dev);
 720        struct hnae_handle *h;
 721        struct hnae_ae_ops *ops;
 722
 723        assert(priv || priv->ae_handle);
 724
 725        h = priv->ae_handle;
 726        ops = h->dev->ops;
 727
 728        if (!ops->set_pauseparam)
 729                return -ESRCH;
 730
 731        return ops->set_pauseparam(priv->ae_handle, param->autoneg,
 732                                   param->rx_pause, param->tx_pause);
 733}
 734
 735/**
 736 * hns_get_coalesce - get coalesce info.
 737 * @dev: net device
 738 * @ec: coalesce info.
 739 *
 740 * Return 0 on success, negative on failure.
 741 */
 742static int hns_get_coalesce(struct net_device *net_dev,
 743                            struct ethtool_coalesce *ec)
 744{
 745        struct hns_nic_priv *priv = netdev_priv(net_dev);
 746        struct hnae_ae_ops *ops;
 747
 748        ops = priv->ae_handle->dev->ops;
 749
 750        ec->use_adaptive_rx_coalesce = 1;
 751        ec->use_adaptive_tx_coalesce = 1;
 752
 753        if ((!ops->get_coalesce_usecs) ||
 754            (!ops->get_rx_max_coalesced_frames))
 755                return -ESRCH;
 756
 757        ops->get_coalesce_usecs(priv->ae_handle,
 758                                        &ec->tx_coalesce_usecs,
 759                                        &ec->rx_coalesce_usecs);
 760
 761        ops->get_rx_max_coalesced_frames(
 762                priv->ae_handle,
 763                &ec->tx_max_coalesced_frames,
 764                &ec->rx_max_coalesced_frames);
 765
 766        return 0;
 767}
 768
 769/**
 770 * hns_set_coalesce - set coalesce info.
 771 * @dev: net device
 772 * @ec: coalesce info.
 773 *
 774 * Return 0 on success, negative on failure.
 775 */
 776static int hns_set_coalesce(struct net_device *net_dev,
 777                            struct ethtool_coalesce *ec)
 778{
 779        struct hns_nic_priv *priv = netdev_priv(net_dev);
 780        struct hnae_ae_ops *ops;
 781        int ret;
 782
 783        assert(priv || priv->ae_handle);
 784
 785        ops = priv->ae_handle->dev->ops;
 786
 787        if (ec->tx_coalesce_usecs != ec->rx_coalesce_usecs)
 788                return -EINVAL;
 789
 790        if (ec->rx_max_coalesced_frames != ec->tx_max_coalesced_frames)
 791                return -EINVAL;
 792
 793        if ((!ops->set_coalesce_usecs) ||
 794            (!ops->set_coalesce_frames))
 795                return -ESRCH;
 796
 797        ops->set_coalesce_usecs(priv->ae_handle,
 798                                        ec->rx_coalesce_usecs);
 799
 800        ret = ops->set_coalesce_frames(
 801                priv->ae_handle,
 802                ec->rx_max_coalesced_frames);
 803
 804        return ret;
 805}
 806
 807/**
 808 * hns_get_channels - get channel info.
 809 * @dev: net device
 810 * @ch: channel info.
 811 */
 812void hns_get_channels(struct net_device *net_dev, struct ethtool_channels *ch)
 813{
 814        struct hns_nic_priv *priv = netdev_priv(net_dev);
 815
 816        ch->max_rx = priv->ae_handle->q_num;
 817        ch->max_tx = priv->ae_handle->q_num;
 818
 819        ch->rx_count = priv->ae_handle->q_num;
 820        ch->tx_count = priv->ae_handle->q_num;
 821}
 822
 823/**
 824 * get_ethtool_stats - get detail statistics.
 825 * @dev: net device
 826 * @stats: statistics info.
 827 * @data: statistics data.
 828 */
 829void hns_get_ethtool_stats(struct net_device *netdev,
 830                           struct ethtool_stats *stats, u64 *data)
 831{
 832        u64 *p = data;
 833        struct hns_nic_priv *priv = netdev_priv(netdev);
 834        struct hnae_handle *h = priv->ae_handle;
 835        const struct rtnl_link_stats64 *net_stats;
 836        struct rtnl_link_stats64 temp;
 837
 838        if (!h->dev->ops->get_stats || !h->dev->ops->update_stats) {
 839                netdev_err(netdev, "get_stats or update_stats is null!\n");
 840                return;
 841        }
 842
 843        h->dev->ops->update_stats(h, &netdev->stats);
 844
 845        net_stats = dev_get_stats(netdev, &temp);
 846
 847        /* get netdev statistics */
 848        p[0] = net_stats->rx_packets;
 849        p[1] = net_stats->tx_packets;
 850        p[2] = net_stats->rx_bytes;
 851        p[3] = net_stats->tx_bytes;
 852        p[4] = net_stats->rx_errors;
 853        p[5] = net_stats->tx_errors;
 854        p[6] = net_stats->rx_dropped;
 855        p[7] = net_stats->tx_dropped;
 856        p[8] = net_stats->multicast;
 857        p[9] = net_stats->collisions;
 858        p[10] = net_stats->rx_over_errors;
 859        p[11] = net_stats->rx_crc_errors;
 860        p[12] = net_stats->rx_frame_errors;
 861        p[13] = net_stats->rx_fifo_errors;
 862        p[14] = net_stats->rx_missed_errors;
 863        p[15] = net_stats->tx_aborted_errors;
 864        p[16] = net_stats->tx_carrier_errors;
 865        p[17] = net_stats->tx_fifo_errors;
 866        p[18] = net_stats->tx_heartbeat_errors;
 867        p[19] = net_stats->rx_length_errors;
 868        p[20] = net_stats->tx_window_errors;
 869        p[21] = net_stats->rx_compressed;
 870        p[22] = net_stats->tx_compressed;
 871
 872        p[23] = netdev->rx_dropped.counter;
 873        p[24] = netdev->tx_dropped.counter;
 874
 875        p[25] = priv->tx_timeout_count;
 876
 877        /* get driver statistics */
 878        h->dev->ops->get_stats(h, &p[26]);
 879}
 880
 881/**
 882 * get_strings: Return a set of strings that describe the requested objects
 883 * @dev: net device
 884 * @stats: string set ID.
 885 * @data: objects data.
 886 */
 887void hns_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
 888{
 889        struct hns_nic_priv *priv = netdev_priv(netdev);
 890        struct hnae_handle *h = priv->ae_handle;
 891        char *buff = (char *)data;
 892
 893        if (!h->dev->ops->get_strings) {
 894                netdev_err(netdev, "h->dev->ops->get_strings is null!\n");
 895                return;
 896        }
 897
 898        if (stringset == ETH_SS_TEST) {
 899                if (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII) {
 900                        memcpy(buff, hns_nic_test_strs[MAC_INTERNALLOOP_MAC],
 901                               ETH_GSTRING_LEN);
 902                        buff += ETH_GSTRING_LEN;
 903                }
 904                memcpy(buff, hns_nic_test_strs[MAC_INTERNALLOOP_SERDES],
 905                       ETH_GSTRING_LEN);
 906                buff += ETH_GSTRING_LEN;
 907                if ((priv->phy) && (!priv->phy->is_c45))
 908                        memcpy(buff, hns_nic_test_strs[MAC_INTERNALLOOP_PHY],
 909                               ETH_GSTRING_LEN);
 910
 911        } else {
 912                snprintf(buff, ETH_GSTRING_LEN, "rx_packets");
 913                buff = buff + ETH_GSTRING_LEN;
 914                snprintf(buff, ETH_GSTRING_LEN, "tx_packets");
 915                buff = buff + ETH_GSTRING_LEN;
 916                snprintf(buff, ETH_GSTRING_LEN, "rx_bytes");
 917                buff = buff + ETH_GSTRING_LEN;
 918                snprintf(buff, ETH_GSTRING_LEN, "tx_bytes");
 919                buff = buff + ETH_GSTRING_LEN;
 920                snprintf(buff, ETH_GSTRING_LEN, "rx_errors");
 921                buff = buff + ETH_GSTRING_LEN;
 922                snprintf(buff, ETH_GSTRING_LEN, "tx_errors");
 923                buff = buff + ETH_GSTRING_LEN;
 924                snprintf(buff, ETH_GSTRING_LEN, "rx_dropped");
 925                buff = buff + ETH_GSTRING_LEN;
 926                snprintf(buff, ETH_GSTRING_LEN, "tx_dropped");
 927                buff = buff + ETH_GSTRING_LEN;
 928                snprintf(buff, ETH_GSTRING_LEN, "multicast");
 929                buff = buff + ETH_GSTRING_LEN;
 930                snprintf(buff, ETH_GSTRING_LEN, "collisions");
 931                buff = buff + ETH_GSTRING_LEN;
 932                snprintf(buff, ETH_GSTRING_LEN, "rx_over_errors");
 933                buff = buff + ETH_GSTRING_LEN;
 934                snprintf(buff, ETH_GSTRING_LEN, "rx_crc_errors");
 935                buff = buff + ETH_GSTRING_LEN;
 936                snprintf(buff, ETH_GSTRING_LEN, "rx_frame_errors");
 937                buff = buff + ETH_GSTRING_LEN;
 938                snprintf(buff, ETH_GSTRING_LEN, "rx_fifo_errors");
 939                buff = buff + ETH_GSTRING_LEN;
 940                snprintf(buff, ETH_GSTRING_LEN, "rx_missed_errors");
 941                buff = buff + ETH_GSTRING_LEN;
 942                snprintf(buff, ETH_GSTRING_LEN, "tx_aborted_errors");
 943                buff = buff + ETH_GSTRING_LEN;
 944                snprintf(buff, ETH_GSTRING_LEN, "tx_carrier_errors");
 945                buff = buff + ETH_GSTRING_LEN;
 946                snprintf(buff, ETH_GSTRING_LEN, "tx_fifo_errors");
 947                buff = buff + ETH_GSTRING_LEN;
 948                snprintf(buff, ETH_GSTRING_LEN, "tx_heartbeat_errors");
 949                buff = buff + ETH_GSTRING_LEN;
 950                snprintf(buff, ETH_GSTRING_LEN, "rx_length_errors");
 951                buff = buff + ETH_GSTRING_LEN;
 952                snprintf(buff, ETH_GSTRING_LEN, "tx_window_errors");
 953                buff = buff + ETH_GSTRING_LEN;
 954                snprintf(buff, ETH_GSTRING_LEN, "rx_compressed");
 955                buff = buff + ETH_GSTRING_LEN;
 956                snprintf(buff, ETH_GSTRING_LEN, "tx_compressed");
 957                buff = buff + ETH_GSTRING_LEN;
 958                snprintf(buff, ETH_GSTRING_LEN, "netdev_rx_dropped");
 959                buff = buff + ETH_GSTRING_LEN;
 960                snprintf(buff, ETH_GSTRING_LEN, "netdev_tx_dropped");
 961                buff = buff + ETH_GSTRING_LEN;
 962
 963                snprintf(buff, ETH_GSTRING_LEN, "netdev_tx_timeout");
 964                buff = buff + ETH_GSTRING_LEN;
 965
 966                h->dev->ops->get_strings(h, stringset, (u8 *)buff);
 967        }
 968}
 969
 970/**
 971 * nic_get_sset_count - get string set count witch returned by nic_get_strings.
 972 * @dev: net device
 973 * @stringset: string set index, 0: self test string; 1: statistics string.
 974 *
 975 * Return string set count.
 976 */
 977int hns_get_sset_count(struct net_device *netdev, int stringset)
 978{
 979        struct hns_nic_priv *priv = netdev_priv(netdev);
 980        struct hnae_handle *h = priv->ae_handle;
 981        struct hnae_ae_ops *ops = h->dev->ops;
 982
 983        if (!ops->get_sset_count) {
 984                netdev_err(netdev, "get_sset_count is null!\n");
 985                return -EOPNOTSUPP;
 986        }
 987        if (stringset == ETH_SS_TEST) {
 988                u32 cnt = (sizeof(hns_nic_test_strs) / ETH_GSTRING_LEN);
 989
 990                if (priv->ae_handle->phy_if == PHY_INTERFACE_MODE_XGMII)
 991                        cnt--;
 992
 993                if ((!priv->phy) || (priv->phy->is_c45))
 994                        cnt--;
 995
 996                return cnt;
 997        } else {
 998                return (HNS_NET_STATS_CNT + ops->get_sset_count(h, stringset));
 999        }
1000}
1001
1002/**
1003 * hns_phy_led_set - set phy LED status.
1004 * @dev: net device
1005 * @value: LED state.
1006 *
1007 * Return 0 on success, negative on failure.
1008 */
1009int hns_phy_led_set(struct net_device *netdev, int value)
1010{
1011        int retval;
1012        struct hns_nic_priv *priv = netdev_priv(netdev);
1013        struct phy_device *phy_dev = priv->phy;
1014
1015        retval = phy_write(phy_dev, HNS_PHY_PAGE_REG, HNS_PHY_PAGE_LED);
1016        retval = phy_write(phy_dev, HNS_LED_FC_REG, value);
1017        retval = phy_write(phy_dev, HNS_PHY_PAGE_REG, HNS_PHY_PAGE_COPPER);
1018        if (retval) {
1019                netdev_err(netdev, "mdiobus_write fail !\n");
1020                return retval;
1021        }
1022        return 0;
1023}
1024
1025/**
1026 * nic_set_phys_id - set phy identify LED.
1027 * @dev: net device
1028 * @state: LED state.
1029 *
1030 * Return 0 on success, negative on failure.
1031 */
1032int hns_set_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state)
1033{
1034        struct hns_nic_priv *priv = netdev_priv(netdev);
1035        struct hnae_handle *h = priv->ae_handle;
1036        struct phy_device *phy_dev = priv->phy;
1037        int ret;
1038
1039        if (phy_dev)
1040                switch (state) {
1041                case ETHTOOL_ID_ACTIVE:
1042                        ret = phy_write(phy_dev, HNS_PHY_PAGE_REG,
1043                                        HNS_PHY_PAGE_LED);
1044                        if (ret)
1045                                return ret;
1046
1047                        priv->phy_led_val = phy_read(phy_dev, HNS_LED_FC_REG);
1048
1049                        ret = phy_write(phy_dev, HNS_PHY_PAGE_REG,
1050                                        HNS_PHY_PAGE_COPPER);
1051                        if (ret)
1052                                return ret;
1053                        return 2;
1054                case ETHTOOL_ID_ON:
1055                        ret = hns_phy_led_set(netdev, HNS_LED_FORCE_ON);
1056                        if (ret)
1057                                return ret;
1058                        break;
1059                case ETHTOOL_ID_OFF:
1060                        ret = hns_phy_led_set(netdev, HNS_LED_FORCE_OFF);
1061                        if (ret)
1062                                return ret;
1063                        break;
1064                case ETHTOOL_ID_INACTIVE:
1065                        ret = phy_write(phy_dev, HNS_PHY_PAGE_REG,
1066                                        HNS_PHY_PAGE_LED);
1067                        if (ret)
1068                                return ret;
1069
1070                        ret = phy_write(phy_dev, HNS_LED_FC_REG,
1071                                        priv->phy_led_val);
1072                        if (ret)
1073                                return ret;
1074
1075                        ret = phy_write(phy_dev, HNS_PHY_PAGE_REG,
1076                                        HNS_PHY_PAGE_COPPER);
1077                        if (ret)
1078                                return ret;
1079                        break;
1080                default:
1081                        return -EINVAL;
1082                }
1083        else
1084                switch (state) {
1085                case ETHTOOL_ID_ACTIVE:
1086                        return h->dev->ops->set_led_id(h, HNAE_LED_ACTIVE);
1087                case ETHTOOL_ID_ON:
1088                        return h->dev->ops->set_led_id(h, HNAE_LED_ON);
1089                case ETHTOOL_ID_OFF:
1090                        return h->dev->ops->set_led_id(h, HNAE_LED_OFF);
1091                case ETHTOOL_ID_INACTIVE:
1092                        return h->dev->ops->set_led_id(h, HNAE_LED_INACTIVE);
1093                default:
1094                        return -EINVAL;
1095                }
1096
1097        return 0;
1098}
1099
1100/**
1101 * hns_get_regs - get net device register
1102 * @dev: net device
1103 * @cmd: ethtool cmd
1104 * @date: register data
1105 */
1106void hns_get_regs(struct net_device *net_dev, struct ethtool_regs *cmd,
1107                  void *data)
1108{
1109        struct hns_nic_priv *priv = netdev_priv(net_dev);
1110        struct hnae_ae_ops *ops;
1111
1112        assert(priv || priv->ae_handle);
1113
1114        ops = priv->ae_handle->dev->ops;
1115
1116        cmd->version = HNS_CHIP_VERSION;
1117        if (!ops->get_regs) {
1118                netdev_err(net_dev, "ops->get_regs is null!\n");
1119                return;
1120        }
1121        ops->get_regs(priv->ae_handle, data);
1122}
1123
1124/**
1125 * nic_get_regs_len - get total register len.
1126 * @dev: net device
1127 *
1128 * Return total register len.
1129 */
1130static int hns_get_regs_len(struct net_device *net_dev)
1131{
1132        u32 reg_num;
1133        struct hns_nic_priv *priv = netdev_priv(net_dev);
1134        struct hnae_ae_ops *ops;
1135
1136        assert(priv || priv->ae_handle);
1137
1138        ops = priv->ae_handle->dev->ops;
1139        if (!ops->get_regs_len) {
1140                netdev_err(net_dev, "ops->get_regs_len is null!\n");
1141                return -EOPNOTSUPP;
1142        }
1143
1144        reg_num = ops->get_regs_len(priv->ae_handle);
1145        if (reg_num > 0)
1146                return reg_num * sizeof(u32);
1147        else
1148                return reg_num; /* error code */
1149}
1150
1151/**
1152 * hns_nic_nway_reset - nway reset
1153 * @dev: net device
1154 *
1155 * Return 0 on success, negative on failure
1156 */
1157static int hns_nic_nway_reset(struct net_device *netdev)
1158{
1159        int ret = 0;
1160        struct hns_nic_priv *priv = netdev_priv(netdev);
1161        struct phy_device *phy = priv->phy;
1162
1163        if (netif_running(netdev)) {
1164                if (phy)
1165                        ret = genphy_restart_aneg(phy);
1166        }
1167
1168        return ret;
1169}
1170
1171static u32
1172hns_get_rss_key_size(struct net_device *netdev)
1173{
1174        struct hns_nic_priv *priv = netdev_priv(netdev);
1175        struct hnae_ae_ops *ops;
1176        u32 ret;
1177
1178        if (AE_IS_VER1(priv->enet_ver)) {
1179                netdev_err(netdev,
1180                           "RSS feature is not supported on this hardware\n");
1181                return -EOPNOTSUPP;
1182        }
1183
1184        ops = priv->ae_handle->dev->ops;
1185        ret = ops->get_rss_key_size(priv->ae_handle);
1186
1187        return ret;
1188}
1189
1190static u32
1191hns_get_rss_indir_size(struct net_device *netdev)
1192{
1193        struct hns_nic_priv *priv = netdev_priv(netdev);
1194        struct hnae_ae_ops *ops;
1195        u32 ret;
1196
1197        if (AE_IS_VER1(priv->enet_ver)) {
1198                netdev_err(netdev,
1199                           "RSS feature is not supported on this hardware\n");
1200                return -EOPNOTSUPP;
1201        }
1202
1203        ops = priv->ae_handle->dev->ops;
1204        ret = ops->get_rss_indir_size(priv->ae_handle);
1205
1206        return ret;
1207}
1208
1209static int
1210hns_get_rss(struct net_device *netdev, u32 *indir, u8 *key, u8 *hfunc)
1211{
1212        struct hns_nic_priv *priv = netdev_priv(netdev);
1213        struct hnae_ae_ops *ops;
1214        int ret;
1215
1216        if (AE_IS_VER1(priv->enet_ver)) {
1217                netdev_err(netdev,
1218                           "RSS feature is not supported on this hardware\n");
1219                return -EOPNOTSUPP;
1220        }
1221
1222        ops = priv->ae_handle->dev->ops;
1223
1224        if (!indir)
1225                return 0;
1226
1227        ret = ops->get_rss(priv->ae_handle, indir, key, hfunc);
1228
1229        return 0;
1230}
1231
1232static int
1233hns_set_rss(struct net_device *netdev, const u32 *indir, const u8 *key,
1234            const u8 hfunc)
1235{
1236        struct hns_nic_priv *priv = netdev_priv(netdev);
1237        struct hnae_ae_ops *ops;
1238        int ret;
1239
1240        if (AE_IS_VER1(priv->enet_ver)) {
1241                netdev_err(netdev,
1242                           "RSS feature is not supported on this hardware\n");
1243                return -EOPNOTSUPP;
1244        }
1245
1246        ops = priv->ae_handle->dev->ops;
1247
1248        /* currently hfunc can only be Toeplitz hash */
1249        if (key ||
1250            (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP))
1251                return -EOPNOTSUPP;
1252        if (!indir)
1253                return 0;
1254
1255        ret = ops->set_rss(priv->ae_handle, indir, key, hfunc);
1256
1257        return 0;
1258}
1259
1260static struct ethtool_ops hns_ethtool_ops = {
1261        .get_drvinfo = hns_nic_get_drvinfo,
1262        .get_link  = hns_nic_get_link,
1263        .get_settings  = hns_nic_get_settings,
1264        .set_settings  = hns_nic_set_settings,
1265        .get_ringparam = hns_get_ringparam,
1266        .get_pauseparam = hns_get_pauseparam,
1267        .set_pauseparam = hns_set_pauseparam,
1268        .get_coalesce = hns_get_coalesce,
1269        .set_coalesce = hns_set_coalesce,
1270        .get_channels = hns_get_channels,
1271        .self_test = hns_nic_self_test,
1272        .get_strings = hns_get_strings,
1273        .get_sset_count = hns_get_sset_count,
1274        .get_ethtool_stats = hns_get_ethtool_stats,
1275        .set_phys_id = hns_set_phys_id,
1276        .get_regs_len = hns_get_regs_len,
1277        .get_regs = hns_get_regs,
1278        .nway_reset = hns_nic_nway_reset,
1279        .get_rxfh_key_size = hns_get_rss_key_size,
1280        .get_rxfh_indir_size = hns_get_rss_indir_size,
1281        .get_rxfh = hns_get_rss,
1282        .set_rxfh = hns_set_rss,
1283};
1284
1285void hns_ethtool_set_ops(struct net_device *ndev)
1286{
1287        ndev->ethtool_ops = &hns_ethtool_ops;
1288}
1289