linux/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2// Copyright (c) 2016-2017 Hisilicon Limited.
   3
   4#include <linux/etherdevice.h>
   5#include <linux/string.h>
   6#include <linux/phy.h>
   7
   8#include "hns3_enet.h"
   9
  10struct hns3_stats {
  11        char stats_string[ETH_GSTRING_LEN];
  12        int stats_offset;
  13};
  14
  15/* tqp related stats */
  16#define HNS3_TQP_STAT(_string, _member) {                       \
  17        .stats_string = _string,                                \
  18        .stats_offset = offsetof(struct hns3_enet_ring, stats) +\
  19                        offsetof(struct ring_stats, _member),   \
  20}
  21
  22static const struct hns3_stats hns3_txq_stats[] = {
  23        /* Tx per-queue statistics */
  24        HNS3_TQP_STAT("io_err_cnt", io_err_cnt),
  25        HNS3_TQP_STAT("dropped", sw_err_cnt),
  26        HNS3_TQP_STAT("seg_pkt_cnt", seg_pkt_cnt),
  27        HNS3_TQP_STAT("packets", tx_pkts),
  28        HNS3_TQP_STAT("bytes", tx_bytes),
  29        HNS3_TQP_STAT("errors", tx_err_cnt),
  30        HNS3_TQP_STAT("wake", restart_queue),
  31        HNS3_TQP_STAT("busy", tx_busy),
  32        HNS3_TQP_STAT("copy", tx_copy),
  33};
  34
  35#define HNS3_TXQ_STATS_COUNT ARRAY_SIZE(hns3_txq_stats)
  36
  37static const struct hns3_stats hns3_rxq_stats[] = {
  38        /* Rx per-queue statistics */
  39        HNS3_TQP_STAT("io_err_cnt", io_err_cnt),
  40        HNS3_TQP_STAT("dropped", sw_err_cnt),
  41        HNS3_TQP_STAT("seg_pkt_cnt", seg_pkt_cnt),
  42        HNS3_TQP_STAT("packets", rx_pkts),
  43        HNS3_TQP_STAT("bytes", rx_bytes),
  44        HNS3_TQP_STAT("errors", rx_err_cnt),
  45        HNS3_TQP_STAT("reuse_pg_cnt", reuse_pg_cnt),
  46        HNS3_TQP_STAT("err_pkt_len", err_pkt_len),
  47        HNS3_TQP_STAT("err_bd_num", err_bd_num),
  48        HNS3_TQP_STAT("l2_err", l2_err),
  49        HNS3_TQP_STAT("l3l4_csum_err", l3l4_csum_err),
  50        HNS3_TQP_STAT("multicast", rx_multicast),
  51        HNS3_TQP_STAT("non_reuse_pg", non_reuse_pg),
  52};
  53
  54#define HNS3_RXQ_STATS_COUNT ARRAY_SIZE(hns3_rxq_stats)
  55
  56#define HNS3_TQP_STATS_COUNT (HNS3_TXQ_STATS_COUNT + HNS3_RXQ_STATS_COUNT)
  57
  58#define HNS3_SELF_TEST_TYPE_NUM         3
  59#define HNS3_NIC_LB_TEST_PKT_NUM        1
  60#define HNS3_NIC_LB_TEST_RING_ID        0
  61#define HNS3_NIC_LB_TEST_PACKET_SIZE    128
  62#define HNS3_NIC_LB_SETUP_USEC          10000
  63
  64/* Nic loopback test err  */
  65#define HNS3_NIC_LB_TEST_NO_MEM_ERR     1
  66#define HNS3_NIC_LB_TEST_TX_CNT_ERR     2
  67#define HNS3_NIC_LB_TEST_RX_CNT_ERR     3
  68
  69struct hns3_link_mode_mapping {
  70        u32 hns3_link_mode;
  71        u32 ethtool_link_mode;
  72};
  73
  74static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en)
  75{
  76        struct hnae3_handle *h = hns3_get_handle(ndev);
  77        bool vlan_filter_enable;
  78        int ret;
  79
  80        if (!h->ae_algo->ops->set_loopback ||
  81            !h->ae_algo->ops->set_promisc_mode)
  82                return -EOPNOTSUPP;
  83
  84        switch (loop) {
  85        case HNAE3_LOOP_SERIAL_SERDES:
  86        case HNAE3_LOOP_PARALLEL_SERDES:
  87        case HNAE3_LOOP_APP:
  88                ret = h->ae_algo->ops->set_loopback(h, loop, en);
  89                break;
  90        default:
  91                ret = -ENOTSUPP;
  92                break;
  93        }
  94
  95        if (ret)
  96                return ret;
  97
  98        if (en) {
  99                h->ae_algo->ops->set_promisc_mode(h, true, true);
 100        } else {
 101                /* recover promisc mode before loopback test */
 102                hns3_update_promisc_mode(ndev, h->netdev_flags);
 103                vlan_filter_enable = ndev->flags & IFF_PROMISC ? false : true;
 104                hns3_enable_vlan_filter(ndev, vlan_filter_enable);
 105        }
 106
 107        return ret;
 108}
 109
 110static int hns3_lp_up(struct net_device *ndev, enum hnae3_loop loop_mode)
 111{
 112        struct hnae3_handle *h = hns3_get_handle(ndev);
 113        int ret;
 114
 115        ret = hns3_nic_reset_all_ring(h);
 116        if (ret)
 117                return ret;
 118
 119        ret = hns3_lp_setup(ndev, loop_mode, true);
 120        usleep_range(HNS3_NIC_LB_SETUP_USEC, HNS3_NIC_LB_SETUP_USEC * 2);
 121
 122        return ret;
 123}
 124
 125static int hns3_lp_down(struct net_device *ndev, enum hnae3_loop loop_mode)
 126{
 127        int ret;
 128
 129        ret = hns3_lp_setup(ndev, loop_mode, false);
 130        if (ret) {
 131                netdev_err(ndev, "lb_setup return error: %d\n", ret);
 132                return ret;
 133        }
 134
 135        usleep_range(HNS3_NIC_LB_SETUP_USEC, HNS3_NIC_LB_SETUP_USEC * 2);
 136
 137        return 0;
 138}
 139
 140static void hns3_lp_setup_skb(struct sk_buff *skb)
 141{
 142        struct net_device *ndev = skb->dev;
 143        unsigned char *packet;
 144        struct ethhdr *ethh;
 145        unsigned int i;
 146
 147        skb_reserve(skb, NET_IP_ALIGN);
 148        ethh = skb_put(skb, sizeof(struct ethhdr));
 149        packet = skb_put(skb, HNS3_NIC_LB_TEST_PACKET_SIZE);
 150
 151        memcpy(ethh->h_dest, ndev->dev_addr, ETH_ALEN);
 152
 153        /* The dst mac addr of loopback packet is the same as the host'
 154         * mac addr, the SSU component may loop back the packet to host
 155         * before the packet reaches mac or serdes, which will defect
 156         * the purpose of mac or serdes selftest.
 157         */
 158        ethh->h_dest[5] += 0x1f;
 159        eth_zero_addr(ethh->h_source);
 160        ethh->h_proto = htons(ETH_P_ARP);
 161        skb_reset_mac_header(skb);
 162
 163        for (i = 0; i < HNS3_NIC_LB_TEST_PACKET_SIZE; i++)
 164                packet[i] = (unsigned char)(i & 0xff);
 165}
 166
 167static void hns3_lb_check_skb_data(struct hns3_enet_ring *ring,
 168                                   struct sk_buff *skb)
 169{
 170        struct hns3_enet_tqp_vector *tqp_vector = ring->tqp_vector;
 171        unsigned char *packet = skb->data;
 172        u32 i;
 173
 174        for (i = 0; i < skb->len; i++)
 175                if (packet[i] != (unsigned char)(i & 0xff))
 176                        break;
 177
 178        /* The packet is correctly received */
 179        if (i == skb->len)
 180                tqp_vector->rx_group.total_packets++;
 181        else
 182                print_hex_dump(KERN_ERR, "selftest:", DUMP_PREFIX_OFFSET, 16, 1,
 183                               skb->data, skb->len, true);
 184
 185        dev_kfree_skb_any(skb);
 186}
 187
 188static u32 hns3_lb_check_rx_ring(struct hns3_nic_priv *priv, u32 budget)
 189{
 190        struct hnae3_handle *h = priv->ae_handle;
 191        struct hnae3_knic_private_info *kinfo;
 192        u32 i, rcv_good_pkt_total = 0;
 193
 194        kinfo = &h->kinfo;
 195        for (i = kinfo->num_tqps; i < kinfo->num_tqps * 2; i++) {
 196                struct hns3_enet_ring *ring = priv->ring_data[i].ring;
 197                struct hns3_enet_ring_group *rx_group;
 198                u64 pre_rx_pkt;
 199
 200                rx_group = &ring->tqp_vector->rx_group;
 201                pre_rx_pkt = rx_group->total_packets;
 202
 203                preempt_disable();
 204                hns3_clean_rx_ring(ring, budget, hns3_lb_check_skb_data);
 205                preempt_enable();
 206
 207                rcv_good_pkt_total += (rx_group->total_packets - pre_rx_pkt);
 208                rx_group->total_packets = pre_rx_pkt;
 209        }
 210        return rcv_good_pkt_total;
 211}
 212
 213static void hns3_lb_clear_tx_ring(struct hns3_nic_priv *priv, u32 start_ringid,
 214                                  u32 end_ringid, u32 budget)
 215{
 216        u32 i;
 217
 218        for (i = start_ringid; i <= end_ringid; i++) {
 219                struct hns3_enet_ring *ring = priv->ring_data[i].ring;
 220
 221                hns3_clean_tx_ring(ring);
 222        }
 223}
 224
 225/**
 226 * hns3_lp_run_test -  run loopback test
 227 * @ndev: net device
 228 * @mode: loopback type
 229 */
 230static int hns3_lp_run_test(struct net_device *ndev, enum hnae3_loop mode)
 231{
 232        struct hns3_nic_priv *priv = netdev_priv(ndev);
 233        struct sk_buff *skb;
 234        u32 i, good_cnt;
 235        int ret_val = 0;
 236
 237        skb = alloc_skb(HNS3_NIC_LB_TEST_PACKET_SIZE + ETH_HLEN + NET_IP_ALIGN,
 238                        GFP_KERNEL);
 239        if (!skb)
 240                return HNS3_NIC_LB_TEST_NO_MEM_ERR;
 241
 242        skb->dev = ndev;
 243        hns3_lp_setup_skb(skb);
 244        skb->queue_mapping = HNS3_NIC_LB_TEST_RING_ID;
 245
 246        good_cnt = 0;
 247        for (i = 0; i < HNS3_NIC_LB_TEST_PKT_NUM; i++) {
 248                netdev_tx_t tx_ret;
 249
 250                skb_get(skb);
 251                tx_ret = hns3_nic_net_xmit(skb, ndev);
 252                if (tx_ret == NETDEV_TX_OK) {
 253                        good_cnt++;
 254                } else {
 255                        kfree_skb(skb);
 256                        netdev_err(ndev, "hns3_lb_run_test xmit failed: %d\n",
 257                                   tx_ret);
 258                }
 259        }
 260        if (good_cnt != HNS3_NIC_LB_TEST_PKT_NUM) {
 261                ret_val = HNS3_NIC_LB_TEST_TX_CNT_ERR;
 262                netdev_err(ndev, "mode %d sent fail, cnt=0x%x, budget=0x%x\n",
 263                           mode, good_cnt, HNS3_NIC_LB_TEST_PKT_NUM);
 264                goto out;
 265        }
 266
 267        /* Allow 200 milliseconds for packets to go from Tx to Rx */
 268        msleep(200);
 269
 270        good_cnt = hns3_lb_check_rx_ring(priv, HNS3_NIC_LB_TEST_PKT_NUM);
 271        if (good_cnt != HNS3_NIC_LB_TEST_PKT_NUM) {
 272                ret_val = HNS3_NIC_LB_TEST_RX_CNT_ERR;
 273                netdev_err(ndev, "mode %d recv fail, cnt=0x%x, budget=0x%x\n",
 274                           mode, good_cnt, HNS3_NIC_LB_TEST_PKT_NUM);
 275        }
 276
 277out:
 278        hns3_lb_clear_tx_ring(priv, HNS3_NIC_LB_TEST_RING_ID,
 279                              HNS3_NIC_LB_TEST_RING_ID,
 280                              HNS3_NIC_LB_TEST_PKT_NUM);
 281
 282        kfree_skb(skb);
 283        return ret_val;
 284}
 285
 286/**
 287 * hns3_nic_self_test - self test
 288 * @ndev: net device
 289 * @eth_test: test cmd
 290 * @data: test result
 291 */
 292static void hns3_self_test(struct net_device *ndev,
 293                           struct ethtool_test *eth_test, u64 *data)
 294{
 295        struct hns3_nic_priv *priv = netdev_priv(ndev);
 296        struct hnae3_handle *h = priv->ae_handle;
 297        int st_param[HNS3_SELF_TEST_TYPE_NUM][2];
 298        bool if_running = netif_running(ndev);
 299#if IS_ENABLED(CONFIG_VLAN_8021Q)
 300        bool dis_vlan_filter;
 301#endif
 302        int test_index = 0;
 303        u32 i;
 304
 305        if (hns3_nic_resetting(ndev)) {
 306                netdev_err(ndev, "dev resetting!");
 307                return;
 308        }
 309
 310        /* Only do offline selftest, or pass by default */
 311        if (eth_test->flags != ETH_TEST_FL_OFFLINE)
 312                return;
 313
 314        st_param[HNAE3_LOOP_APP][0] = HNAE3_LOOP_APP;
 315        st_param[HNAE3_LOOP_APP][1] =
 316                        h->flags & HNAE3_SUPPORT_APP_LOOPBACK;
 317
 318        st_param[HNAE3_LOOP_SERIAL_SERDES][0] = HNAE3_LOOP_SERIAL_SERDES;
 319        st_param[HNAE3_LOOP_SERIAL_SERDES][1] =
 320                        h->flags & HNAE3_SUPPORT_SERDES_SERIAL_LOOPBACK;
 321
 322        st_param[HNAE3_LOOP_PARALLEL_SERDES][0] =
 323                        HNAE3_LOOP_PARALLEL_SERDES;
 324        st_param[HNAE3_LOOP_PARALLEL_SERDES][1] =
 325                        h->flags & HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK;
 326
 327        if (if_running)
 328                ndev->netdev_ops->ndo_stop(ndev);
 329
 330#if IS_ENABLED(CONFIG_VLAN_8021Q)
 331        /* Disable the vlan filter for selftest does not support it */
 332        dis_vlan_filter = (ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) &&
 333                                h->ae_algo->ops->enable_vlan_filter;
 334        if (dis_vlan_filter)
 335                h->ae_algo->ops->enable_vlan_filter(h, false);
 336#endif
 337
 338        /* Tell firmware to stop mac autoneg before loopback test start,
 339         * otherwise loopback test may be failed when the port is still
 340         * negotiating.
 341         */
 342        if (h->ae_algo->ops->halt_autoneg)
 343                h->ae_algo->ops->halt_autoneg(h, true);
 344
 345        set_bit(HNS3_NIC_STATE_TESTING, &priv->state);
 346
 347        for (i = 0; i < HNS3_SELF_TEST_TYPE_NUM; i++) {
 348                enum hnae3_loop loop_type = (enum hnae3_loop)st_param[i][0];
 349
 350                if (!st_param[i][1])
 351                        continue;
 352
 353                data[test_index] = hns3_lp_up(ndev, loop_type);
 354                if (!data[test_index])
 355                        data[test_index] = hns3_lp_run_test(ndev, loop_type);
 356
 357                hns3_lp_down(ndev, loop_type);
 358
 359                if (data[test_index])
 360                        eth_test->flags |= ETH_TEST_FL_FAILED;
 361
 362                test_index++;
 363        }
 364
 365        clear_bit(HNS3_NIC_STATE_TESTING, &priv->state);
 366
 367        if (h->ae_algo->ops->halt_autoneg)
 368                h->ae_algo->ops->halt_autoneg(h, false);
 369
 370#if IS_ENABLED(CONFIG_VLAN_8021Q)
 371        if (dis_vlan_filter)
 372                h->ae_algo->ops->enable_vlan_filter(h, true);
 373#endif
 374
 375        if (if_running)
 376                ndev->netdev_ops->ndo_open(ndev);
 377}
 378
 379static int hns3_get_sset_count(struct net_device *netdev, int stringset)
 380{
 381        struct hnae3_handle *h = hns3_get_handle(netdev);
 382        const struct hnae3_ae_ops *ops = h->ae_algo->ops;
 383
 384        if (!ops->get_sset_count)
 385                return -EOPNOTSUPP;
 386
 387        switch (stringset) {
 388        case ETH_SS_STATS:
 389                return ((HNS3_TQP_STATS_COUNT * h->kinfo.num_tqps) +
 390                        ops->get_sset_count(h, stringset));
 391
 392        case ETH_SS_TEST:
 393                return ops->get_sset_count(h, stringset);
 394
 395        default:
 396                return -EOPNOTSUPP;
 397        }
 398}
 399
 400static void *hns3_update_strings(u8 *data, const struct hns3_stats *stats,
 401                u32 stat_count, u32 num_tqps, const char *prefix)
 402{
 403#define MAX_PREFIX_SIZE (6 + 4)
 404        u32 size_left;
 405        u32 i, j;
 406        u32 n1;
 407
 408        for (i = 0; i < num_tqps; i++) {
 409                for (j = 0; j < stat_count; j++) {
 410                        data[ETH_GSTRING_LEN - 1] = '\0';
 411
 412                        /* first, prepend the prefix string */
 413                        n1 = snprintf(data, MAX_PREFIX_SIZE, "%s%d_",
 414                                      prefix, i);
 415                        n1 = min_t(uint, n1, MAX_PREFIX_SIZE - 1);
 416                        size_left = (ETH_GSTRING_LEN - 1) - n1;
 417
 418                        /* now, concatenate the stats string to it */
 419                        strncat(data, stats[j].stats_string, size_left);
 420                        data += ETH_GSTRING_LEN;
 421                }
 422        }
 423
 424        return data;
 425}
 426
 427static u8 *hns3_get_strings_tqps(struct hnae3_handle *handle, u8 *data)
 428{
 429        struct hnae3_knic_private_info *kinfo = &handle->kinfo;
 430        const char tx_prefix[] = "txq";
 431        const char rx_prefix[] = "rxq";
 432
 433        /* get strings for Tx */
 434        data = hns3_update_strings(data, hns3_txq_stats, HNS3_TXQ_STATS_COUNT,
 435                                   kinfo->num_tqps, tx_prefix);
 436
 437        /* get strings for Rx */
 438        data = hns3_update_strings(data, hns3_rxq_stats, HNS3_RXQ_STATS_COUNT,
 439                                   kinfo->num_tqps, rx_prefix);
 440
 441        return data;
 442}
 443
 444static void hns3_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
 445{
 446        struct hnae3_handle *h = hns3_get_handle(netdev);
 447        const struct hnae3_ae_ops *ops = h->ae_algo->ops;
 448        char *buff = (char *)data;
 449
 450        if (!ops->get_strings)
 451                return;
 452
 453        switch (stringset) {
 454        case ETH_SS_STATS:
 455                buff = hns3_get_strings_tqps(h, buff);
 456                ops->get_strings(h, stringset, (u8 *)buff);
 457                break;
 458        case ETH_SS_TEST:
 459                ops->get_strings(h, stringset, data);
 460                break;
 461        default:
 462                break;
 463        }
 464}
 465
 466static u64 *hns3_get_stats_tqps(struct hnae3_handle *handle, u64 *data)
 467{
 468        struct hns3_nic_priv *nic_priv = (struct hns3_nic_priv *)handle->priv;
 469        struct hnae3_knic_private_info *kinfo = &handle->kinfo;
 470        struct hns3_enet_ring *ring;
 471        u8 *stat;
 472        int i, j;
 473
 474        /* get stats for Tx */
 475        for (i = 0; i < kinfo->num_tqps; i++) {
 476                ring = nic_priv->ring_data[i].ring;
 477                for (j = 0; j < HNS3_TXQ_STATS_COUNT; j++) {
 478                        stat = (u8 *)ring + hns3_txq_stats[j].stats_offset;
 479                        *data++ = *(u64 *)stat;
 480                }
 481        }
 482
 483        /* get stats for Rx */
 484        for (i = 0; i < kinfo->num_tqps; i++) {
 485                ring = nic_priv->ring_data[i + kinfo->num_tqps].ring;
 486                for (j = 0; j < HNS3_RXQ_STATS_COUNT; j++) {
 487                        stat = (u8 *)ring + hns3_rxq_stats[j].stats_offset;
 488                        *data++ = *(u64 *)stat;
 489                }
 490        }
 491
 492        return data;
 493}
 494
 495/* hns3_get_stats - get detail statistics.
 496 * @netdev: net device
 497 * @stats: statistics info.
 498 * @data: statistics data.
 499 */
 500static void hns3_get_stats(struct net_device *netdev,
 501                           struct ethtool_stats *stats, u64 *data)
 502{
 503        struct hnae3_handle *h = hns3_get_handle(netdev);
 504        u64 *p = data;
 505
 506        if (hns3_nic_resetting(netdev)) {
 507                netdev_err(netdev, "dev resetting, could not get stats\n");
 508                return;
 509        }
 510
 511        if (!h->ae_algo->ops->get_stats || !h->ae_algo->ops->update_stats) {
 512                netdev_err(netdev, "could not get any statistics\n");
 513                return;
 514        }
 515
 516        h->ae_algo->ops->update_stats(h, &netdev->stats);
 517
 518        /* get per-queue stats */
 519        p = hns3_get_stats_tqps(h, p);
 520
 521        /* get MAC & other misc hardware stats */
 522        h->ae_algo->ops->get_stats(h, p);
 523}
 524
 525static void hns3_get_drvinfo(struct net_device *netdev,
 526                             struct ethtool_drvinfo *drvinfo)
 527{
 528        struct hns3_nic_priv *priv = netdev_priv(netdev);
 529        struct hnae3_handle *h = priv->ae_handle;
 530
 531        if (!h->ae_algo->ops->get_fw_version) {
 532                netdev_err(netdev, "could not get fw version!\n");
 533                return;
 534        }
 535
 536        strncpy(drvinfo->version, hns3_driver_version,
 537                sizeof(drvinfo->version));
 538        drvinfo->version[sizeof(drvinfo->version) - 1] = '\0';
 539
 540        strncpy(drvinfo->driver, h->pdev->driver->name,
 541                sizeof(drvinfo->driver));
 542        drvinfo->driver[sizeof(drvinfo->driver) - 1] = '\0';
 543
 544        strncpy(drvinfo->bus_info, pci_name(h->pdev),
 545                sizeof(drvinfo->bus_info));
 546        drvinfo->bus_info[ETHTOOL_BUSINFO_LEN - 1] = '\0';
 547
 548        snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), "0x%08x",
 549                 priv->ae_handle->ae_algo->ops->get_fw_version(h));
 550}
 551
 552static u32 hns3_get_link(struct net_device *netdev)
 553{
 554        struct hnae3_handle *h = hns3_get_handle(netdev);
 555
 556        if (h->ae_algo->ops->get_status)
 557                return h->ae_algo->ops->get_status(h);
 558        else
 559                return 0;
 560}
 561
 562static void hns3_get_ringparam(struct net_device *netdev,
 563                               struct ethtool_ringparam *param)
 564{
 565        struct hns3_nic_priv *priv = netdev_priv(netdev);
 566        struct hnae3_handle *h = priv->ae_handle;
 567        int queue_num = h->kinfo.num_tqps;
 568
 569        if (hns3_nic_resetting(netdev)) {
 570                netdev_err(netdev, "dev resetting!");
 571                return;
 572        }
 573
 574        param->tx_max_pending = HNS3_RING_MAX_PENDING;
 575        param->rx_max_pending = HNS3_RING_MAX_PENDING;
 576
 577        param->tx_pending = priv->ring_data[0].ring->desc_num;
 578        param->rx_pending = priv->ring_data[queue_num].ring->desc_num;
 579}
 580
 581static void hns3_get_pauseparam(struct net_device *netdev,
 582                                struct ethtool_pauseparam *param)
 583{
 584        struct hnae3_handle *h = hns3_get_handle(netdev);
 585
 586        if (h->ae_algo->ops->get_pauseparam)
 587                h->ae_algo->ops->get_pauseparam(h, &param->autoneg,
 588                        &param->rx_pause, &param->tx_pause);
 589}
 590
 591static int hns3_set_pauseparam(struct net_device *netdev,
 592                               struct ethtool_pauseparam *param)
 593{
 594        struct hnae3_handle *h = hns3_get_handle(netdev);
 595
 596        if (h->ae_algo->ops->set_pauseparam)
 597                return h->ae_algo->ops->set_pauseparam(h, param->autoneg,
 598                                                       param->rx_pause,
 599                                                       param->tx_pause);
 600        return -EOPNOTSUPP;
 601}
 602
 603static void hns3_get_ksettings(struct hnae3_handle *h,
 604                               struct ethtool_link_ksettings *cmd)
 605{
 606        const struct hnae3_ae_ops *ops = h->ae_algo->ops;
 607
 608        /* 1.auto_neg & speed & duplex from cmd */
 609        if (ops->get_ksettings_an_result)
 610                ops->get_ksettings_an_result(h,
 611                                             &cmd->base.autoneg,
 612                                             &cmd->base.speed,
 613                                             &cmd->base.duplex);
 614
 615        /* 2.get link mode*/
 616        if (ops->get_link_mode)
 617                ops->get_link_mode(h,
 618                                   cmd->link_modes.supported,
 619                                   cmd->link_modes.advertising);
 620
 621        /* 3.mdix_ctrl&mdix get from phy reg */
 622        if (ops->get_mdix_mode)
 623                ops->get_mdix_mode(h, &cmd->base.eth_tp_mdix_ctrl,
 624                                   &cmd->base.eth_tp_mdix);
 625}
 626
 627static int hns3_get_link_ksettings(struct net_device *netdev,
 628                                   struct ethtool_link_ksettings *cmd)
 629{
 630        struct hnae3_handle *h = hns3_get_handle(netdev);
 631        const struct hnae3_ae_ops *ops;
 632        u8 module_type;
 633        u8 media_type;
 634        u8 link_stat;
 635
 636        ops = h->ae_algo->ops;
 637        if (ops->get_media_type)
 638                ops->get_media_type(h, &media_type, &module_type);
 639        else
 640                return -EOPNOTSUPP;
 641
 642        switch (media_type) {
 643        case HNAE3_MEDIA_TYPE_NONE:
 644                cmd->base.port = PORT_NONE;
 645                hns3_get_ksettings(h, cmd);
 646                break;
 647        case HNAE3_MEDIA_TYPE_FIBER:
 648                if (module_type == HNAE3_MODULE_TYPE_CR)
 649                        cmd->base.port = PORT_DA;
 650                else
 651                        cmd->base.port = PORT_FIBRE;
 652
 653                hns3_get_ksettings(h, cmd);
 654                break;
 655        case HNAE3_MEDIA_TYPE_BACKPLANE:
 656                cmd->base.port = PORT_NONE;
 657                hns3_get_ksettings(h, cmd);
 658                break;
 659        case HNAE3_MEDIA_TYPE_COPPER:
 660                cmd->base.port = PORT_TP;
 661                if (!netdev->phydev)
 662                        hns3_get_ksettings(h, cmd);
 663                else
 664                        phy_ethtool_ksettings_get(netdev->phydev, cmd);
 665                break;
 666        default:
 667
 668                netdev_warn(netdev, "Unknown media type");
 669                return 0;
 670        }
 671
 672        /* mdio_support */
 673        cmd->base.mdio_support = ETH_MDIO_SUPPORTS_C22;
 674
 675        link_stat = hns3_get_link(netdev);
 676        if (!link_stat) {
 677                cmd->base.speed = SPEED_UNKNOWN;
 678                cmd->base.duplex = DUPLEX_UNKNOWN;
 679        }
 680
 681        return 0;
 682}
 683
 684static int hns3_check_ksettings_param(struct net_device *netdev,
 685                                      const struct ethtool_link_ksettings *cmd)
 686{
 687        struct hnae3_handle *handle = hns3_get_handle(netdev);
 688        const struct hnae3_ae_ops *ops = handle->ae_algo->ops;
 689        u8 module_type = HNAE3_MODULE_TYPE_UNKNOWN;
 690        u8 media_type = HNAE3_MEDIA_TYPE_UNKNOWN;
 691        u8 autoneg;
 692        u32 speed;
 693        u8 duplex;
 694        int ret;
 695
 696        if (ops->get_ksettings_an_result) {
 697                ops->get_ksettings_an_result(handle, &autoneg, &speed, &duplex);
 698                if (cmd->base.autoneg == autoneg && cmd->base.speed == speed &&
 699                    cmd->base.duplex == duplex)
 700                        return 0;
 701        }
 702
 703        if (ops->get_media_type)
 704                ops->get_media_type(handle, &media_type, &module_type);
 705
 706        if (cmd->base.duplex != DUPLEX_FULL &&
 707            media_type != HNAE3_MEDIA_TYPE_COPPER) {
 708                netdev_err(netdev,
 709                           "only copper port supports half duplex!");
 710                return -EINVAL;
 711        }
 712
 713        if (ops->check_port_speed) {
 714                ret = ops->check_port_speed(handle, cmd->base.speed);
 715                if (ret) {
 716                        netdev_err(netdev, "unsupported speed\n");
 717                        return ret;
 718                }
 719        }
 720
 721        return 0;
 722}
 723
 724static int hns3_set_link_ksettings(struct net_device *netdev,
 725                                   const struct ethtool_link_ksettings *cmd)
 726{
 727        struct hnae3_handle *handle = hns3_get_handle(netdev);
 728        const struct hnae3_ae_ops *ops = handle->ae_algo->ops;
 729        int ret = 0;
 730
 731        /* Chip don't support this mode. */
 732        if (cmd->base.speed == SPEED_1000 && cmd->base.duplex == DUPLEX_HALF)
 733                return -EINVAL;
 734
 735        /* Only support ksettings_set for netdev with phy attached for now */
 736        if (netdev->phydev)
 737                return phy_ethtool_ksettings_set(netdev->phydev, cmd);
 738
 739        if (handle->pdev->revision == 0x20)
 740                return -EOPNOTSUPP;
 741
 742        ret = hns3_check_ksettings_param(netdev, cmd);
 743        if (ret)
 744                return ret;
 745
 746        if (ops->set_autoneg) {
 747                ret = ops->set_autoneg(handle, cmd->base.autoneg);
 748                if (ret)
 749                        return ret;
 750        }
 751
 752        if (ops->cfg_mac_speed_dup_h)
 753                ret = ops->cfg_mac_speed_dup_h(handle, cmd->base.speed,
 754                                               cmd->base.duplex);
 755
 756        return ret;
 757}
 758
 759static u32 hns3_get_rss_key_size(struct net_device *netdev)
 760{
 761        struct hnae3_handle *h = hns3_get_handle(netdev);
 762
 763        if (!h->ae_algo->ops->get_rss_key_size)
 764                return 0;
 765
 766        return h->ae_algo->ops->get_rss_key_size(h);
 767}
 768
 769static u32 hns3_get_rss_indir_size(struct net_device *netdev)
 770{
 771        struct hnae3_handle *h = hns3_get_handle(netdev);
 772
 773        if (!h->ae_algo->ops->get_rss_indir_size)
 774                return 0;
 775
 776        return h->ae_algo->ops->get_rss_indir_size(h);
 777}
 778
 779static int hns3_get_rss(struct net_device *netdev, u32 *indir, u8 *key,
 780                        u8 *hfunc)
 781{
 782        struct hnae3_handle *h = hns3_get_handle(netdev);
 783
 784        if (!h->ae_algo->ops->get_rss)
 785                return -EOPNOTSUPP;
 786
 787        return h->ae_algo->ops->get_rss(h, indir, key, hfunc);
 788}
 789
 790static int hns3_set_rss(struct net_device *netdev, const u32 *indir,
 791                        const u8 *key, const u8 hfunc)
 792{
 793        struct hnae3_handle *h = hns3_get_handle(netdev);
 794
 795        if (!h->ae_algo->ops->set_rss)
 796                return -EOPNOTSUPP;
 797
 798        if ((h->pdev->revision == 0x20 &&
 799             hfunc != ETH_RSS_HASH_TOP) || (hfunc != ETH_RSS_HASH_NO_CHANGE &&
 800             hfunc != ETH_RSS_HASH_TOP && hfunc != ETH_RSS_HASH_XOR)) {
 801                netdev_err(netdev, "hash func not supported\n");
 802                return -EOPNOTSUPP;
 803        }
 804
 805        if (!indir) {
 806                netdev_err(netdev,
 807                           "set rss failed for indir is empty\n");
 808                return -EOPNOTSUPP;
 809        }
 810
 811        return h->ae_algo->ops->set_rss(h, indir, key, hfunc);
 812}
 813
 814static int hns3_get_rxnfc(struct net_device *netdev,
 815                          struct ethtool_rxnfc *cmd,
 816                          u32 *rule_locs)
 817{
 818        struct hnae3_handle *h = hns3_get_handle(netdev);
 819
 820        switch (cmd->cmd) {
 821        case ETHTOOL_GRXRINGS:
 822                cmd->data = h->kinfo.num_tqps;
 823                return 0;
 824        case ETHTOOL_GRXFH:
 825                if (h->ae_algo->ops->get_rss_tuple)
 826                        return h->ae_algo->ops->get_rss_tuple(h, cmd);
 827                return -EOPNOTSUPP;
 828        case ETHTOOL_GRXCLSRLCNT:
 829                if (h->ae_algo->ops->get_fd_rule_cnt)
 830                        return h->ae_algo->ops->get_fd_rule_cnt(h, cmd);
 831                return -EOPNOTSUPP;
 832        case ETHTOOL_GRXCLSRULE:
 833                if (h->ae_algo->ops->get_fd_rule_info)
 834                        return h->ae_algo->ops->get_fd_rule_info(h, cmd);
 835                return -EOPNOTSUPP;
 836        case ETHTOOL_GRXCLSRLALL:
 837                if (h->ae_algo->ops->get_fd_all_rules)
 838                        return h->ae_algo->ops->get_fd_all_rules(h, cmd,
 839                                                                 rule_locs);
 840                return -EOPNOTSUPP;
 841        default:
 842                return -EOPNOTSUPP;
 843        }
 844}
 845
 846static int hns3_change_all_ring_bd_num(struct hns3_nic_priv *priv,
 847                                       u32 tx_desc_num, u32 rx_desc_num)
 848{
 849        struct hnae3_handle *h = priv->ae_handle;
 850        int i;
 851
 852        h->kinfo.num_tx_desc = tx_desc_num;
 853        h->kinfo.num_rx_desc = rx_desc_num;
 854
 855        for (i = 0; i < h->kinfo.num_tqps; i++) {
 856                priv->ring_data[i].ring->desc_num = tx_desc_num;
 857                priv->ring_data[i + h->kinfo.num_tqps].ring->desc_num =
 858                        rx_desc_num;
 859        }
 860
 861        return hns3_init_all_ring(priv);
 862}
 863
 864static int hns3_set_ringparam(struct net_device *ndev,
 865                              struct ethtool_ringparam *param)
 866{
 867        struct hns3_nic_priv *priv = netdev_priv(ndev);
 868        struct hnae3_handle *h = priv->ae_handle;
 869        bool if_running = netif_running(ndev);
 870        u32 old_tx_desc_num, new_tx_desc_num;
 871        u32 old_rx_desc_num, new_rx_desc_num;
 872        int queue_num = h->kinfo.num_tqps;
 873        int ret;
 874
 875        if (hns3_nic_resetting(ndev))
 876                return -EBUSY;
 877
 878        if (param->rx_mini_pending || param->rx_jumbo_pending)
 879                return -EINVAL;
 880
 881        if (param->tx_pending > HNS3_RING_MAX_PENDING ||
 882            param->tx_pending < HNS3_RING_MIN_PENDING ||
 883            param->rx_pending > HNS3_RING_MAX_PENDING ||
 884            param->rx_pending < HNS3_RING_MIN_PENDING) {
 885                netdev_err(ndev, "Queue depth out of range [%d-%d]\n",
 886                           HNS3_RING_MIN_PENDING, HNS3_RING_MAX_PENDING);
 887                return -EINVAL;
 888        }
 889
 890        /* Hardware requires that its descriptors must be multiple of eight */
 891        new_tx_desc_num = ALIGN(param->tx_pending, HNS3_RING_BD_MULTIPLE);
 892        new_rx_desc_num = ALIGN(param->rx_pending, HNS3_RING_BD_MULTIPLE);
 893        old_tx_desc_num = priv->ring_data[0].ring->desc_num;
 894        old_rx_desc_num = priv->ring_data[queue_num].ring->desc_num;
 895        if (old_tx_desc_num == new_tx_desc_num &&
 896            old_rx_desc_num == new_rx_desc_num)
 897                return 0;
 898
 899        netdev_info(ndev,
 900                    "Changing Tx/Rx ring depth from %d/%d to %d/%d\n",
 901                    old_tx_desc_num, old_rx_desc_num,
 902                    new_tx_desc_num, new_rx_desc_num);
 903
 904        if (if_running)
 905                ndev->netdev_ops->ndo_stop(ndev);
 906
 907        ret = hns3_uninit_all_ring(priv);
 908        if (ret)
 909                return ret;
 910
 911        ret = hns3_change_all_ring_bd_num(priv, new_tx_desc_num,
 912                                          new_rx_desc_num);
 913        if (ret) {
 914                ret = hns3_change_all_ring_bd_num(priv, old_tx_desc_num,
 915                                                  old_rx_desc_num);
 916                if (ret) {
 917                        netdev_err(ndev,
 918                                   "Revert to old bd num fail, ret=%d.\n", ret);
 919                        return ret;
 920                }
 921        }
 922
 923        if (if_running)
 924                ret = ndev->netdev_ops->ndo_open(ndev);
 925
 926        return ret;
 927}
 928
 929static int hns3_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
 930{
 931        struct hnae3_handle *h = hns3_get_handle(netdev);
 932
 933        switch (cmd->cmd) {
 934        case ETHTOOL_SRXFH:
 935                if (h->ae_algo->ops->set_rss_tuple)
 936                        return h->ae_algo->ops->set_rss_tuple(h, cmd);
 937                return -EOPNOTSUPP;
 938        case ETHTOOL_SRXCLSRLINS:
 939                if (h->ae_algo->ops->add_fd_entry)
 940                        return h->ae_algo->ops->add_fd_entry(h, cmd);
 941                return -EOPNOTSUPP;
 942        case ETHTOOL_SRXCLSRLDEL:
 943                if (h->ae_algo->ops->del_fd_entry)
 944                        return h->ae_algo->ops->del_fd_entry(h, cmd);
 945                return -EOPNOTSUPP;
 946        default:
 947                return -EOPNOTSUPP;
 948        }
 949}
 950
 951static int hns3_nway_reset(struct net_device *netdev)
 952{
 953        struct hnae3_handle *handle = hns3_get_handle(netdev);
 954        const struct hnae3_ae_ops *ops = handle->ae_algo->ops;
 955        struct phy_device *phy = netdev->phydev;
 956        int autoneg;
 957
 958        if (!netif_running(netdev))
 959                return 0;
 960
 961        if (hns3_nic_resetting(netdev)) {
 962                netdev_err(netdev, "dev resetting!");
 963                return -EBUSY;
 964        }
 965
 966        if (!ops->get_autoneg || !ops->restart_autoneg)
 967                return -EOPNOTSUPP;
 968
 969        autoneg = ops->get_autoneg(handle);
 970        if (autoneg != AUTONEG_ENABLE) {
 971                netdev_err(netdev,
 972                           "Autoneg is off, don't support to restart it\n");
 973                return -EINVAL;
 974        }
 975
 976        if (phy)
 977                return genphy_restart_aneg(phy);
 978
 979        if (handle->pdev->revision == 0x20)
 980                return -EOPNOTSUPP;
 981
 982        return ops->restart_autoneg(handle);
 983}
 984
 985static void hns3_get_channels(struct net_device *netdev,
 986                              struct ethtool_channels *ch)
 987{
 988        struct hnae3_handle *h = hns3_get_handle(netdev);
 989
 990        if (h->ae_algo->ops->get_channels)
 991                h->ae_algo->ops->get_channels(h, ch);
 992}
 993
 994static int hns3_get_coalesce_per_queue(struct net_device *netdev, u32 queue,
 995                                       struct ethtool_coalesce *cmd)
 996{
 997        struct hns3_enet_tqp_vector *tx_vector, *rx_vector;
 998        struct hns3_nic_priv *priv = netdev_priv(netdev);
 999        struct hnae3_handle *h = priv->ae_handle;
1000        u16 queue_num = h->kinfo.num_tqps;
1001
1002        if (hns3_nic_resetting(netdev))
1003                return -EBUSY;
1004
1005        if (queue >= queue_num) {
1006                netdev_err(netdev,
1007                           "Invalid queue value %d! Queue max id=%d\n",
1008                           queue, queue_num - 1);
1009                return -EINVAL;
1010        }
1011
1012        tx_vector = priv->ring_data[queue].ring->tqp_vector;
1013        rx_vector = priv->ring_data[queue_num + queue].ring->tqp_vector;
1014
1015        cmd->use_adaptive_tx_coalesce =
1016                        tx_vector->tx_group.coal.gl_adapt_enable;
1017        cmd->use_adaptive_rx_coalesce =
1018                        rx_vector->rx_group.coal.gl_adapt_enable;
1019
1020        cmd->tx_coalesce_usecs = tx_vector->tx_group.coal.int_gl;
1021        cmd->rx_coalesce_usecs = rx_vector->rx_group.coal.int_gl;
1022
1023        cmd->tx_coalesce_usecs_high = h->kinfo.int_rl_setting;
1024        cmd->rx_coalesce_usecs_high = h->kinfo.int_rl_setting;
1025
1026        return 0;
1027}
1028
1029static int hns3_get_coalesce(struct net_device *netdev,
1030                             struct ethtool_coalesce *cmd)
1031{
1032        return hns3_get_coalesce_per_queue(netdev, 0, cmd);
1033}
1034
1035static int hns3_check_gl_coalesce_para(struct net_device *netdev,
1036                                       struct ethtool_coalesce *cmd)
1037{
1038        u32 rx_gl, tx_gl;
1039
1040        if (cmd->rx_coalesce_usecs > HNS3_INT_GL_MAX) {
1041                netdev_err(netdev,
1042                           "Invalid rx-usecs value, rx-usecs range is 0-%d\n",
1043                           HNS3_INT_GL_MAX);
1044                return -EINVAL;
1045        }
1046
1047        if (cmd->tx_coalesce_usecs > HNS3_INT_GL_MAX) {
1048                netdev_err(netdev,
1049                           "Invalid tx-usecs value, tx-usecs range is 0-%d\n",
1050                           HNS3_INT_GL_MAX);
1051                return -EINVAL;
1052        }
1053
1054        rx_gl = hns3_gl_round_down(cmd->rx_coalesce_usecs);
1055        if (rx_gl != cmd->rx_coalesce_usecs) {
1056                netdev_info(netdev,
1057                            "rx_usecs(%d) rounded down to %d, because it must be multiple of 2.\n",
1058                            cmd->rx_coalesce_usecs, rx_gl);
1059        }
1060
1061        tx_gl = hns3_gl_round_down(cmd->tx_coalesce_usecs);
1062        if (tx_gl != cmd->tx_coalesce_usecs) {
1063                netdev_info(netdev,
1064                            "tx_usecs(%d) rounded down to %d, because it must be multiple of 2.\n",
1065                            cmd->tx_coalesce_usecs, tx_gl);
1066        }
1067
1068        return 0;
1069}
1070
1071static int hns3_check_rl_coalesce_para(struct net_device *netdev,
1072                                       struct ethtool_coalesce *cmd)
1073{
1074        u32 rl;
1075
1076        if (cmd->tx_coalesce_usecs_high != cmd->rx_coalesce_usecs_high) {
1077                netdev_err(netdev,
1078                           "tx_usecs_high must be same as rx_usecs_high.\n");
1079                return -EINVAL;
1080        }
1081
1082        if (cmd->rx_coalesce_usecs_high > HNS3_INT_RL_MAX) {
1083                netdev_err(netdev,
1084                           "Invalid usecs_high value, usecs_high range is 0-%d\n",
1085                           HNS3_INT_RL_MAX);
1086                return -EINVAL;
1087        }
1088
1089        rl = hns3_rl_round_down(cmd->rx_coalesce_usecs_high);
1090        if (rl != cmd->rx_coalesce_usecs_high) {
1091                netdev_info(netdev,
1092                            "usecs_high(%d) rounded down to %d, because it must be multiple of 4.\n",
1093                            cmd->rx_coalesce_usecs_high, rl);
1094        }
1095
1096        return 0;
1097}
1098
1099static int hns3_check_coalesce_para(struct net_device *netdev,
1100                                    struct ethtool_coalesce *cmd)
1101{
1102        int ret;
1103
1104        ret = hns3_check_gl_coalesce_para(netdev, cmd);
1105        if (ret) {
1106                netdev_err(netdev,
1107                           "Check gl coalesce param fail. ret = %d\n", ret);
1108                return ret;
1109        }
1110
1111        ret = hns3_check_rl_coalesce_para(netdev, cmd);
1112        if (ret) {
1113                netdev_err(netdev,
1114                           "Check rl coalesce param fail. ret = %d\n", ret);
1115                return ret;
1116        }
1117
1118        if (cmd->use_adaptive_tx_coalesce == 1 ||
1119            cmd->use_adaptive_rx_coalesce == 1) {
1120                netdev_info(netdev,
1121                            "adaptive-tx=%d and adaptive-rx=%d, tx_usecs or rx_usecs will changed dynamically.\n",
1122                            cmd->use_adaptive_tx_coalesce,
1123                            cmd->use_adaptive_rx_coalesce);
1124        }
1125
1126        return 0;
1127}
1128
1129static void hns3_set_coalesce_per_queue(struct net_device *netdev,
1130                                        struct ethtool_coalesce *cmd,
1131                                        u32 queue)
1132{
1133        struct hns3_enet_tqp_vector *tx_vector, *rx_vector;
1134        struct hns3_nic_priv *priv = netdev_priv(netdev);
1135        struct hnae3_handle *h = priv->ae_handle;
1136        int queue_num = h->kinfo.num_tqps;
1137
1138        tx_vector = priv->ring_data[queue].ring->tqp_vector;
1139        rx_vector = priv->ring_data[queue_num + queue].ring->tqp_vector;
1140
1141        tx_vector->tx_group.coal.gl_adapt_enable =
1142                                cmd->use_adaptive_tx_coalesce;
1143        rx_vector->rx_group.coal.gl_adapt_enable =
1144                                cmd->use_adaptive_rx_coalesce;
1145
1146        tx_vector->tx_group.coal.int_gl = cmd->tx_coalesce_usecs;
1147        rx_vector->rx_group.coal.int_gl = cmd->rx_coalesce_usecs;
1148
1149        hns3_set_vector_coalesce_tx_gl(tx_vector,
1150                                       tx_vector->tx_group.coal.int_gl);
1151        hns3_set_vector_coalesce_rx_gl(rx_vector,
1152                                       rx_vector->rx_group.coal.int_gl);
1153
1154        hns3_set_vector_coalesce_rl(tx_vector, h->kinfo.int_rl_setting);
1155        hns3_set_vector_coalesce_rl(rx_vector, h->kinfo.int_rl_setting);
1156}
1157
1158static int hns3_set_coalesce(struct net_device *netdev,
1159                             struct ethtool_coalesce *cmd)
1160{
1161        struct hnae3_handle *h = hns3_get_handle(netdev);
1162        u16 queue_num = h->kinfo.num_tqps;
1163        int ret;
1164        int i;
1165
1166        if (hns3_nic_resetting(netdev))
1167                return -EBUSY;
1168
1169        ret = hns3_check_coalesce_para(netdev, cmd);
1170        if (ret)
1171                return ret;
1172
1173        h->kinfo.int_rl_setting =
1174                hns3_rl_round_down(cmd->rx_coalesce_usecs_high);
1175
1176        for (i = 0; i < queue_num; i++)
1177                hns3_set_coalesce_per_queue(netdev, cmd, i);
1178
1179        return 0;
1180}
1181
1182static int hns3_get_regs_len(struct net_device *netdev)
1183{
1184        struct hnae3_handle *h = hns3_get_handle(netdev);
1185
1186        if (!h->ae_algo->ops->get_regs_len)
1187                return -EOPNOTSUPP;
1188
1189        return h->ae_algo->ops->get_regs_len(h);
1190}
1191
1192static void hns3_get_regs(struct net_device *netdev,
1193                          struct ethtool_regs *cmd, void *data)
1194{
1195        struct hnae3_handle *h = hns3_get_handle(netdev);
1196
1197        if (!h->ae_algo->ops->get_regs)
1198                return;
1199
1200        h->ae_algo->ops->get_regs(h, &cmd->version, data);
1201}
1202
1203static int hns3_set_phys_id(struct net_device *netdev,
1204                            enum ethtool_phys_id_state state)
1205{
1206        struct hnae3_handle *h = hns3_get_handle(netdev);
1207
1208        if (!h->ae_algo->ops->set_led_id)
1209                return -EOPNOTSUPP;
1210
1211        return h->ae_algo->ops->set_led_id(h, state);
1212}
1213
1214static u32 hns3_get_msglevel(struct net_device *netdev)
1215{
1216        struct hnae3_handle *h = hns3_get_handle(netdev);
1217
1218        return h->msg_enable;
1219}
1220
1221static void hns3_set_msglevel(struct net_device *netdev, u32 msg_level)
1222{
1223        struct hnae3_handle *h = hns3_get_handle(netdev);
1224
1225        h->msg_enable = msg_level;
1226}
1227
1228/* Translate local fec value into ethtool value. */
1229static unsigned int loc_to_eth_fec(u8 loc_fec)
1230{
1231        u32 eth_fec = 0;
1232
1233        if (loc_fec & BIT(HNAE3_FEC_AUTO))
1234                eth_fec |= ETHTOOL_FEC_AUTO;
1235        if (loc_fec & BIT(HNAE3_FEC_RS))
1236                eth_fec |= ETHTOOL_FEC_RS;
1237        if (loc_fec & BIT(HNAE3_FEC_BASER))
1238                eth_fec |= ETHTOOL_FEC_BASER;
1239
1240        /* if nothing is set, then FEC is off */
1241        if (!eth_fec)
1242                eth_fec = ETHTOOL_FEC_OFF;
1243
1244        return eth_fec;
1245}
1246
1247/* Translate ethtool fec value into local value. */
1248static unsigned int eth_to_loc_fec(unsigned int eth_fec)
1249{
1250        u32 loc_fec = 0;
1251
1252        if (eth_fec & ETHTOOL_FEC_OFF)
1253                return loc_fec;
1254
1255        if (eth_fec & ETHTOOL_FEC_AUTO)
1256                loc_fec |= BIT(HNAE3_FEC_AUTO);
1257        if (eth_fec & ETHTOOL_FEC_RS)
1258                loc_fec |= BIT(HNAE3_FEC_RS);
1259        if (eth_fec & ETHTOOL_FEC_BASER)
1260                loc_fec |= BIT(HNAE3_FEC_BASER);
1261
1262        return loc_fec;
1263}
1264
1265static int hns3_get_fecparam(struct net_device *netdev,
1266                             struct ethtool_fecparam *fec)
1267{
1268        struct hnae3_handle *handle = hns3_get_handle(netdev);
1269        const struct hnae3_ae_ops *ops = handle->ae_algo->ops;
1270        u8 fec_ability;
1271        u8 fec_mode;
1272
1273        if (handle->pdev->revision == 0x20)
1274                return -EOPNOTSUPP;
1275
1276        if (!ops->get_fec)
1277                return -EOPNOTSUPP;
1278
1279        ops->get_fec(handle, &fec_ability, &fec_mode);
1280
1281        fec->fec = loc_to_eth_fec(fec_ability);
1282        fec->active_fec = loc_to_eth_fec(fec_mode);
1283
1284        return 0;
1285}
1286
1287static int hns3_set_fecparam(struct net_device *netdev,
1288                             struct ethtool_fecparam *fec)
1289{
1290        struct hnae3_handle *handle = hns3_get_handle(netdev);
1291        const struct hnae3_ae_ops *ops = handle->ae_algo->ops;
1292        u32 fec_mode;
1293
1294        if (handle->pdev->revision == 0x20)
1295                return -EOPNOTSUPP;
1296
1297        if (!ops->set_fec)
1298                return -EOPNOTSUPP;
1299        fec_mode = eth_to_loc_fec(fec->fec);
1300        return ops->set_fec(handle, fec_mode);
1301}
1302
1303static const struct ethtool_ops hns3vf_ethtool_ops = {
1304        .get_drvinfo = hns3_get_drvinfo,
1305        .get_ringparam = hns3_get_ringparam,
1306        .set_ringparam = hns3_set_ringparam,
1307        .get_strings = hns3_get_strings,
1308        .get_ethtool_stats = hns3_get_stats,
1309        .get_sset_count = hns3_get_sset_count,
1310        .get_rxnfc = hns3_get_rxnfc,
1311        .set_rxnfc = hns3_set_rxnfc,
1312        .get_rxfh_key_size = hns3_get_rss_key_size,
1313        .get_rxfh_indir_size = hns3_get_rss_indir_size,
1314        .get_rxfh = hns3_get_rss,
1315        .set_rxfh = hns3_set_rss,
1316        .get_link_ksettings = hns3_get_link_ksettings,
1317        .get_channels = hns3_get_channels,
1318        .get_coalesce = hns3_get_coalesce,
1319        .set_coalesce = hns3_set_coalesce,
1320        .get_regs_len = hns3_get_regs_len,
1321        .get_regs = hns3_get_regs,
1322        .get_link = hns3_get_link,
1323        .get_msglevel = hns3_get_msglevel,
1324        .set_msglevel = hns3_set_msglevel,
1325};
1326
1327static const struct ethtool_ops hns3_ethtool_ops = {
1328        .self_test = hns3_self_test,
1329        .get_drvinfo = hns3_get_drvinfo,
1330        .get_link = hns3_get_link,
1331        .get_ringparam = hns3_get_ringparam,
1332        .set_ringparam = hns3_set_ringparam,
1333        .get_pauseparam = hns3_get_pauseparam,
1334        .set_pauseparam = hns3_set_pauseparam,
1335        .get_strings = hns3_get_strings,
1336        .get_ethtool_stats = hns3_get_stats,
1337        .get_sset_count = hns3_get_sset_count,
1338        .get_rxnfc = hns3_get_rxnfc,
1339        .set_rxnfc = hns3_set_rxnfc,
1340        .get_rxfh_key_size = hns3_get_rss_key_size,
1341        .get_rxfh_indir_size = hns3_get_rss_indir_size,
1342        .get_rxfh = hns3_get_rss,
1343        .set_rxfh = hns3_set_rss,
1344        .get_link_ksettings = hns3_get_link_ksettings,
1345        .set_link_ksettings = hns3_set_link_ksettings,
1346        .nway_reset = hns3_nway_reset,
1347        .get_channels = hns3_get_channels,
1348        .set_channels = hns3_set_channels,
1349        .get_coalesce = hns3_get_coalesce,
1350        .set_coalesce = hns3_set_coalesce,
1351        .get_regs_len = hns3_get_regs_len,
1352        .get_regs = hns3_get_regs,
1353        .set_phys_id = hns3_set_phys_id,
1354        .get_msglevel = hns3_get_msglevel,
1355        .set_msglevel = hns3_set_msglevel,
1356        .get_fecparam = hns3_get_fecparam,
1357        .set_fecparam = hns3_set_fecparam,
1358};
1359
1360void hns3_ethtool_set_ops(struct net_device *netdev)
1361{
1362        struct hnae3_handle *h = hns3_get_handle(netdev);
1363
1364        if (h->flags & HNAE3_SUPPORT_VF)
1365                netdev->ethtool_ops = &hns3vf_ethtool_ops;
1366        else
1367                netdev->ethtool_ops = &hns3_ethtool_ops;
1368}
1369