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