linux/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2015 Cavium, Inc.
   3 *
   4 * This program is free software; you can redistribute it and/or modify it
   5 * under the terms of version 2 of the GNU General Public License
   6 * as published by the Free Software Foundation.
   7 */
   8
   9/* ETHTOOL Support for VNIC_VF Device*/
  10
  11#include <linux/pci.h>
  12
  13#include "nic_reg.h"
  14#include "nic.h"
  15#include "nicvf_queues.h"
  16#include "q_struct.h"
  17#include "thunder_bgx.h"
  18
  19#define DRV_NAME        "thunder-nicvf"
  20#define DRV_VERSION     "1.0"
  21
  22struct nicvf_stat {
  23        char name[ETH_GSTRING_LEN];
  24        unsigned int index;
  25};
  26
  27#define NICVF_HW_STAT(stat) { \
  28        .name = #stat, \
  29        .index = offsetof(struct nicvf_hw_stats, stat) / sizeof(u64), \
  30}
  31
  32#define NICVF_DRV_STAT(stat) { \
  33        .name = #stat, \
  34        .index = offsetof(struct nicvf_drv_stats, stat) / sizeof(u64), \
  35}
  36
  37static const struct nicvf_stat nicvf_hw_stats[] = {
  38        NICVF_HW_STAT(rx_bytes),
  39        NICVF_HW_STAT(rx_frames),
  40        NICVF_HW_STAT(rx_ucast_frames),
  41        NICVF_HW_STAT(rx_bcast_frames),
  42        NICVF_HW_STAT(rx_mcast_frames),
  43        NICVF_HW_STAT(rx_drops),
  44        NICVF_HW_STAT(rx_drop_red),
  45        NICVF_HW_STAT(rx_drop_red_bytes),
  46        NICVF_HW_STAT(rx_drop_overrun),
  47        NICVF_HW_STAT(rx_drop_overrun_bytes),
  48        NICVF_HW_STAT(rx_drop_bcast),
  49        NICVF_HW_STAT(rx_drop_mcast),
  50        NICVF_HW_STAT(rx_drop_l3_bcast),
  51        NICVF_HW_STAT(rx_drop_l3_mcast),
  52        NICVF_HW_STAT(rx_fcs_errors),
  53        NICVF_HW_STAT(rx_l2_errors),
  54        NICVF_HW_STAT(tx_bytes),
  55        NICVF_HW_STAT(tx_frames),
  56        NICVF_HW_STAT(tx_ucast_frames),
  57        NICVF_HW_STAT(tx_bcast_frames),
  58        NICVF_HW_STAT(tx_mcast_frames),
  59        NICVF_HW_STAT(tx_drops),
  60};
  61
  62static const struct nicvf_stat nicvf_drv_stats[] = {
  63        NICVF_DRV_STAT(rx_bgx_truncated_pkts),
  64        NICVF_DRV_STAT(rx_jabber_errs),
  65        NICVF_DRV_STAT(rx_fcs_errs),
  66        NICVF_DRV_STAT(rx_bgx_errs),
  67        NICVF_DRV_STAT(rx_prel2_errs),
  68        NICVF_DRV_STAT(rx_l2_hdr_malformed),
  69        NICVF_DRV_STAT(rx_oversize),
  70        NICVF_DRV_STAT(rx_undersize),
  71        NICVF_DRV_STAT(rx_l2_len_mismatch),
  72        NICVF_DRV_STAT(rx_l2_pclp),
  73        NICVF_DRV_STAT(rx_ip_ver_errs),
  74        NICVF_DRV_STAT(rx_ip_csum_errs),
  75        NICVF_DRV_STAT(rx_ip_hdr_malformed),
  76        NICVF_DRV_STAT(rx_ip_payload_malformed),
  77        NICVF_DRV_STAT(rx_ip_ttl_errs),
  78        NICVF_DRV_STAT(rx_l3_pclp),
  79        NICVF_DRV_STAT(rx_l4_malformed),
  80        NICVF_DRV_STAT(rx_l4_csum_errs),
  81        NICVF_DRV_STAT(rx_udp_len_errs),
  82        NICVF_DRV_STAT(rx_l4_port_errs),
  83        NICVF_DRV_STAT(rx_tcp_flag_errs),
  84        NICVF_DRV_STAT(rx_tcp_offset_errs),
  85        NICVF_DRV_STAT(rx_l4_pclp),
  86        NICVF_DRV_STAT(rx_truncated_pkts),
  87
  88        NICVF_DRV_STAT(tx_desc_fault),
  89        NICVF_DRV_STAT(tx_hdr_cons_err),
  90        NICVF_DRV_STAT(tx_subdesc_err),
  91        NICVF_DRV_STAT(tx_max_size_exceeded),
  92        NICVF_DRV_STAT(tx_imm_size_oflow),
  93        NICVF_DRV_STAT(tx_data_seq_err),
  94        NICVF_DRV_STAT(tx_mem_seq_err),
  95        NICVF_DRV_STAT(tx_lock_viol),
  96        NICVF_DRV_STAT(tx_data_fault),
  97        NICVF_DRV_STAT(tx_tstmp_conflict),
  98        NICVF_DRV_STAT(tx_tstmp_timeout),
  99        NICVF_DRV_STAT(tx_mem_fault),
 100        NICVF_DRV_STAT(tx_csum_overlap),
 101        NICVF_DRV_STAT(tx_csum_overflow),
 102
 103        NICVF_DRV_STAT(tx_tso),
 104        NICVF_DRV_STAT(tx_timeout),
 105        NICVF_DRV_STAT(txq_stop),
 106        NICVF_DRV_STAT(txq_wake),
 107        NICVF_DRV_STAT(rcv_buffer_alloc_failures),
 108        NICVF_DRV_STAT(page_alloc),
 109};
 110
 111static const struct nicvf_stat nicvf_queue_stats[] = {
 112        { "bytes", 0 },
 113        { "frames", 1 },
 114};
 115
 116static const unsigned int nicvf_n_hw_stats = ARRAY_SIZE(nicvf_hw_stats);
 117static const unsigned int nicvf_n_drv_stats = ARRAY_SIZE(nicvf_drv_stats);
 118static const unsigned int nicvf_n_queue_stats = ARRAY_SIZE(nicvf_queue_stats);
 119
 120static int nicvf_get_link_ksettings(struct net_device *netdev,
 121                                    struct ethtool_link_ksettings *cmd)
 122{
 123        struct nicvf *nic = netdev_priv(netdev);
 124        u32 supported, advertising;
 125
 126        supported = 0;
 127        advertising = 0;
 128
 129        if (!nic->link_up) {
 130                cmd->base.duplex = DUPLEX_UNKNOWN;
 131                cmd->base.speed = SPEED_UNKNOWN;
 132                return 0;
 133        }
 134
 135        switch (nic->speed) {
 136        case SPEED_1000:
 137                cmd->base.port = PORT_MII | PORT_TP;
 138                cmd->base.autoneg = AUTONEG_ENABLE;
 139                supported |= SUPPORTED_MII | SUPPORTED_TP;
 140                supported |= SUPPORTED_1000baseT_Full |
 141                                  SUPPORTED_1000baseT_Half |
 142                                  SUPPORTED_100baseT_Full  |
 143                                  SUPPORTED_100baseT_Half  |
 144                                  SUPPORTED_10baseT_Full   |
 145                                  SUPPORTED_10baseT_Half;
 146                supported |= SUPPORTED_Autoneg;
 147                advertising |= ADVERTISED_1000baseT_Full |
 148                                    ADVERTISED_1000baseT_Half |
 149                                    ADVERTISED_100baseT_Full  |
 150                                    ADVERTISED_100baseT_Half  |
 151                                    ADVERTISED_10baseT_Full   |
 152                                    ADVERTISED_10baseT_Half;
 153                break;
 154        case SPEED_10000:
 155                if (nic->mac_type == BGX_MODE_RXAUI) {
 156                        cmd->base.port = PORT_TP;
 157                        supported |= SUPPORTED_TP;
 158                } else {
 159                        cmd->base.port = PORT_FIBRE;
 160                        supported |= SUPPORTED_FIBRE;
 161                }
 162                cmd->base.autoneg = AUTONEG_DISABLE;
 163                supported |= SUPPORTED_10000baseT_Full;
 164                break;
 165        case SPEED_40000:
 166                cmd->base.port = PORT_FIBRE;
 167                cmd->base.autoneg = AUTONEG_DISABLE;
 168                supported |= SUPPORTED_FIBRE;
 169                supported |= SUPPORTED_40000baseCR4_Full;
 170                break;
 171        }
 172        cmd->base.duplex = nic->duplex;
 173        cmd->base.speed = nic->speed;
 174
 175        ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
 176                                                supported);
 177        ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
 178                                                advertising);
 179
 180        return 0;
 181}
 182
 183static u32 nicvf_get_link(struct net_device *netdev)
 184{
 185        struct nicvf *nic = netdev_priv(netdev);
 186
 187        return nic->link_up;
 188}
 189
 190static void nicvf_get_drvinfo(struct net_device *netdev,
 191                              struct ethtool_drvinfo *info)
 192{
 193        struct nicvf *nic = netdev_priv(netdev);
 194
 195        strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
 196        strlcpy(info->version, DRV_VERSION, sizeof(info->version));
 197        strlcpy(info->bus_info, pci_name(nic->pdev), sizeof(info->bus_info));
 198}
 199
 200static u32 nicvf_get_msglevel(struct net_device *netdev)
 201{
 202        struct nicvf *nic = netdev_priv(netdev);
 203
 204        return nic->msg_enable;
 205}
 206
 207static void nicvf_set_msglevel(struct net_device *netdev, u32 lvl)
 208{
 209        struct nicvf *nic = netdev_priv(netdev);
 210
 211        nic->msg_enable = lvl;
 212}
 213
 214static void nicvf_get_qset_strings(struct nicvf *nic, u8 **data, int qset)
 215{
 216        int stats, qidx;
 217        int start_qidx = qset * MAX_RCV_QUEUES_PER_QS;
 218
 219        for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) {
 220                for (stats = 0; stats < nicvf_n_queue_stats; stats++) {
 221                        sprintf(*data, "rxq%d: %s", qidx + start_qidx,
 222                                nicvf_queue_stats[stats].name);
 223                        *data += ETH_GSTRING_LEN;
 224                }
 225        }
 226
 227        for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) {
 228                for (stats = 0; stats < nicvf_n_queue_stats; stats++) {
 229                        sprintf(*data, "txq%d: %s", qidx + start_qidx,
 230                                nicvf_queue_stats[stats].name);
 231                        *data += ETH_GSTRING_LEN;
 232                }
 233        }
 234}
 235
 236static void nicvf_get_strings(struct net_device *netdev, u32 sset, u8 *data)
 237{
 238        struct nicvf *nic = netdev_priv(netdev);
 239        int stats;
 240        int sqs;
 241
 242        if (sset != ETH_SS_STATS)
 243                return;
 244
 245        for (stats = 0; stats < nicvf_n_hw_stats; stats++) {
 246                memcpy(data, nicvf_hw_stats[stats].name, ETH_GSTRING_LEN);
 247                data += ETH_GSTRING_LEN;
 248        }
 249
 250        for (stats = 0; stats < nicvf_n_drv_stats; stats++) {
 251                memcpy(data, nicvf_drv_stats[stats].name, ETH_GSTRING_LEN);
 252                data += ETH_GSTRING_LEN;
 253        }
 254
 255        nicvf_get_qset_strings(nic, &data, 0);
 256
 257        for (sqs = 0; sqs < nic->sqs_count; sqs++) {
 258                if (!nic->snicvf[sqs])
 259                        continue;
 260                nicvf_get_qset_strings(nic->snicvf[sqs], &data, sqs + 1);
 261        }
 262
 263        for (stats = 0; stats < BGX_RX_STATS_COUNT; stats++) {
 264                sprintf(data, "bgx_rxstat%d: ", stats);
 265                data += ETH_GSTRING_LEN;
 266        }
 267
 268        for (stats = 0; stats < BGX_TX_STATS_COUNT; stats++) {
 269                sprintf(data, "bgx_txstat%d: ", stats);
 270                data += ETH_GSTRING_LEN;
 271        }
 272}
 273
 274static int nicvf_get_sset_count(struct net_device *netdev, int sset)
 275{
 276        struct nicvf *nic = netdev_priv(netdev);
 277        int qstats_count;
 278        int sqs;
 279
 280        if (sset != ETH_SS_STATS)
 281                return -EINVAL;
 282
 283        qstats_count = nicvf_n_queue_stats *
 284                       (nic->qs->rq_cnt + nic->qs->sq_cnt);
 285        for (sqs = 0; sqs < nic->sqs_count; sqs++) {
 286                struct nicvf *snic;
 287
 288                snic = nic->snicvf[sqs];
 289                if (!snic)
 290                        continue;
 291                qstats_count += nicvf_n_queue_stats *
 292                                (snic->qs->rq_cnt + snic->qs->sq_cnt);
 293        }
 294
 295        return nicvf_n_hw_stats + nicvf_n_drv_stats +
 296                qstats_count +
 297                BGX_RX_STATS_COUNT + BGX_TX_STATS_COUNT;
 298}
 299
 300static void nicvf_get_qset_stats(struct nicvf *nic,
 301                                 struct ethtool_stats *stats, u64 **data)
 302{
 303        int stat, qidx;
 304
 305        if (!nic)
 306                return;
 307
 308        for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) {
 309                nicvf_update_rq_stats(nic, qidx);
 310                for (stat = 0; stat < nicvf_n_queue_stats; stat++)
 311                        *((*data)++) = ((u64 *)&nic->qs->rq[qidx].stats)
 312                                        [nicvf_queue_stats[stat].index];
 313        }
 314
 315        for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) {
 316                nicvf_update_sq_stats(nic, qidx);
 317                for (stat = 0; stat < nicvf_n_queue_stats; stat++)
 318                        *((*data)++) = ((u64 *)&nic->qs->sq[qidx].stats)
 319                                        [nicvf_queue_stats[stat].index];
 320        }
 321}
 322
 323static void nicvf_get_ethtool_stats(struct net_device *netdev,
 324                                    struct ethtool_stats *stats, u64 *data)
 325{
 326        struct nicvf *nic = netdev_priv(netdev);
 327        int stat, tmp_stats;
 328        int sqs, cpu;
 329
 330        nicvf_update_stats(nic);
 331
 332        /* Update LMAC stats */
 333        nicvf_update_lmac_stats(nic);
 334
 335        for (stat = 0; stat < nicvf_n_hw_stats; stat++)
 336                *(data++) = ((u64 *)&nic->hw_stats)
 337                                [nicvf_hw_stats[stat].index];
 338        for (stat = 0; stat < nicvf_n_drv_stats; stat++) {
 339                tmp_stats = 0;
 340                for_each_possible_cpu(cpu)
 341                        tmp_stats += ((u64 *)per_cpu_ptr(nic->drv_stats, cpu))
 342                                     [nicvf_drv_stats[stat].index];
 343                *(data++) = tmp_stats;
 344        }
 345
 346        nicvf_get_qset_stats(nic, stats, &data);
 347
 348        for (sqs = 0; sqs < nic->sqs_count; sqs++) {
 349                if (!nic->snicvf[sqs])
 350                        continue;
 351                nicvf_get_qset_stats(nic->snicvf[sqs], stats, &data);
 352        }
 353
 354        for (stat = 0; stat < BGX_RX_STATS_COUNT; stat++)
 355                *(data++) = nic->bgx_stats.rx_stats[stat];
 356        for (stat = 0; stat < BGX_TX_STATS_COUNT; stat++)
 357                *(data++) = nic->bgx_stats.tx_stats[stat];
 358}
 359
 360static int nicvf_get_regs_len(struct net_device *dev)
 361{
 362        return sizeof(u64) * NIC_VF_REG_COUNT;
 363}
 364
 365static void nicvf_get_regs(struct net_device *dev,
 366                           struct ethtool_regs *regs, void *reg)
 367{
 368        struct nicvf *nic = netdev_priv(dev);
 369        u64 *p = (u64 *)reg;
 370        u64 reg_offset;
 371        int mbox, key, stat, q;
 372        int i = 0;
 373
 374        regs->version = 0;
 375        memset(p, 0, NIC_VF_REG_COUNT);
 376
 377        p[i++] = nicvf_reg_read(nic, NIC_VNIC_CFG);
 378        /* Mailbox registers */
 379        for (mbox = 0; mbox < NIC_PF_VF_MAILBOX_SIZE; mbox++)
 380                p[i++] = nicvf_reg_read(nic,
 381                                        NIC_VF_PF_MAILBOX_0_1 | (mbox << 3));
 382
 383        p[i++] = nicvf_reg_read(nic, NIC_VF_INT);
 384        p[i++] = nicvf_reg_read(nic, NIC_VF_INT_W1S);
 385        p[i++] = nicvf_reg_read(nic, NIC_VF_ENA_W1C);
 386        p[i++] = nicvf_reg_read(nic, NIC_VF_ENA_W1S);
 387        p[i++] = nicvf_reg_read(nic, NIC_VNIC_RSS_CFG);
 388
 389        for (key = 0; key < RSS_HASH_KEY_SIZE; key++)
 390                p[i++] = nicvf_reg_read(nic, NIC_VNIC_RSS_KEY_0_4 | (key << 3));
 391
 392        /* Tx/Rx statistics */
 393        for (stat = 0; stat < TX_STATS_ENUM_LAST; stat++)
 394                p[i++] = nicvf_reg_read(nic,
 395                                        NIC_VNIC_TX_STAT_0_4 | (stat << 3));
 396
 397        for (i = 0; i < RX_STATS_ENUM_LAST; i++)
 398                p[i++] = nicvf_reg_read(nic,
 399                                        NIC_VNIC_RX_STAT_0_13 | (stat << 3));
 400
 401        p[i++] = nicvf_reg_read(nic, NIC_QSET_RQ_GEN_CFG);
 402
 403        /* All completion queue's registers */
 404        for (q = 0; q < MAX_CMP_QUEUES_PER_QS; q++) {
 405                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_CFG, q);
 406                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_CFG2, q);
 407                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_THRESH, q);
 408                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_BASE, q);
 409                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_HEAD, q);
 410                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_TAIL, q);
 411                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_DOOR, q);
 412                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_STATUS, q);
 413                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_STATUS2, q);
 414                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_DEBUG, q);
 415        }
 416
 417        /* All receive queue's registers */
 418        for (q = 0; q < MAX_RCV_QUEUES_PER_QS; q++) {
 419                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_RQ_0_7_CFG, q);
 420                p[i++] = nicvf_queue_reg_read(nic,
 421                                                  NIC_QSET_RQ_0_7_STAT_0_1, q);
 422                reg_offset = NIC_QSET_RQ_0_7_STAT_0_1 | (1 << 3);
 423                p[i++] = nicvf_queue_reg_read(nic, reg_offset, q);
 424        }
 425
 426        for (q = 0; q < MAX_SND_QUEUES_PER_QS; q++) {
 427                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_CFG, q);
 428                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_THRESH, q);
 429                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_BASE, q);
 430                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_HEAD, q);
 431                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_TAIL, q);
 432                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_DOOR, q);
 433                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_STATUS, q);
 434                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_DEBUG, q);
 435                /* Padding, was NIC_QSET_SQ_0_7_CNM_CHG, which
 436                 * produces bus errors when read
 437                 */
 438                p[i++] = 0;
 439                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_STAT_0_1, q);
 440                reg_offset = NIC_QSET_SQ_0_7_STAT_0_1 | (1 << 3);
 441                p[i++] = nicvf_queue_reg_read(nic, reg_offset, q);
 442        }
 443
 444        for (q = 0; q < MAX_RCV_BUF_DESC_RINGS_PER_QS; q++) {
 445                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_CFG, q);
 446                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_THRESH, q);
 447                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_BASE, q);
 448                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_HEAD, q);
 449                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_TAIL, q);
 450                p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_DOOR, q);
 451                p[i++] = nicvf_queue_reg_read(nic,
 452                                              NIC_QSET_RBDR_0_1_STATUS0, q);
 453                p[i++] = nicvf_queue_reg_read(nic,
 454                                              NIC_QSET_RBDR_0_1_STATUS1, q);
 455                reg_offset = NIC_QSET_RBDR_0_1_PREFETCH_STATUS;
 456                p[i++] = nicvf_queue_reg_read(nic, reg_offset, q);
 457        }
 458}
 459
 460static int nicvf_get_coalesce(struct net_device *netdev,
 461                              struct ethtool_coalesce *cmd)
 462{
 463        struct nicvf *nic = netdev_priv(netdev);
 464
 465        cmd->rx_coalesce_usecs = nic->cq_coalesce_usecs;
 466        return 0;
 467}
 468
 469static void nicvf_get_ringparam(struct net_device *netdev,
 470                                struct ethtool_ringparam *ring)
 471{
 472        struct nicvf *nic = netdev_priv(netdev);
 473        struct queue_set *qs = nic->qs;
 474
 475        ring->rx_max_pending = MAX_CMP_QUEUE_LEN;
 476        ring->rx_pending = qs->cq_len;
 477        ring->tx_max_pending = MAX_SND_QUEUE_LEN;
 478        ring->tx_pending = qs->sq_len;
 479}
 480
 481static int nicvf_set_ringparam(struct net_device *netdev,
 482                               struct ethtool_ringparam *ring)
 483{
 484        struct nicvf *nic = netdev_priv(netdev);
 485        struct queue_set *qs = nic->qs;
 486        u32 rx_count, tx_count;
 487
 488        /* Due to HW errata this is not supported on T88 pass 1.x silicon */
 489        if (pass1_silicon(nic->pdev))
 490                return -EINVAL;
 491
 492        if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
 493                return -EINVAL;
 494
 495        tx_count = clamp_t(u32, ring->tx_pending,
 496                           MIN_SND_QUEUE_LEN, MAX_SND_QUEUE_LEN);
 497        rx_count = clamp_t(u32, ring->rx_pending,
 498                           MIN_CMP_QUEUE_LEN, MAX_CMP_QUEUE_LEN);
 499
 500        if ((tx_count == qs->sq_len) && (rx_count == qs->cq_len))
 501                return 0;
 502
 503        /* Permitted lengths are 1K, 2K, 4K, 8K, 16K, 32K, 64K */
 504        qs->sq_len = rounddown_pow_of_two(tx_count);
 505        qs->cq_len = rounddown_pow_of_two(rx_count);
 506
 507        if (netif_running(netdev)) {
 508                nicvf_stop(netdev);
 509                nicvf_open(netdev);
 510        }
 511
 512        return 0;
 513}
 514
 515static int nicvf_get_rss_hash_opts(struct nicvf *nic,
 516                                   struct ethtool_rxnfc *info)
 517{
 518        info->data = 0;
 519
 520        switch (info->flow_type) {
 521        case TCP_V4_FLOW:
 522        case TCP_V6_FLOW:
 523        case UDP_V4_FLOW:
 524        case UDP_V6_FLOW:
 525        case SCTP_V4_FLOW:
 526        case SCTP_V6_FLOW:
 527                info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
 528        case IPV4_FLOW:
 529        case IPV6_FLOW:
 530                info->data |= RXH_IP_SRC | RXH_IP_DST;
 531                break;
 532        default:
 533                return -EINVAL;
 534        }
 535
 536        return 0;
 537}
 538
 539static int nicvf_get_rxnfc(struct net_device *dev,
 540                           struct ethtool_rxnfc *info, u32 *rules)
 541{
 542        struct nicvf *nic = netdev_priv(dev);
 543        int ret = -EOPNOTSUPP;
 544
 545        switch (info->cmd) {
 546        case ETHTOOL_GRXRINGS:
 547                info->data = nic->rx_queues;
 548                ret = 0;
 549                break;
 550        case ETHTOOL_GRXFH:
 551                return nicvf_get_rss_hash_opts(nic, info);
 552        default:
 553                break;
 554        }
 555        return ret;
 556}
 557
 558static int nicvf_set_rss_hash_opts(struct nicvf *nic,
 559                                   struct ethtool_rxnfc *info)
 560{
 561        struct nicvf_rss_info *rss = &nic->rss_info;
 562        u64 rss_cfg = nicvf_reg_read(nic, NIC_VNIC_RSS_CFG);
 563
 564        if (!rss->enable)
 565                netdev_err(nic->netdev,
 566                           "RSS is disabled, hash cannot be set\n");
 567
 568        netdev_info(nic->netdev, "Set RSS flow type = %d, data = %lld\n",
 569                    info->flow_type, info->data);
 570
 571        if (!(info->data & RXH_IP_SRC) || !(info->data & RXH_IP_DST))
 572                return -EINVAL;
 573
 574        switch (info->flow_type) {
 575        case TCP_V4_FLOW:
 576        case TCP_V6_FLOW:
 577                switch (info->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
 578                case 0:
 579                        rss_cfg &= ~(1ULL << RSS_HASH_TCP);
 580                        break;
 581                case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
 582                        rss_cfg |= (1ULL << RSS_HASH_TCP);
 583                        break;
 584                default:
 585                        return -EINVAL;
 586                }
 587                break;
 588        case UDP_V4_FLOW:
 589        case UDP_V6_FLOW:
 590                switch (info->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
 591                case 0:
 592                        rss_cfg &= ~(1ULL << RSS_HASH_UDP);
 593                        break;
 594                case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
 595                        rss_cfg |= (1ULL << RSS_HASH_UDP);
 596                        break;
 597                default:
 598                        return -EINVAL;
 599                }
 600                break;
 601        case SCTP_V4_FLOW:
 602        case SCTP_V6_FLOW:
 603                switch (info->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
 604                case 0:
 605                        rss_cfg &= ~(1ULL << RSS_HASH_L4ETC);
 606                        break;
 607                case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
 608                        rss_cfg |= (1ULL << RSS_HASH_L4ETC);
 609                        break;
 610                default:
 611                        return -EINVAL;
 612                }
 613                break;
 614        case IPV4_FLOW:
 615        case IPV6_FLOW:
 616                rss_cfg = RSS_HASH_IP;
 617                break;
 618        default:
 619                return -EINVAL;
 620        }
 621
 622        nicvf_reg_write(nic, NIC_VNIC_RSS_CFG, rss_cfg);
 623        return 0;
 624}
 625
 626static int nicvf_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info)
 627{
 628        struct nicvf *nic = netdev_priv(dev);
 629
 630        switch (info->cmd) {
 631        case ETHTOOL_SRXFH:
 632                return nicvf_set_rss_hash_opts(nic, info);
 633        default:
 634                break;
 635        }
 636        return -EOPNOTSUPP;
 637}
 638
 639static u32 nicvf_get_rxfh_key_size(struct net_device *netdev)
 640{
 641        return RSS_HASH_KEY_SIZE * sizeof(u64);
 642}
 643
 644static u32 nicvf_get_rxfh_indir_size(struct net_device *dev)
 645{
 646        struct nicvf *nic = netdev_priv(dev);
 647
 648        return nic->rss_info.rss_size;
 649}
 650
 651static int nicvf_get_rxfh(struct net_device *dev, u32 *indir, u8 *hkey,
 652                          u8 *hfunc)
 653{
 654        struct nicvf *nic = netdev_priv(dev);
 655        struct nicvf_rss_info *rss = &nic->rss_info;
 656        int idx;
 657
 658        if (indir) {
 659                for (idx = 0; idx < rss->rss_size; idx++)
 660                        indir[idx] = rss->ind_tbl[idx];
 661        }
 662
 663        if (hkey)
 664                memcpy(hkey, rss->key, RSS_HASH_KEY_SIZE * sizeof(u64));
 665
 666        if (hfunc)
 667                *hfunc = ETH_RSS_HASH_TOP;
 668
 669        return 0;
 670}
 671
 672static int nicvf_set_rxfh(struct net_device *dev, const u32 *indir,
 673                          const u8 *hkey, const u8 hfunc)
 674{
 675        struct nicvf *nic = netdev_priv(dev);
 676        struct nicvf_rss_info *rss = &nic->rss_info;
 677        int idx;
 678
 679        if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
 680                return -EOPNOTSUPP;
 681
 682        if (!rss->enable) {
 683                netdev_err(nic->netdev,
 684                           "RSS is disabled, cannot change settings\n");
 685                return -EIO;
 686        }
 687
 688        if (indir) {
 689                for (idx = 0; idx < rss->rss_size; idx++)
 690                        rss->ind_tbl[idx] = indir[idx];
 691        }
 692
 693        if (hkey) {
 694                memcpy(rss->key, hkey, RSS_HASH_KEY_SIZE * sizeof(u64));
 695                nicvf_set_rss_key(nic);
 696        }
 697
 698        nicvf_config_rss(nic);
 699        return 0;
 700}
 701
 702/* Get no of queues device supports and current queue count */
 703static void nicvf_get_channels(struct net_device *dev,
 704                               struct ethtool_channels *channel)
 705{
 706        struct nicvf *nic = netdev_priv(dev);
 707
 708        memset(channel, 0, sizeof(*channel));
 709
 710        channel->max_rx = nic->max_queues;
 711        channel->max_tx = nic->max_queues;
 712
 713        channel->rx_count = nic->rx_queues;
 714        channel->tx_count = nic->tx_queues;
 715}
 716
 717/* Set no of Tx, Rx queues to be used */
 718static int nicvf_set_channels(struct net_device *dev,
 719                              struct ethtool_channels *channel)
 720{
 721        struct nicvf *nic = netdev_priv(dev);
 722        int err = 0;
 723        bool if_up = netif_running(dev);
 724        u8 cqcount, txq_count;
 725
 726        if (!channel->rx_count || !channel->tx_count)
 727                return -EINVAL;
 728        if (channel->rx_count > nic->max_queues)
 729                return -EINVAL;
 730        if (channel->tx_count > nic->max_queues)
 731                return -EINVAL;
 732
 733        if (nic->xdp_prog &&
 734            ((channel->tx_count + channel->rx_count) > nic->max_queues)) {
 735                netdev_err(nic->netdev,
 736                           "XDP mode, RXQs + TXQs > Max %d\n",
 737                           nic->max_queues);
 738                return -EINVAL;
 739        }
 740
 741        if (if_up)
 742                nicvf_stop(dev);
 743
 744        nic->rx_queues = channel->rx_count;
 745        nic->tx_queues = channel->tx_count;
 746        if (!nic->xdp_prog)
 747                nic->xdp_tx_queues = 0;
 748        else
 749                nic->xdp_tx_queues = channel->rx_count;
 750
 751        txq_count = nic->xdp_tx_queues + nic->tx_queues;
 752        cqcount = max(nic->rx_queues, txq_count);
 753
 754        if (cqcount > MAX_CMP_QUEUES_PER_QS) {
 755                nic->sqs_count = roundup(cqcount, MAX_CMP_QUEUES_PER_QS);
 756                nic->sqs_count = (nic->sqs_count / MAX_CMP_QUEUES_PER_QS) - 1;
 757        } else {
 758                nic->sqs_count = 0;
 759        }
 760
 761        nic->qs->rq_cnt = min_t(u8, nic->rx_queues, MAX_RCV_QUEUES_PER_QS);
 762        nic->qs->sq_cnt = min_t(u8, txq_count, MAX_SND_QUEUES_PER_QS);
 763        nic->qs->cq_cnt = max(nic->qs->rq_cnt, nic->qs->sq_cnt);
 764
 765        err = nicvf_set_real_num_queues(dev, nic->tx_queues, nic->rx_queues);
 766        if (err)
 767                return err;
 768
 769        if (if_up)
 770                nicvf_open(dev);
 771
 772        netdev_info(dev, "Setting num Tx rings to %d, Rx rings to %d success\n",
 773                    nic->tx_queues, nic->rx_queues);
 774
 775        return err;
 776}
 777
 778static void nicvf_get_pauseparam(struct net_device *dev,
 779                                 struct ethtool_pauseparam *pause)
 780{
 781        struct nicvf *nic = netdev_priv(dev);
 782        union nic_mbx mbx = {};
 783
 784        /* Supported only for 10G/40G interfaces */
 785        if ((nic->mac_type == BGX_MODE_SGMII) ||
 786            (nic->mac_type == BGX_MODE_QSGMII) ||
 787            (nic->mac_type == BGX_MODE_RGMII))
 788                return;
 789
 790        mbx.pfc.msg = NIC_MBOX_MSG_PFC;
 791        mbx.pfc.get = 1;
 792        if (!nicvf_send_msg_to_pf(nic, &mbx)) {
 793                pause->autoneg = nic->pfc.autoneg;
 794                pause->rx_pause = nic->pfc.fc_rx;
 795                pause->tx_pause = nic->pfc.fc_tx;
 796        }
 797}
 798
 799static int nicvf_set_pauseparam(struct net_device *dev,
 800                                struct ethtool_pauseparam *pause)
 801{
 802        struct nicvf *nic = netdev_priv(dev);
 803        union nic_mbx mbx = {};
 804
 805        /* Supported only for 10G/40G interfaces */
 806        if ((nic->mac_type == BGX_MODE_SGMII) ||
 807            (nic->mac_type == BGX_MODE_QSGMII) ||
 808            (nic->mac_type == BGX_MODE_RGMII))
 809                return -EOPNOTSUPP;
 810
 811        if (pause->autoneg)
 812                return -EOPNOTSUPP;
 813
 814        mbx.pfc.msg = NIC_MBOX_MSG_PFC;
 815        mbx.pfc.get = 0;
 816        mbx.pfc.fc_rx = pause->rx_pause;
 817        mbx.pfc.fc_tx = pause->tx_pause;
 818        if (nicvf_send_msg_to_pf(nic, &mbx))
 819                return -EAGAIN;
 820
 821        nic->pfc.fc_rx = pause->rx_pause;
 822        nic->pfc.fc_tx = pause->tx_pause;
 823
 824        return 0;
 825}
 826
 827static const struct ethtool_ops nicvf_ethtool_ops = {
 828        .get_link               = nicvf_get_link,
 829        .get_drvinfo            = nicvf_get_drvinfo,
 830        .get_msglevel           = nicvf_get_msglevel,
 831        .set_msglevel           = nicvf_set_msglevel,
 832        .get_strings            = nicvf_get_strings,
 833        .get_sset_count         = nicvf_get_sset_count,
 834        .get_ethtool_stats      = nicvf_get_ethtool_stats,
 835        .get_regs_len           = nicvf_get_regs_len,
 836        .get_regs               = nicvf_get_regs,
 837        .get_coalesce           = nicvf_get_coalesce,
 838        .get_ringparam          = nicvf_get_ringparam,
 839        .set_ringparam          = nicvf_set_ringparam,
 840        .get_rxnfc              = nicvf_get_rxnfc,
 841        .set_rxnfc              = nicvf_set_rxnfc,
 842        .get_rxfh_key_size      = nicvf_get_rxfh_key_size,
 843        .get_rxfh_indir_size    = nicvf_get_rxfh_indir_size,
 844        .get_rxfh               = nicvf_get_rxfh,
 845        .set_rxfh               = nicvf_set_rxfh,
 846        .get_channels           = nicvf_get_channels,
 847        .set_channels           = nicvf_set_channels,
 848        .get_pauseparam         = nicvf_get_pauseparam,
 849        .set_pauseparam         = nicvf_set_pauseparam,
 850        .get_ts_info            = ethtool_op_get_ts_info,
 851        .get_link_ksettings     = nicvf_get_link_ksettings,
 852};
 853
 854void nicvf_set_ethtool_ops(struct net_device *netdev)
 855{
 856        netdev->ethtool_ops = &nicvf_ethtool_ops;
 857}
 858