linux/drivers/net/ethernet/emulex/benet/be_ethtool.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2005 - 2015 Emulex
   3 * All rights reserved.
   4 *
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public License version 2
   7 * as published by the Free Software Foundation.  The full GNU General
   8 * Public License is included in this distribution in the file called COPYING.
   9 *
  10 * Contact Information:
  11 * linux-drivers@emulex.com
  12 *
  13 * Emulex
  14 * 3333 Susan Street
  15 * Costa Mesa, CA 92626
  16 */
  17
  18#include "be.h"
  19#include "be_cmds.h"
  20#include <linux/ethtool.h>
  21
  22struct be_ethtool_stat {
  23        char desc[ETH_GSTRING_LEN];
  24        int type;
  25        int size;
  26        int offset;
  27};
  28
  29enum {DRVSTAT_TX, DRVSTAT_RX, DRVSTAT};
  30#define FIELDINFO(_struct, field) FIELD_SIZEOF(_struct, field), \
  31                                        offsetof(_struct, field)
  32#define DRVSTAT_TX_INFO(field)  #field, DRVSTAT_TX,\
  33                                        FIELDINFO(struct be_tx_stats, field)
  34#define DRVSTAT_RX_INFO(field)  #field, DRVSTAT_RX,\
  35                                        FIELDINFO(struct be_rx_stats, field)
  36#define DRVSTAT_INFO(field)     #field, DRVSTAT,\
  37                                        FIELDINFO(struct be_drv_stats, field)
  38
  39static const struct be_ethtool_stat et_stats[] = {
  40        {DRVSTAT_INFO(rx_crc_errors)},
  41        {DRVSTAT_INFO(rx_alignment_symbol_errors)},
  42        {DRVSTAT_INFO(rx_pause_frames)},
  43        {DRVSTAT_INFO(rx_control_frames)},
  44        /* Received packets dropped when the Ethernet length field
  45         * is not equal to the actual Ethernet data length.
  46         */
  47        {DRVSTAT_INFO(rx_in_range_errors)},
  48        /* Received packets dropped when their length field is >= 1501 bytes
  49         * and <= 1535 bytes.
  50         */
  51        {DRVSTAT_INFO(rx_out_range_errors)},
  52        /* Received packets dropped when they are longer than 9216 bytes */
  53        {DRVSTAT_INFO(rx_frame_too_long)},
  54        /* Received packets dropped when they don't pass the unicast or
  55         * multicast address filtering.
  56         */
  57        {DRVSTAT_INFO(rx_address_filtered)},
  58        /* Received packets dropped when IP packet length field is less than
  59         * the IP header length field.
  60         */
  61        {DRVSTAT_INFO(rx_dropped_too_small)},
  62        /* Received packets dropped when IP length field is greater than
  63         * the actual packet length.
  64         */
  65        {DRVSTAT_INFO(rx_dropped_too_short)},
  66        /* Received packets dropped when the IP header length field is less
  67         * than 5.
  68         */
  69        {DRVSTAT_INFO(rx_dropped_header_too_small)},
  70        /* Received packets dropped when the TCP header length field is less
  71         * than 5 or the TCP header length + IP header length is more
  72         * than IP packet length.
  73         */
  74        {DRVSTAT_INFO(rx_dropped_tcp_length)},
  75        {DRVSTAT_INFO(rx_dropped_runt)},
  76        /* Number of received packets dropped when a fifo for descriptors going
  77         * into the packet demux block overflows. In normal operation, this
  78         * fifo must never overflow.
  79         */
  80        {DRVSTAT_INFO(rxpp_fifo_overflow_drop)},
  81        /* Received packets dropped when the RX block runs out of space in
  82         * one of its input FIFOs. This could happen due a long burst of
  83         * minimum-sized (64b) frames in the receive path.
  84         * This counter may also be erroneously incremented rarely.
  85         */
  86        {DRVSTAT_INFO(rx_input_fifo_overflow_drop)},
  87        {DRVSTAT_INFO(rx_ip_checksum_errs)},
  88        {DRVSTAT_INFO(rx_tcp_checksum_errs)},
  89        {DRVSTAT_INFO(rx_udp_checksum_errs)},
  90        {DRVSTAT_INFO(tx_pauseframes)},
  91        {DRVSTAT_INFO(tx_controlframes)},
  92        {DRVSTAT_INFO(rx_priority_pause_frames)},
  93        {DRVSTAT_INFO(tx_priority_pauseframes)},
  94        /* Received packets dropped when an internal fifo going into
  95         * main packet buffer tank (PMEM) overflows.
  96         */
  97        {DRVSTAT_INFO(pmem_fifo_overflow_drop)},
  98        {DRVSTAT_INFO(jabber_events)},
  99        /* Received packets dropped due to lack of available HW packet buffers
 100         * used to temporarily hold the received packets.
 101         */
 102        {DRVSTAT_INFO(rx_drops_no_pbuf)},
 103        /* Received packets dropped due to input receive buffer
 104         * descriptor fifo overflowing.
 105         */
 106        {DRVSTAT_INFO(rx_drops_no_erx_descr)},
 107        /* Packets dropped because the internal FIFO to the offloaded TCP
 108         * receive processing block is full. This could happen only for
 109         * offloaded iSCSI or FCoE trarffic.
 110         */
 111        {DRVSTAT_INFO(rx_drops_no_tpre_descr)},
 112        /* Received packets dropped when they need more than 8
 113         * receive buffers. This cannot happen as the driver configures
 114         * 2048 byte receive buffers.
 115         */
 116        {DRVSTAT_INFO(rx_drops_too_many_frags)},
 117        {DRVSTAT_INFO(forwarded_packets)},
 118        /* Received packets dropped when the frame length
 119         * is more than 9018 bytes
 120         */
 121        {DRVSTAT_INFO(rx_drops_mtu)},
 122        /* Number of dma mapping errors */
 123        {DRVSTAT_INFO(dma_map_errors)},
 124        /* Number of packets dropped due to random early drop function */
 125        {DRVSTAT_INFO(eth_red_drops)},
 126        {DRVSTAT_INFO(rx_roce_bytes_lsd)},
 127        {DRVSTAT_INFO(rx_roce_bytes_msd)},
 128        {DRVSTAT_INFO(rx_roce_frames)},
 129        {DRVSTAT_INFO(roce_drops_payload_len)},
 130        {DRVSTAT_INFO(roce_drops_crc)}
 131};
 132
 133#define ETHTOOL_STATS_NUM ARRAY_SIZE(et_stats)
 134
 135/* Stats related to multi RX queues: get_stats routine assumes bytes, pkts
 136 * are first and second members respectively.
 137 */
 138static const struct be_ethtool_stat et_rx_stats[] = {
 139        {DRVSTAT_RX_INFO(rx_bytes)},/* If moving this member see above note */
 140        {DRVSTAT_RX_INFO(rx_pkts)}, /* If moving this member see above note */
 141        {DRVSTAT_RX_INFO(rx_vxlan_offload_pkts)},
 142        {DRVSTAT_RX_INFO(rx_compl)},
 143        {DRVSTAT_RX_INFO(rx_compl_err)},
 144        {DRVSTAT_RX_INFO(rx_mcast_pkts)},
 145        /* Number of page allocation failures while posting receive buffers
 146         * to HW.
 147         */
 148        {DRVSTAT_RX_INFO(rx_post_fail)},
 149        /* Recevied packets dropped due to skb allocation failure */
 150        {DRVSTAT_RX_INFO(rx_drops_no_skbs)},
 151        /* Received packets dropped due to lack of available fetched buffers
 152         * posted by the driver.
 153         */
 154        {DRVSTAT_RX_INFO(rx_drops_no_frags)}
 155};
 156
 157#define ETHTOOL_RXSTATS_NUM (ARRAY_SIZE(et_rx_stats))
 158
 159/* Stats related to multi TX queues: get_stats routine assumes compl is the
 160 * first member
 161 */
 162static const struct be_ethtool_stat et_tx_stats[] = {
 163        {DRVSTAT_TX_INFO(tx_compl)}, /* If moving this member see above note */
 164        /* This counter is incremented when the HW encounters an error while
 165         * parsing the packet header of an outgoing TX request. This counter is
 166         * applicable only for BE2, BE3 and Skyhawk based adapters.
 167         */
 168        {DRVSTAT_TX_INFO(tx_hdr_parse_err)},
 169        /* This counter is incremented when an error occurs in the DMA
 170         * operation associated with the TX request from the host to the device.
 171         */
 172        {DRVSTAT_TX_INFO(tx_dma_err)},
 173        /* This counter is incremented when MAC or VLAN spoof checking is
 174         * enabled on the interface and the TX request fails the spoof check
 175         * in HW.
 176         */
 177        {DRVSTAT_TX_INFO(tx_spoof_check_err)},
 178        /* This counter is incremented when the HW encounters an error while
 179         * performing TSO offload. This counter is applicable only for Lancer
 180         * adapters.
 181         */
 182        {DRVSTAT_TX_INFO(tx_tso_err)},
 183        /* This counter is incremented when the HW detects Q-in-Q style VLAN
 184         * tagging in a packet and such tagging is not expected on the outgoing
 185         * interface. This counter is applicable only for Lancer adapters.
 186         */
 187        {DRVSTAT_TX_INFO(tx_qinq_err)},
 188        /* This counter is incremented when the HW detects parity errors in the
 189         * packet data. This counter is applicable only for Lancer adapters.
 190         */
 191        {DRVSTAT_TX_INFO(tx_internal_parity_err)},
 192        {DRVSTAT_TX_INFO(tx_bytes)},
 193        {DRVSTAT_TX_INFO(tx_pkts)},
 194        {DRVSTAT_TX_INFO(tx_vxlan_offload_pkts)},
 195        /* Number of skbs queued for trasmission by the driver */
 196        {DRVSTAT_TX_INFO(tx_reqs)},
 197        /* Number of times the TX queue was stopped due to lack
 198         * of spaces in the TXQ.
 199         */
 200        {DRVSTAT_TX_INFO(tx_stops)},
 201        /* Pkts dropped in the driver's transmit path */
 202        {DRVSTAT_TX_INFO(tx_drv_drops)}
 203};
 204
 205#define ETHTOOL_TXSTATS_NUM (ARRAY_SIZE(et_tx_stats))
 206
 207static const char et_self_tests[][ETH_GSTRING_LEN] = {
 208        "MAC Loopback test",
 209        "PHY Loopback test",
 210        "External Loopback test",
 211        "DDR DMA test",
 212        "Link test"
 213};
 214
 215#define ETHTOOL_TESTS_NUM ARRAY_SIZE(et_self_tests)
 216#define BE_MAC_LOOPBACK 0x0
 217#define BE_PHY_LOOPBACK 0x1
 218#define BE_ONE_PORT_EXT_LOOPBACK 0x2
 219#define BE_NO_LOOPBACK 0xff
 220
 221static void be_get_drvinfo(struct net_device *netdev,
 222                           struct ethtool_drvinfo *drvinfo)
 223{
 224        struct be_adapter *adapter = netdev_priv(netdev);
 225
 226        strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
 227        strlcpy(drvinfo->version, DRV_VER, sizeof(drvinfo->version));
 228        if (!memcmp(adapter->fw_ver, adapter->fw_on_flash, FW_VER_LEN))
 229                strlcpy(drvinfo->fw_version, adapter->fw_ver,
 230                        sizeof(drvinfo->fw_version));
 231        else
 232                snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
 233                         "%s [%s]", adapter->fw_ver, adapter->fw_on_flash);
 234
 235        strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
 236                sizeof(drvinfo->bus_info));
 237        drvinfo->testinfo_len = 0;
 238        drvinfo->regdump_len = 0;
 239        drvinfo->eedump_len = 0;
 240}
 241
 242static u32 lancer_cmd_get_file_len(struct be_adapter *adapter, u8 *file_name)
 243{
 244        u32 data_read = 0, eof;
 245        u8 addn_status;
 246        struct be_dma_mem data_len_cmd;
 247        int status;
 248
 249        memset(&data_len_cmd, 0, sizeof(data_len_cmd));
 250        /* data_offset and data_size should be 0 to get reg len */
 251        status = lancer_cmd_read_object(adapter, &data_len_cmd, 0, 0,
 252                                        file_name, &data_read, &eof,
 253                                        &addn_status);
 254
 255        return data_read;
 256}
 257
 258static int lancer_cmd_read_file(struct be_adapter *adapter, u8 *file_name,
 259                                u32 buf_len, void *buf)
 260{
 261        struct be_dma_mem read_cmd;
 262        u32 read_len = 0, total_read_len = 0, chunk_size;
 263        u32 eof = 0;
 264        u8 addn_status;
 265        int status = 0;
 266
 267        read_cmd.size = LANCER_READ_FILE_CHUNK;
 268        read_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, read_cmd.size,
 269                                          &read_cmd.dma, GFP_ATOMIC);
 270
 271        if (!read_cmd.va) {
 272                dev_err(&adapter->pdev->dev,
 273                        "Memory allocation failure while reading dump\n");
 274                return -ENOMEM;
 275        }
 276
 277        while ((total_read_len < buf_len) && !eof) {
 278                chunk_size = min_t(u32, (buf_len - total_read_len),
 279                                   LANCER_READ_FILE_CHUNK);
 280                chunk_size = ALIGN(chunk_size, 4);
 281                status = lancer_cmd_read_object(adapter, &read_cmd, chunk_size,
 282                                                total_read_len, file_name,
 283                                                &read_len, &eof, &addn_status);
 284                if (!status) {
 285                        memcpy(buf + total_read_len, read_cmd.va, read_len);
 286                        total_read_len += read_len;
 287                        eof &= LANCER_READ_FILE_EOF_MASK;
 288                } else {
 289                        status = -EIO;
 290                        break;
 291                }
 292        }
 293        dma_free_coherent(&adapter->pdev->dev, read_cmd.size, read_cmd.va,
 294                          read_cmd.dma);
 295
 296        return status;
 297}
 298
 299static int be_get_reg_len(struct net_device *netdev)
 300{
 301        struct be_adapter *adapter = netdev_priv(netdev);
 302        u32 log_size = 0;
 303
 304        if (!check_privilege(adapter, MAX_PRIVILEGES))
 305                return 0;
 306
 307        if (be_physfn(adapter)) {
 308                if (lancer_chip(adapter))
 309                        log_size = lancer_cmd_get_file_len(adapter,
 310                                                           LANCER_FW_DUMP_FILE);
 311                else
 312                        be_cmd_get_reg_len(adapter, &log_size);
 313        }
 314        return log_size;
 315}
 316
 317static void
 318be_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *buf)
 319{
 320        struct be_adapter *adapter = netdev_priv(netdev);
 321
 322        if (be_physfn(adapter)) {
 323                memset(buf, 0, regs->len);
 324                if (lancer_chip(adapter))
 325                        lancer_cmd_read_file(adapter, LANCER_FW_DUMP_FILE,
 326                                             regs->len, buf);
 327                else
 328                        be_cmd_get_regs(adapter, regs->len, buf);
 329        }
 330}
 331
 332static int be_get_coalesce(struct net_device *netdev,
 333                           struct ethtool_coalesce *et)
 334{
 335        struct be_adapter *adapter = netdev_priv(netdev);
 336        struct be_aic_obj *aic = &adapter->aic_obj[0];
 337
 338        et->rx_coalesce_usecs = aic->prev_eqd;
 339        et->rx_coalesce_usecs_high = aic->max_eqd;
 340        et->rx_coalesce_usecs_low = aic->min_eqd;
 341
 342        et->tx_coalesce_usecs = aic->prev_eqd;
 343        et->tx_coalesce_usecs_high = aic->max_eqd;
 344        et->tx_coalesce_usecs_low = aic->min_eqd;
 345
 346        et->use_adaptive_rx_coalesce = aic->enable;
 347        et->use_adaptive_tx_coalesce = aic->enable;
 348
 349        return 0;
 350}
 351
 352/* TX attributes are ignored. Only RX attributes are considered
 353 * eqd cmd is issued in the worker thread.
 354 */
 355static int be_set_coalesce(struct net_device *netdev,
 356                           struct ethtool_coalesce *et)
 357{
 358        struct be_adapter *adapter = netdev_priv(netdev);
 359        struct be_aic_obj *aic = &adapter->aic_obj[0];
 360        struct be_eq_obj *eqo;
 361        int i;
 362
 363        for_all_evt_queues(adapter, eqo, i) {
 364                aic->enable = et->use_adaptive_rx_coalesce;
 365                aic->max_eqd = min(et->rx_coalesce_usecs_high, BE_MAX_EQD);
 366                aic->min_eqd = min(et->rx_coalesce_usecs_low, aic->max_eqd);
 367                aic->et_eqd = min(et->rx_coalesce_usecs, aic->max_eqd);
 368                aic->et_eqd = max(aic->et_eqd, aic->min_eqd);
 369                aic++;
 370        }
 371
 372        /* For Skyhawk, the EQD setting happens via EQ_DB when AIC is enabled.
 373         * When AIC is disabled, persistently force set EQD value via the
 374         * FW cmd, so that we don't have to calculate the delay multiplier
 375         * encode value each time EQ_DB is rung
 376         */
 377        if (!et->use_adaptive_rx_coalesce && skyhawk_chip(adapter))
 378                be_eqd_update(adapter, true);
 379
 380        return 0;
 381}
 382
 383static void be_get_ethtool_stats(struct net_device *netdev,
 384                                 struct ethtool_stats *stats, uint64_t *data)
 385{
 386        struct be_adapter *adapter = netdev_priv(netdev);
 387        struct be_rx_obj *rxo;
 388        struct be_tx_obj *txo;
 389        void *p;
 390        unsigned int i, j, base = 0, start;
 391
 392        for (i = 0; i < ETHTOOL_STATS_NUM; i++) {
 393                p = (u8 *)&adapter->drv_stats + et_stats[i].offset;
 394                data[i] = *(u32 *)p;
 395        }
 396        base += ETHTOOL_STATS_NUM;
 397
 398        for_all_rx_queues(adapter, rxo, j) {
 399                struct be_rx_stats *stats = rx_stats(rxo);
 400
 401                do {
 402                        start = u64_stats_fetch_begin_irq(&stats->sync);
 403                        data[base] = stats->rx_bytes;
 404                        data[base + 1] = stats->rx_pkts;
 405                } while (u64_stats_fetch_retry_irq(&stats->sync, start));
 406
 407                for (i = 2; i < ETHTOOL_RXSTATS_NUM; i++) {
 408                        p = (u8 *)stats + et_rx_stats[i].offset;
 409                        data[base + i] = *(u32 *)p;
 410                }
 411                base += ETHTOOL_RXSTATS_NUM;
 412        }
 413
 414        for_all_tx_queues(adapter, txo, j) {
 415                struct be_tx_stats *stats = tx_stats(txo);
 416
 417                do {
 418                        start = u64_stats_fetch_begin_irq(&stats->sync_compl);
 419                        data[base] = stats->tx_compl;
 420                } while (u64_stats_fetch_retry_irq(&stats->sync_compl, start));
 421
 422                do {
 423                        start = u64_stats_fetch_begin_irq(&stats->sync);
 424                        for (i = 1; i < ETHTOOL_TXSTATS_NUM; i++) {
 425                                p = (u8 *)stats + et_tx_stats[i].offset;
 426                                data[base + i] =
 427                                        (et_tx_stats[i].size == sizeof(u64)) ?
 428                                                *(u64 *)p : *(u32 *)p;
 429                        }
 430                } while (u64_stats_fetch_retry_irq(&stats->sync, start));
 431                base += ETHTOOL_TXSTATS_NUM;
 432        }
 433}
 434
 435static void be_get_stat_strings(struct net_device *netdev, uint32_t stringset,
 436                                uint8_t *data)
 437{
 438        struct be_adapter *adapter = netdev_priv(netdev);
 439        int i, j;
 440
 441        switch (stringset) {
 442        case ETH_SS_STATS:
 443                for (i = 0; i < ETHTOOL_STATS_NUM; i++) {
 444                        memcpy(data, et_stats[i].desc, ETH_GSTRING_LEN);
 445                        data += ETH_GSTRING_LEN;
 446                }
 447                for (i = 0; i < adapter->num_rx_qs; i++) {
 448                        for (j = 0; j < ETHTOOL_RXSTATS_NUM; j++) {
 449                                sprintf(data, "rxq%d: %s", i,
 450                                        et_rx_stats[j].desc);
 451                                data += ETH_GSTRING_LEN;
 452                        }
 453                }
 454                for (i = 0; i < adapter->num_tx_qs; i++) {
 455                        for (j = 0; j < ETHTOOL_TXSTATS_NUM; j++) {
 456                                sprintf(data, "txq%d: %s", i,
 457                                        et_tx_stats[j].desc);
 458                                data += ETH_GSTRING_LEN;
 459                        }
 460                }
 461                break;
 462        case ETH_SS_TEST:
 463                for (i = 0; i < ETHTOOL_TESTS_NUM; i++) {
 464                        memcpy(data, et_self_tests[i], ETH_GSTRING_LEN);
 465                        data += ETH_GSTRING_LEN;
 466                }
 467                break;
 468        }
 469}
 470
 471static int be_get_sset_count(struct net_device *netdev, int stringset)
 472{
 473        struct be_adapter *adapter = netdev_priv(netdev);
 474
 475        switch (stringset) {
 476        case ETH_SS_TEST:
 477                return ETHTOOL_TESTS_NUM;
 478        case ETH_SS_STATS:
 479                return ETHTOOL_STATS_NUM +
 480                        adapter->num_rx_qs * ETHTOOL_RXSTATS_NUM +
 481                        adapter->num_tx_qs * ETHTOOL_TXSTATS_NUM;
 482        default:
 483                return -EINVAL;
 484        }
 485}
 486
 487static u32 be_get_port_type(struct be_adapter *adapter)
 488{
 489        u32 port;
 490
 491        switch (adapter->phy.interface_type) {
 492        case PHY_TYPE_BASET_1GB:
 493        case PHY_TYPE_BASEX_1GB:
 494        case PHY_TYPE_SGMII:
 495                port = PORT_TP;
 496                break;
 497        case PHY_TYPE_SFP_PLUS_10GB:
 498                if (adapter->phy.cable_type & SFP_PLUS_COPPER_CABLE)
 499                        port = PORT_DA;
 500                else
 501                        port = PORT_FIBRE;
 502                break;
 503        case PHY_TYPE_QSFP:
 504                if (adapter->phy.cable_type & QSFP_PLUS_CR4_CABLE)
 505                        port = PORT_DA;
 506                else
 507                        port = PORT_FIBRE;
 508                break;
 509        case PHY_TYPE_XFP_10GB:
 510        case PHY_TYPE_SFP_1GB:
 511                port = PORT_FIBRE;
 512                break;
 513        case PHY_TYPE_BASET_10GB:
 514                port = PORT_TP;
 515                break;
 516        default:
 517                port = PORT_OTHER;
 518        }
 519
 520        return port;
 521}
 522
 523static u32 convert_to_et_setting(struct be_adapter *adapter, u32 if_speeds)
 524{
 525        u32 val = 0;
 526
 527        switch (adapter->phy.interface_type) {
 528        case PHY_TYPE_BASET_1GB:
 529        case PHY_TYPE_BASEX_1GB:
 530        case PHY_TYPE_SGMII:
 531                val |= SUPPORTED_TP;
 532                if (if_speeds & BE_SUPPORTED_SPEED_1GBPS)
 533                        val |= SUPPORTED_1000baseT_Full;
 534                if (if_speeds & BE_SUPPORTED_SPEED_100MBPS)
 535                        val |= SUPPORTED_100baseT_Full;
 536                if (if_speeds & BE_SUPPORTED_SPEED_10MBPS)
 537                        val |= SUPPORTED_10baseT_Full;
 538                break;
 539        case PHY_TYPE_KX4_10GB:
 540                val |= SUPPORTED_Backplane;
 541                if (if_speeds & BE_SUPPORTED_SPEED_1GBPS)
 542                        val |= SUPPORTED_1000baseKX_Full;
 543                if (if_speeds & BE_SUPPORTED_SPEED_10GBPS)
 544                        val |= SUPPORTED_10000baseKX4_Full;
 545                break;
 546        case PHY_TYPE_KR2_20GB:
 547                val |= SUPPORTED_Backplane;
 548                if (if_speeds & BE_SUPPORTED_SPEED_10GBPS)
 549                        val |= SUPPORTED_10000baseKR_Full;
 550                if (if_speeds & BE_SUPPORTED_SPEED_20GBPS)
 551                        val |= SUPPORTED_20000baseKR2_Full;
 552                break;
 553        case PHY_TYPE_KR_10GB:
 554                val |= SUPPORTED_Backplane |
 555                                SUPPORTED_10000baseKR_Full;
 556                break;
 557        case PHY_TYPE_KR4_40GB:
 558                val |= SUPPORTED_Backplane;
 559                if (if_speeds & BE_SUPPORTED_SPEED_10GBPS)
 560                        val |= SUPPORTED_10000baseKR_Full;
 561                if (if_speeds & BE_SUPPORTED_SPEED_40GBPS)
 562                        val |= SUPPORTED_40000baseKR4_Full;
 563                break;
 564        case PHY_TYPE_QSFP:
 565                if (if_speeds & BE_SUPPORTED_SPEED_40GBPS) {
 566                        switch (adapter->phy.cable_type) {
 567                        case QSFP_PLUS_CR4_CABLE:
 568                                val |= SUPPORTED_40000baseCR4_Full;
 569                                break;
 570                        case QSFP_PLUS_LR4_CABLE:
 571                                val |= SUPPORTED_40000baseLR4_Full;
 572                                break;
 573                        default:
 574                                val |= SUPPORTED_40000baseSR4_Full;
 575                                break;
 576                        }
 577                }
 578        case PHY_TYPE_SFP_PLUS_10GB:
 579        case PHY_TYPE_XFP_10GB:
 580        case PHY_TYPE_SFP_1GB:
 581                val |= SUPPORTED_FIBRE;
 582                if (if_speeds & BE_SUPPORTED_SPEED_10GBPS)
 583                        val |= SUPPORTED_10000baseT_Full;
 584                if (if_speeds & BE_SUPPORTED_SPEED_1GBPS)
 585                        val |= SUPPORTED_1000baseT_Full;
 586                break;
 587        case PHY_TYPE_BASET_10GB:
 588                val |= SUPPORTED_TP;
 589                if (if_speeds & BE_SUPPORTED_SPEED_10GBPS)
 590                        val |= SUPPORTED_10000baseT_Full;
 591                if (if_speeds & BE_SUPPORTED_SPEED_1GBPS)
 592                        val |= SUPPORTED_1000baseT_Full;
 593                if (if_speeds & BE_SUPPORTED_SPEED_100MBPS)
 594                        val |= SUPPORTED_100baseT_Full;
 595                break;
 596        default:
 597                val |= SUPPORTED_TP;
 598        }
 599
 600        return val;
 601}
 602
 603bool be_pause_supported(struct be_adapter *adapter)
 604{
 605        return (adapter->phy.interface_type == PHY_TYPE_SFP_PLUS_10GB ||
 606                adapter->phy.interface_type == PHY_TYPE_XFP_10GB) ?
 607                false : true;
 608}
 609
 610static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 611{
 612        struct be_adapter *adapter = netdev_priv(netdev);
 613        u8 link_status;
 614        u16 link_speed = 0;
 615        int status;
 616        u32 auto_speeds;
 617        u32 fixed_speeds;
 618
 619        if (adapter->phy.link_speed < 0) {
 620                status = be_cmd_link_status_query(adapter, &link_speed,
 621                                                  &link_status, 0);
 622                if (!status)
 623                        be_link_status_update(adapter, link_status);
 624                ethtool_cmd_speed_set(ecmd, link_speed);
 625
 626                status = be_cmd_get_phy_info(adapter);
 627                if (!status) {
 628                        auto_speeds = adapter->phy.auto_speeds_supported;
 629                        fixed_speeds = adapter->phy.fixed_speeds_supported;
 630
 631                        be_cmd_query_cable_type(adapter);
 632
 633                        ecmd->supported =
 634                                convert_to_et_setting(adapter,
 635                                                      auto_speeds |
 636                                                      fixed_speeds);
 637                        ecmd->advertising =
 638                                convert_to_et_setting(adapter, auto_speeds);
 639
 640                        ecmd->port = be_get_port_type(adapter);
 641
 642                        if (adapter->phy.auto_speeds_supported) {
 643                                ecmd->supported |= SUPPORTED_Autoneg;
 644                                ecmd->autoneg = AUTONEG_ENABLE;
 645                                ecmd->advertising |= ADVERTISED_Autoneg;
 646                        }
 647
 648                        ecmd->supported |= SUPPORTED_Pause;
 649                        if (be_pause_supported(adapter))
 650                                ecmd->advertising |= ADVERTISED_Pause;
 651
 652                        switch (adapter->phy.interface_type) {
 653                        case PHY_TYPE_KR_10GB:
 654                        case PHY_TYPE_KX4_10GB:
 655                                ecmd->transceiver = XCVR_INTERNAL;
 656                                break;
 657                        default:
 658                                ecmd->transceiver = XCVR_EXTERNAL;
 659                                break;
 660                        }
 661                } else {
 662                        ecmd->port = PORT_OTHER;
 663                        ecmd->autoneg = AUTONEG_DISABLE;
 664                        ecmd->transceiver = XCVR_DUMMY1;
 665                }
 666
 667                /* Save for future use */
 668                adapter->phy.link_speed = ethtool_cmd_speed(ecmd);
 669                adapter->phy.port_type = ecmd->port;
 670                adapter->phy.transceiver = ecmd->transceiver;
 671                adapter->phy.autoneg = ecmd->autoneg;
 672                adapter->phy.advertising = ecmd->advertising;
 673                adapter->phy.supported = ecmd->supported;
 674        } else {
 675                ethtool_cmd_speed_set(ecmd, adapter->phy.link_speed);
 676                ecmd->port = adapter->phy.port_type;
 677                ecmd->transceiver = adapter->phy.transceiver;
 678                ecmd->autoneg = adapter->phy.autoneg;
 679                ecmd->advertising = adapter->phy.advertising;
 680                ecmd->supported = adapter->phy.supported;
 681        }
 682
 683        ecmd->duplex = netif_carrier_ok(netdev) ? DUPLEX_FULL : DUPLEX_UNKNOWN;
 684        ecmd->phy_address = adapter->port_num;
 685
 686        return 0;
 687}
 688
 689static void be_get_ringparam(struct net_device *netdev,
 690                             struct ethtool_ringparam *ring)
 691{
 692        struct be_adapter *adapter = netdev_priv(netdev);
 693
 694        ring->rx_max_pending = adapter->rx_obj[0].q.len;
 695        ring->rx_pending = adapter->rx_obj[0].q.len;
 696        ring->tx_max_pending = adapter->tx_obj[0].q.len;
 697        ring->tx_pending = adapter->tx_obj[0].q.len;
 698}
 699
 700static void
 701be_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
 702{
 703        struct be_adapter *adapter = netdev_priv(netdev);
 704
 705        be_cmd_get_flow_control(adapter, &ecmd->tx_pause, &ecmd->rx_pause);
 706        ecmd->autoneg = adapter->phy.fc_autoneg;
 707}
 708
 709static int
 710be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
 711{
 712        struct be_adapter *adapter = netdev_priv(netdev);
 713        int status;
 714
 715        if (ecmd->autoneg != adapter->phy.fc_autoneg)
 716                return -EINVAL;
 717
 718        status = be_cmd_set_flow_control(adapter, ecmd->tx_pause,
 719                                         ecmd->rx_pause);
 720        if (status) {
 721                dev_warn(&adapter->pdev->dev, "Pause param set failed\n");
 722                return be_cmd_status(status);
 723        }
 724
 725        adapter->tx_fc = ecmd->tx_pause;
 726        adapter->rx_fc = ecmd->rx_pause;
 727        return 0;
 728}
 729
 730static int be_set_phys_id(struct net_device *netdev,
 731                          enum ethtool_phys_id_state state)
 732{
 733        struct be_adapter *adapter = netdev_priv(netdev);
 734
 735        switch (state) {
 736        case ETHTOOL_ID_ACTIVE:
 737                be_cmd_get_beacon_state(adapter, adapter->hba_port_num,
 738                                        &adapter->beacon_state);
 739                return 1;       /* cycle on/off once per second */
 740
 741        case ETHTOOL_ID_ON:
 742                be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
 743                                        BEACON_STATE_ENABLED);
 744                break;
 745
 746        case ETHTOOL_ID_OFF:
 747                be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
 748                                        BEACON_STATE_DISABLED);
 749                break;
 750
 751        case ETHTOOL_ID_INACTIVE:
 752                be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
 753                                        adapter->beacon_state);
 754        }
 755
 756        return 0;
 757}
 758
 759static int be_set_dump(struct net_device *netdev, struct ethtool_dump *dump)
 760{
 761        struct be_adapter *adapter = netdev_priv(netdev);
 762        struct device *dev = &adapter->pdev->dev;
 763        int status;
 764
 765        if (!lancer_chip(adapter) ||
 766            !check_privilege(adapter, MAX_PRIVILEGES))
 767                return -EOPNOTSUPP;
 768
 769        switch (dump->flag) {
 770        case LANCER_INITIATE_FW_DUMP:
 771                status = lancer_initiate_dump(adapter);
 772                if (!status)
 773                        dev_info(dev, "FW dump initiated successfully\n");
 774                break;
 775        case LANCER_DELETE_FW_DUMP:
 776                status = lancer_delete_dump(adapter);
 777                if (!status)
 778                        dev_info(dev, "FW dump deleted successfully\n");
 779        break;
 780        default:
 781                dev_err(dev, "Invalid dump level: 0x%x\n", dump->flag);
 782                return -EINVAL;
 783        }
 784        return status;
 785}
 786
 787static void be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 788{
 789        struct be_adapter *adapter = netdev_priv(netdev);
 790
 791        if (adapter->wol_cap & BE_WOL_CAP) {
 792                wol->supported |= WAKE_MAGIC;
 793                if (adapter->wol_en)
 794                        wol->wolopts |= WAKE_MAGIC;
 795        } else {
 796                wol->wolopts = 0;
 797        }
 798        memset(&wol->sopass, 0, sizeof(wol->sopass));
 799}
 800
 801static int be_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 802{
 803        struct be_adapter *adapter = netdev_priv(netdev);
 804
 805        if (wol->wolopts & ~WAKE_MAGIC)
 806                return -EOPNOTSUPP;
 807
 808        if (!(adapter->wol_cap & BE_WOL_CAP)) {
 809                dev_warn(&adapter->pdev->dev, "WOL not supported\n");
 810                return -EOPNOTSUPP;
 811        }
 812
 813        if (wol->wolopts & WAKE_MAGIC)
 814                adapter->wol_en = true;
 815        else
 816                adapter->wol_en = false;
 817
 818        return 0;
 819}
 820
 821static int be_test_ddr_dma(struct be_adapter *adapter)
 822{
 823        int ret, i;
 824        struct be_dma_mem ddrdma_cmd;
 825        static const u64 pattern[2] = {
 826                0x5a5a5a5a5a5a5a5aULL, 0xa5a5a5a5a5a5a5a5ULL
 827        };
 828
 829        ddrdma_cmd.size = sizeof(struct be_cmd_req_ddrdma_test);
 830        ddrdma_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev,
 831                                            ddrdma_cmd.size, &ddrdma_cmd.dma,
 832                                            GFP_KERNEL);
 833        if (!ddrdma_cmd.va)
 834                return -ENOMEM;
 835
 836        for (i = 0; i < 2; i++) {
 837                ret = be_cmd_ddr_dma_test(adapter, pattern[i],
 838                                          4096, &ddrdma_cmd);
 839                if (ret != 0)
 840                        goto err;
 841        }
 842
 843err:
 844        dma_free_coherent(&adapter->pdev->dev, ddrdma_cmd.size, ddrdma_cmd.va,
 845                          ddrdma_cmd.dma);
 846        return be_cmd_status(ret);
 847}
 848
 849static u64 be_loopback_test(struct be_adapter *adapter, u8 loopback_type,
 850                            u64 *status)
 851{
 852        int ret;
 853
 854        ret = be_cmd_set_loopback(adapter, adapter->hba_port_num,
 855                                  loopback_type, 1);
 856        if (ret)
 857                return ret;
 858
 859        *status = be_cmd_loopback_test(adapter, adapter->hba_port_num,
 860                                       loopback_type, 1500, 2, 0xabc);
 861
 862        ret = be_cmd_set_loopback(adapter, adapter->hba_port_num,
 863                                  BE_NO_LOOPBACK, 1);
 864        if (ret)
 865                return ret;
 866
 867        return *status;
 868}
 869
 870static void be_self_test(struct net_device *netdev, struct ethtool_test *test,
 871                         u64 *data)
 872{
 873        struct be_adapter *adapter = netdev_priv(netdev);
 874        int status;
 875        u8 link_status = 0;
 876
 877        if (adapter->function_caps & BE_FUNCTION_CAPS_SUPER_NIC) {
 878                dev_err(&adapter->pdev->dev, "Self test not supported\n");
 879                test->flags |= ETH_TEST_FL_FAILED;
 880                return;
 881        }
 882
 883        memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM);
 884
 885        if (test->flags & ETH_TEST_FL_OFFLINE) {
 886                if (be_loopback_test(adapter, BE_MAC_LOOPBACK, &data[0]) != 0)
 887                        test->flags |= ETH_TEST_FL_FAILED;
 888
 889                if (be_loopback_test(adapter, BE_PHY_LOOPBACK, &data[1]) != 0)
 890                        test->flags |= ETH_TEST_FL_FAILED;
 891
 892                if (test->flags & ETH_TEST_FL_EXTERNAL_LB) {
 893                        if (be_loopback_test(adapter, BE_ONE_PORT_EXT_LOOPBACK,
 894                                             &data[2]) != 0)
 895                                test->flags |= ETH_TEST_FL_FAILED;
 896                        test->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE;
 897                }
 898        }
 899
 900        if (!lancer_chip(adapter) && be_test_ddr_dma(adapter) != 0) {
 901                data[3] = 1;
 902                test->flags |= ETH_TEST_FL_FAILED;
 903        }
 904
 905        status = be_cmd_link_status_query(adapter, NULL, &link_status, 0);
 906        if (status) {
 907                test->flags |= ETH_TEST_FL_FAILED;
 908                data[4] = -1;
 909        } else if (!link_status) {
 910                test->flags |= ETH_TEST_FL_FAILED;
 911                data[4] = 1;
 912        }
 913}
 914
 915static int be_do_flash(struct net_device *netdev, struct ethtool_flash *efl)
 916{
 917        struct be_adapter *adapter = netdev_priv(netdev);
 918
 919        return be_load_fw(adapter, efl->data);
 920}
 921
 922static int be_get_eeprom_len(struct net_device *netdev)
 923{
 924        struct be_adapter *adapter = netdev_priv(netdev);
 925
 926        if (!check_privilege(adapter, MAX_PRIVILEGES))
 927                return 0;
 928
 929        if (lancer_chip(adapter)) {
 930                if (be_physfn(adapter))
 931                        return lancer_cmd_get_file_len(adapter,
 932                                                       LANCER_VPD_PF_FILE);
 933                else
 934                        return lancer_cmd_get_file_len(adapter,
 935                                                       LANCER_VPD_VF_FILE);
 936        } else {
 937                return BE_READ_SEEPROM_LEN;
 938        }
 939}
 940
 941static int be_read_eeprom(struct net_device *netdev,
 942                          struct ethtool_eeprom *eeprom, uint8_t *data)
 943{
 944        struct be_adapter *adapter = netdev_priv(netdev);
 945        struct be_dma_mem eeprom_cmd;
 946        struct be_cmd_resp_seeprom_read *resp;
 947        int status;
 948
 949        if (!eeprom->len)
 950                return -EINVAL;
 951
 952        if (lancer_chip(adapter)) {
 953                if (be_physfn(adapter))
 954                        return lancer_cmd_read_file(adapter, LANCER_VPD_PF_FILE,
 955                                                    eeprom->len, data);
 956                else
 957                        return lancer_cmd_read_file(adapter, LANCER_VPD_VF_FILE,
 958                                                    eeprom->len, data);
 959        }
 960
 961        eeprom->magic = BE_VENDOR_ID | (adapter->pdev->device<<16);
 962
 963        memset(&eeprom_cmd, 0, sizeof(struct be_dma_mem));
 964        eeprom_cmd.size = sizeof(struct be_cmd_req_seeprom_read);
 965        eeprom_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev,
 966                                            eeprom_cmd.size, &eeprom_cmd.dma,
 967                                            GFP_KERNEL);
 968
 969        if (!eeprom_cmd.va)
 970                return -ENOMEM;
 971
 972        status = be_cmd_get_seeprom_data(adapter, &eeprom_cmd);
 973
 974        if (!status) {
 975                resp = eeprom_cmd.va;
 976                memcpy(data, resp->seeprom_data + eeprom->offset, eeprom->len);
 977        }
 978        dma_free_coherent(&adapter->pdev->dev, eeprom_cmd.size, eeprom_cmd.va,
 979                          eeprom_cmd.dma);
 980
 981        return be_cmd_status(status);
 982}
 983
 984static u32 be_get_msg_level(struct net_device *netdev)
 985{
 986        struct be_adapter *adapter = netdev_priv(netdev);
 987
 988        return adapter->msg_enable;
 989}
 990
 991static void be_set_msg_level(struct net_device *netdev, u32 level)
 992{
 993        struct be_adapter *adapter = netdev_priv(netdev);
 994
 995        if (adapter->msg_enable == level)
 996                return;
 997
 998        if ((level & NETIF_MSG_HW) != (adapter->msg_enable & NETIF_MSG_HW))
 999                if (BEx_chip(adapter))
1000                        be_cmd_set_fw_log_level(adapter, level & NETIF_MSG_HW ?
1001                                                FW_LOG_LEVEL_DEFAULT :
1002                                                FW_LOG_LEVEL_FATAL);
1003        adapter->msg_enable = level;
1004}
1005
1006static u64 be_get_rss_hash_opts(struct be_adapter *adapter, u64 flow_type)
1007{
1008        u64 data = 0;
1009
1010        switch (flow_type) {
1011        case TCP_V4_FLOW:
1012                if (adapter->rss_info.rss_flags & RSS_ENABLE_IPV4)
1013                        data |= RXH_IP_DST | RXH_IP_SRC;
1014                if (adapter->rss_info.rss_flags & RSS_ENABLE_TCP_IPV4)
1015                        data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
1016                break;
1017        case UDP_V4_FLOW:
1018                if (adapter->rss_info.rss_flags & RSS_ENABLE_IPV4)
1019                        data |= RXH_IP_DST | RXH_IP_SRC;
1020                if (adapter->rss_info.rss_flags & RSS_ENABLE_UDP_IPV4)
1021                        data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
1022                break;
1023        case TCP_V6_FLOW:
1024                if (adapter->rss_info.rss_flags & RSS_ENABLE_IPV6)
1025                        data |= RXH_IP_DST | RXH_IP_SRC;
1026                if (adapter->rss_info.rss_flags & RSS_ENABLE_TCP_IPV6)
1027                        data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
1028                break;
1029        case UDP_V6_FLOW:
1030                if (adapter->rss_info.rss_flags & RSS_ENABLE_IPV6)
1031                        data |= RXH_IP_DST | RXH_IP_SRC;
1032                if (adapter->rss_info.rss_flags & RSS_ENABLE_UDP_IPV6)
1033                        data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
1034                break;
1035        }
1036
1037        return data;
1038}
1039
1040static int be_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
1041                        u32 *rule_locs)
1042{
1043        struct be_adapter *adapter = netdev_priv(netdev);
1044
1045        if (!be_multi_rxq(adapter)) {
1046                dev_info(&adapter->pdev->dev,
1047                         "ethtool::get_rxnfc: RX flow hashing is disabled\n");
1048                return -EINVAL;
1049        }
1050
1051        switch (cmd->cmd) {
1052        case ETHTOOL_GRXFH:
1053                cmd->data = be_get_rss_hash_opts(adapter, cmd->flow_type);
1054                break;
1055        case ETHTOOL_GRXRINGS:
1056                cmd->data = adapter->num_rx_qs - 1;
1057                break;
1058        default:
1059                return -EINVAL;
1060        }
1061
1062        return 0;
1063}
1064
1065static int be_set_rss_hash_opts(struct be_adapter *adapter,
1066                                struct ethtool_rxnfc *cmd)
1067{
1068        struct be_rx_obj *rxo;
1069        int status = 0, i, j;
1070        u8 rsstable[128];
1071        u32 rss_flags = adapter->rss_info.rss_flags;
1072
1073        if (cmd->data != L3_RSS_FLAGS &&
1074            cmd->data != (L3_RSS_FLAGS | L4_RSS_FLAGS))
1075                return -EINVAL;
1076
1077        switch (cmd->flow_type) {
1078        case TCP_V4_FLOW:
1079                if (cmd->data == L3_RSS_FLAGS)
1080                        rss_flags &= ~RSS_ENABLE_TCP_IPV4;
1081                else if (cmd->data == (L3_RSS_FLAGS | L4_RSS_FLAGS))
1082                        rss_flags |= RSS_ENABLE_IPV4 |
1083                                        RSS_ENABLE_TCP_IPV4;
1084                break;
1085        case TCP_V6_FLOW:
1086                if (cmd->data == L3_RSS_FLAGS)
1087                        rss_flags &= ~RSS_ENABLE_TCP_IPV6;
1088                else if (cmd->data == (L3_RSS_FLAGS | L4_RSS_FLAGS))
1089                        rss_flags |= RSS_ENABLE_IPV6 |
1090                                        RSS_ENABLE_TCP_IPV6;
1091                break;
1092        case UDP_V4_FLOW:
1093                if ((cmd->data == (L3_RSS_FLAGS | L4_RSS_FLAGS)) &&
1094                    BEx_chip(adapter))
1095                        return -EINVAL;
1096
1097                if (cmd->data == L3_RSS_FLAGS)
1098                        rss_flags &= ~RSS_ENABLE_UDP_IPV4;
1099                else if (cmd->data == (L3_RSS_FLAGS | L4_RSS_FLAGS))
1100                        rss_flags |= RSS_ENABLE_IPV4 |
1101                                        RSS_ENABLE_UDP_IPV4;
1102                break;
1103        case UDP_V6_FLOW:
1104                if ((cmd->data == (L3_RSS_FLAGS | L4_RSS_FLAGS)) &&
1105                    BEx_chip(adapter))
1106                        return -EINVAL;
1107
1108                if (cmd->data == L3_RSS_FLAGS)
1109                        rss_flags &= ~RSS_ENABLE_UDP_IPV6;
1110                else if (cmd->data == (L3_RSS_FLAGS | L4_RSS_FLAGS))
1111                        rss_flags |= RSS_ENABLE_IPV6 |
1112                                        RSS_ENABLE_UDP_IPV6;
1113                break;
1114        default:
1115                return -EINVAL;
1116        }
1117
1118        if (rss_flags == adapter->rss_info.rss_flags)
1119                return status;
1120
1121        if (be_multi_rxq(adapter)) {
1122                for (j = 0; j < 128; j += adapter->num_rss_qs) {
1123                        for_all_rss_queues(adapter, rxo, i) {
1124                                if ((j + i) >= 128)
1125                                        break;
1126                                rsstable[j + i] = rxo->rss_id;
1127                        }
1128                }
1129        }
1130
1131        status = be_cmd_rss_config(adapter, adapter->rss_info.rsstable,
1132                                   rss_flags, 128, adapter->rss_info.rss_hkey);
1133        if (!status)
1134                adapter->rss_info.rss_flags = rss_flags;
1135
1136        return be_cmd_status(status);
1137}
1138
1139static int be_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
1140{
1141        struct be_adapter *adapter = netdev_priv(netdev);
1142        int status = 0;
1143
1144        if (!be_multi_rxq(adapter)) {
1145                dev_err(&adapter->pdev->dev,
1146                        "ethtool::set_rxnfc: RX flow hashing is disabled\n");
1147                return -EINVAL;
1148        }
1149
1150        switch (cmd->cmd) {
1151        case ETHTOOL_SRXFH:
1152                status = be_set_rss_hash_opts(adapter, cmd);
1153                break;
1154        default:
1155                return -EINVAL;
1156        }
1157
1158        return status;
1159}
1160
1161static void be_get_channels(struct net_device *netdev,
1162                            struct ethtool_channels *ch)
1163{
1164        struct be_adapter *adapter = netdev_priv(netdev);
1165
1166        ch->combined_count = adapter->num_evt_qs;
1167        ch->max_combined = be_max_qs(adapter);
1168}
1169
1170static int be_set_channels(struct net_device  *netdev,
1171                           struct ethtool_channels *ch)
1172{
1173        struct be_adapter *adapter = netdev_priv(netdev);
1174        int status;
1175
1176        if (ch->rx_count || ch->tx_count || ch->other_count ||
1177            !ch->combined_count || ch->combined_count > be_max_qs(adapter))
1178                return -EINVAL;
1179
1180        adapter->cfg_num_qs = ch->combined_count;
1181
1182        status = be_update_queues(adapter);
1183        return be_cmd_status(status);
1184}
1185
1186static u32 be_get_rxfh_indir_size(struct net_device *netdev)
1187{
1188        return RSS_INDIR_TABLE_LEN;
1189}
1190
1191static u32 be_get_rxfh_key_size(struct net_device *netdev)
1192{
1193        return RSS_HASH_KEY_LEN;
1194}
1195
1196static int be_get_rxfh(struct net_device *netdev, u32 *indir, u8 *hkey,
1197                       u8 *hfunc)
1198{
1199        struct be_adapter *adapter = netdev_priv(netdev);
1200        int i;
1201        struct rss_info *rss = &adapter->rss_info;
1202
1203        if (indir) {
1204                for (i = 0; i < RSS_INDIR_TABLE_LEN; i++)
1205                        indir[i] = rss->rss_queue[i];
1206        }
1207
1208        if (hkey)
1209                memcpy(hkey, rss->rss_hkey, RSS_HASH_KEY_LEN);
1210
1211        if (hfunc)
1212                *hfunc = ETH_RSS_HASH_TOP;
1213
1214        return 0;
1215}
1216
1217static int be_set_rxfh(struct net_device *netdev, const u32 *indir,
1218                       const u8 *hkey, const u8 hfunc)
1219{
1220        int rc = 0, i, j;
1221        struct be_adapter *adapter = netdev_priv(netdev);
1222        u8 rsstable[RSS_INDIR_TABLE_LEN];
1223
1224        /* We do not allow change in unsupported parameters */
1225        if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
1226                return -EOPNOTSUPP;
1227
1228        if (indir) {
1229                struct be_rx_obj *rxo;
1230
1231                for (i = 0; i < RSS_INDIR_TABLE_LEN; i++) {
1232                        j = indir[i];
1233                        rxo = &adapter->rx_obj[j];
1234                        rsstable[i] = rxo->rss_id;
1235                        adapter->rss_info.rss_queue[i] = j;
1236                }
1237        } else {
1238                memcpy(rsstable, adapter->rss_info.rsstable,
1239                       RSS_INDIR_TABLE_LEN);
1240        }
1241
1242        if (!hkey)
1243                hkey =  adapter->rss_info.rss_hkey;
1244
1245        rc = be_cmd_rss_config(adapter, rsstable,
1246                               adapter->rss_info.rss_flags,
1247                               RSS_INDIR_TABLE_LEN, hkey);
1248        if (rc) {
1249                adapter->rss_info.rss_flags = RSS_ENABLE_NONE;
1250                return -EIO;
1251        }
1252        memcpy(adapter->rss_info.rss_hkey, hkey, RSS_HASH_KEY_LEN);
1253        memcpy(adapter->rss_info.rsstable, rsstable,
1254               RSS_INDIR_TABLE_LEN);
1255        return 0;
1256}
1257
1258static int be_get_module_info(struct net_device *netdev,
1259                              struct ethtool_modinfo *modinfo)
1260{
1261        struct be_adapter *adapter = netdev_priv(netdev);
1262        u8 page_data[PAGE_DATA_LEN];
1263        int status;
1264
1265        if (!check_privilege(adapter, MAX_PRIVILEGES))
1266                return -EOPNOTSUPP;
1267
1268        status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
1269                                                   page_data);
1270        if (!status) {
1271                if (!page_data[SFP_PLUS_SFF_8472_COMP]) {
1272                        modinfo->type = ETH_MODULE_SFF_8079;
1273                        modinfo->eeprom_len = PAGE_DATA_LEN;
1274                } else {
1275                        modinfo->type = ETH_MODULE_SFF_8472;
1276                        modinfo->eeprom_len = 2 * PAGE_DATA_LEN;
1277                }
1278        }
1279        return be_cmd_status(status);
1280}
1281
1282static int be_get_module_eeprom(struct net_device *netdev,
1283                                struct ethtool_eeprom *eeprom, u8 *data)
1284{
1285        struct be_adapter *adapter = netdev_priv(netdev);
1286        int status;
1287
1288        if (!check_privilege(adapter, MAX_PRIVILEGES))
1289                return -EOPNOTSUPP;
1290
1291        status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
1292                                                   data);
1293        if (status)
1294                goto err;
1295
1296        if (eeprom->offset + eeprom->len > PAGE_DATA_LEN) {
1297                status = be_cmd_read_port_transceiver_data(adapter,
1298                                                           TR_PAGE_A2,
1299                                                           data +
1300                                                           PAGE_DATA_LEN);
1301                if (status)
1302                        goto err;
1303        }
1304        if (eeprom->offset)
1305                memcpy(data, data + eeprom->offset, eeprom->len);
1306err:
1307        return be_cmd_status(status);
1308}
1309
1310const struct ethtool_ops be_ethtool_ops = {
1311        .get_settings = be_get_settings,
1312        .get_drvinfo = be_get_drvinfo,
1313        .get_wol = be_get_wol,
1314        .set_wol = be_set_wol,
1315        .get_link = ethtool_op_get_link,
1316        .get_eeprom_len = be_get_eeprom_len,
1317        .get_eeprom = be_read_eeprom,
1318        .get_coalesce = be_get_coalesce,
1319        .set_coalesce = be_set_coalesce,
1320        .get_ringparam = be_get_ringparam,
1321        .get_pauseparam = be_get_pauseparam,
1322        .set_pauseparam = be_set_pauseparam,
1323        .get_strings = be_get_stat_strings,
1324        .set_phys_id = be_set_phys_id,
1325        .set_dump = be_set_dump,
1326        .get_msglevel = be_get_msg_level,
1327        .set_msglevel = be_set_msg_level,
1328        .get_sset_count = be_get_sset_count,
1329        .get_ethtool_stats = be_get_ethtool_stats,
1330        .get_regs_len = be_get_reg_len,
1331        .get_regs = be_get_regs,
1332        .flash_device = be_do_flash,
1333        .self_test = be_self_test,
1334        .get_rxnfc = be_get_rxnfc,
1335        .set_rxnfc = be_set_rxnfc,
1336        .get_rxfh_indir_size = be_get_rxfh_indir_size,
1337        .get_rxfh_key_size = be_get_rxfh_key_size,
1338        .get_rxfh = be_get_rxfh,
1339        .set_rxfh = be_set_rxfh,
1340        .get_channels = be_get_channels,
1341        .set_channels = be_set_channels,
1342        .get_module_info = be_get_module_info,
1343        .get_module_eeprom = be_get_module_eeprom
1344};
1345