linux/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * QLogic qlcnic NIC Driver
   4 * Copyright (c) 2009-2013 QLogic Corporation
   5 */
   6
   7#include <linux/types.h>
   8#include <linux/delay.h>
   9#include <linux/pci.h>
  10#include <linux/io.h>
  11#include <linux/netdevice.h>
  12#include <linux/ethtool.h>
  13
  14#include "qlcnic.h"
  15
  16struct qlcnic_stats {
  17        char stat_string[ETH_GSTRING_LEN];
  18        int sizeof_stat;
  19        int stat_offset;
  20};
  21
  22#define QLC_SIZEOF(m) sizeof_field(struct qlcnic_adapter, m)
  23#define QLC_OFF(m) offsetof(struct qlcnic_adapter, m)
  24static const u32 qlcnic_fw_dump_level[] = {
  25        0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff
  26};
  27
  28static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
  29        {"xmit_on", QLC_SIZEOF(stats.xmit_on), QLC_OFF(stats.xmit_on)},
  30        {"xmit_off", QLC_SIZEOF(stats.xmit_off), QLC_OFF(stats.xmit_off)},
  31        {"xmit_called", QLC_SIZEOF(stats.xmitcalled),
  32         QLC_OFF(stats.xmitcalled)},
  33        {"xmit_finished", QLC_SIZEOF(stats.xmitfinished),
  34         QLC_OFF(stats.xmitfinished)},
  35        {"tx dma map error", QLC_SIZEOF(stats.tx_dma_map_error),
  36         QLC_OFF(stats.tx_dma_map_error)},
  37        {"tx_bytes", QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)},
  38        {"tx_dropped", QLC_SIZEOF(stats.txdropped), QLC_OFF(stats.txdropped)},
  39        {"rx dma map error", QLC_SIZEOF(stats.rx_dma_map_error),
  40         QLC_OFF(stats.rx_dma_map_error)},
  41        {"rx_pkts", QLC_SIZEOF(stats.rx_pkts), QLC_OFF(stats.rx_pkts)},
  42        {"rx_bytes", QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)},
  43        {"rx_dropped", QLC_SIZEOF(stats.rxdropped), QLC_OFF(stats.rxdropped)},
  44        {"null rxbuf", QLC_SIZEOF(stats.null_rxbuf), QLC_OFF(stats.null_rxbuf)},
  45        {"csummed", QLC_SIZEOF(stats.csummed), QLC_OFF(stats.csummed)},
  46        {"lro_pkts", QLC_SIZEOF(stats.lro_pkts), QLC_OFF(stats.lro_pkts)},
  47        {"lrobytes", QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)},
  48        {"lso_frames", QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)},
  49        {"encap_lso_frames", QLC_SIZEOF(stats.encap_lso_frames),
  50         QLC_OFF(stats.encap_lso_frames)},
  51        {"encap_tx_csummed", QLC_SIZEOF(stats.encap_tx_csummed),
  52         QLC_OFF(stats.encap_tx_csummed)},
  53        {"encap_rx_csummed", QLC_SIZEOF(stats.encap_rx_csummed),
  54         QLC_OFF(stats.encap_rx_csummed)},
  55        {"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure),
  56         QLC_OFF(stats.skb_alloc_failure)},
  57        {"mac_filter_limit_overrun", QLC_SIZEOF(stats.mac_filter_limit_overrun),
  58         QLC_OFF(stats.mac_filter_limit_overrun)},
  59        {"spurious intr", QLC_SIZEOF(stats.spurious_intr),
  60         QLC_OFF(stats.spurious_intr)},
  61        {"mbx spurious intr", QLC_SIZEOF(stats.mbx_spurious_intr),
  62         QLC_OFF(stats.mbx_spurious_intr)},
  63};
  64
  65static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {
  66        "tx unicast frames",
  67        "tx multicast frames",
  68        "tx broadcast frames",
  69        "tx dropped frames",
  70        "tx errors",
  71        "tx local frames",
  72        "tx numbytes",
  73        "rx unicast frames",
  74        "rx multicast frames",
  75        "rx broadcast frames",
  76        "rx dropped frames",
  77        "rx errors",
  78        "rx local frames",
  79        "rx numbytes",
  80};
  81
  82static const char qlcnic_83xx_tx_stats_strings[][ETH_GSTRING_LEN] = {
  83        "ctx_tx_bytes",
  84        "ctx_tx_pkts",
  85        "ctx_tx_errors",
  86        "ctx_tx_dropped_pkts",
  87        "ctx_tx_num_buffers",
  88};
  89
  90static const char qlcnic_83xx_mac_stats_strings[][ETH_GSTRING_LEN] = {
  91        "mac_tx_frames",
  92        "mac_tx_bytes",
  93        "mac_tx_mcast_pkts",
  94        "mac_tx_bcast_pkts",
  95        "mac_tx_pause_cnt",
  96        "mac_tx_ctrl_pkt",
  97        "mac_tx_lt_64b_pkts",
  98        "mac_tx_lt_127b_pkts",
  99        "mac_tx_lt_255b_pkts",
 100        "mac_tx_lt_511b_pkts",
 101        "mac_tx_lt_1023b_pkts",
 102        "mac_tx_lt_1518b_pkts",
 103        "mac_tx_gt_1518b_pkts",
 104        "mac_rx_frames",
 105        "mac_rx_bytes",
 106        "mac_rx_mcast_pkts",
 107        "mac_rx_bcast_pkts",
 108        "mac_rx_pause_cnt",
 109        "mac_rx_ctrl_pkt",
 110        "mac_rx_lt_64b_pkts",
 111        "mac_rx_lt_127b_pkts",
 112        "mac_rx_lt_255b_pkts",
 113        "mac_rx_lt_511b_pkts",
 114        "mac_rx_lt_1023b_pkts",
 115        "mac_rx_lt_1518b_pkts",
 116        "mac_rx_gt_1518b_pkts",
 117        "mac_rx_length_error",
 118        "mac_rx_length_small",
 119        "mac_rx_length_large",
 120        "mac_rx_jabber",
 121        "mac_rx_dropped",
 122        "mac_crc_error",
 123        "mac_align_error",
 124        "eswitch_frames",
 125        "eswitch_bytes",
 126        "eswitch_multicast_frames",
 127        "eswitch_broadcast_frames",
 128        "eswitch_unicast_frames",
 129        "eswitch_error_free_frames",
 130        "eswitch_error_free_bytes",
 131};
 132
 133#define QLCNIC_STATS_LEN        ARRAY_SIZE(qlcnic_gstrings_stats)
 134
 135static const char qlcnic_tx_queue_stats_strings[][ETH_GSTRING_LEN] = {
 136        "xmit_on",
 137        "xmit_off",
 138        "xmit_called",
 139        "xmit_finished",
 140        "tx_bytes",
 141};
 142
 143#define QLCNIC_TX_STATS_LEN     ARRAY_SIZE(qlcnic_tx_queue_stats_strings)
 144
 145static const char qlcnic_83xx_rx_stats_strings[][ETH_GSTRING_LEN] = {
 146        "ctx_rx_bytes",
 147        "ctx_rx_pkts",
 148        "ctx_lro_pkt_cnt",
 149        "ctx_ip_csum_error",
 150        "ctx_rx_pkts_wo_ctx",
 151        "ctx_rx_pkts_drop_wo_sds_on_card",
 152        "ctx_rx_pkts_drop_wo_sds_on_host",
 153        "ctx_rx_osized_pkts",
 154        "ctx_rx_pkts_dropped_wo_rds",
 155        "ctx_rx_unexpected_mcast_pkts",
 156        "ctx_invalid_mac_address",
 157        "ctx_rx_rds_ring_prim_attempted",
 158        "ctx_rx_rds_ring_prim_success",
 159        "ctx_num_lro_flows_added",
 160        "ctx_num_lro_flows_removed",
 161        "ctx_num_lro_flows_active",
 162        "ctx_pkts_dropped_unknown",
 163};
 164
 165static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = {
 166        "Register_Test_on_offline",
 167        "Link_Test_on_offline",
 168        "Interrupt_Test_offline",
 169        "Internal_Loopback_offline",
 170        "External_Loopback_offline",
 171        "EEPROM_Test_offline"
 172};
 173
 174#define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test)
 175
 176static inline int qlcnic_82xx_statistics(struct qlcnic_adapter *adapter)
 177{
 178        return ARRAY_SIZE(qlcnic_gstrings_stats) +
 179               ARRAY_SIZE(qlcnic_83xx_mac_stats_strings) +
 180               QLCNIC_TX_STATS_LEN * adapter->drv_tx_rings;
 181}
 182
 183static inline int qlcnic_83xx_statistics(struct qlcnic_adapter *adapter)
 184{
 185        return ARRAY_SIZE(qlcnic_gstrings_stats) +
 186               ARRAY_SIZE(qlcnic_83xx_tx_stats_strings) +
 187               ARRAY_SIZE(qlcnic_83xx_mac_stats_strings) +
 188               ARRAY_SIZE(qlcnic_83xx_rx_stats_strings) +
 189               QLCNIC_TX_STATS_LEN * adapter->drv_tx_rings;
 190}
 191
 192static int qlcnic_dev_statistics_len(struct qlcnic_adapter *adapter)
 193{
 194        int len = -1;
 195
 196        if (qlcnic_82xx_check(adapter)) {
 197                len = qlcnic_82xx_statistics(adapter);
 198                if (adapter->flags & QLCNIC_ESWITCH_ENABLED)
 199                        len += ARRAY_SIZE(qlcnic_device_gstrings_stats);
 200        } else if (qlcnic_83xx_check(adapter)) {
 201                len = qlcnic_83xx_statistics(adapter);
 202        }
 203
 204        return len;
 205}
 206
 207#define QLCNIC_TX_INTR_NOT_CONFIGURED   0X78563412
 208
 209#define QLCNIC_MAX_EEPROM_LEN   1024
 210
 211static const u32 diag_registers[] = {
 212        QLCNIC_CMDPEG_STATE,
 213        QLCNIC_RCVPEG_STATE,
 214        QLCNIC_FW_CAPABILITIES,
 215        QLCNIC_CRB_DRV_ACTIVE,
 216        QLCNIC_CRB_DEV_STATE,
 217        QLCNIC_CRB_DRV_STATE,
 218        QLCNIC_CRB_DRV_SCRATCH,
 219        QLCNIC_CRB_DEV_PARTITION_INFO,
 220        QLCNIC_CRB_DRV_IDC_VER,
 221        QLCNIC_PEG_ALIVE_COUNTER,
 222        QLCNIC_PEG_HALT_STATUS1,
 223        QLCNIC_PEG_HALT_STATUS2,
 224        -1
 225};
 226
 227
 228static const u32 ext_diag_registers[] = {
 229        CRB_XG_STATE_P3P,
 230        ISR_INT_STATE_REG,
 231        QLCNIC_CRB_PEG_NET_0+0x3c,
 232        QLCNIC_CRB_PEG_NET_1+0x3c,
 233        QLCNIC_CRB_PEG_NET_2+0x3c,
 234        QLCNIC_CRB_PEG_NET_4+0x3c,
 235        -1
 236};
 237
 238#define QLCNIC_MGMT_API_VERSION 3
 239#define QLCNIC_ETHTOOL_REGS_VER 4
 240
 241static inline int qlcnic_get_ring_regs_len(struct qlcnic_adapter *adapter)
 242{
 243        int ring_regs_cnt = (adapter->drv_tx_rings * 5) +
 244                            (adapter->max_rds_rings * 2) +
 245                            (adapter->drv_sds_rings * 3) + 5;
 246        return ring_regs_cnt * sizeof(u32);
 247}
 248
 249static int qlcnic_get_regs_len(struct net_device *dev)
 250{
 251        struct qlcnic_adapter *adapter = netdev_priv(dev);
 252        u32 len;
 253
 254        if (qlcnic_83xx_check(adapter))
 255                len = qlcnic_83xx_get_regs_len(adapter);
 256        else
 257                len = sizeof(ext_diag_registers) + sizeof(diag_registers);
 258
 259        len += ((QLCNIC_DEV_INFO_SIZE + 2) * sizeof(u32));
 260        len += qlcnic_get_ring_regs_len(adapter);
 261        return len;
 262}
 263
 264static int qlcnic_get_eeprom_len(struct net_device *dev)
 265{
 266        return QLCNIC_FLASH_TOTAL_SIZE;
 267}
 268
 269static void
 270qlcnic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
 271{
 272        struct qlcnic_adapter *adapter = netdev_priv(dev);
 273        u32 fw_major, fw_minor, fw_build;
 274        fw_major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR);
 275        fw_minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR);
 276        fw_build = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB);
 277        snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
 278                "%d.%d.%d", fw_major, fw_minor, fw_build);
 279
 280        strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
 281                sizeof(drvinfo->bus_info));
 282        strlcpy(drvinfo->driver, qlcnic_driver_name, sizeof(drvinfo->driver));
 283        strlcpy(drvinfo->version, QLCNIC_LINUX_VERSIONID,
 284                sizeof(drvinfo->version));
 285}
 286
 287static int qlcnic_82xx_get_link_ksettings(struct qlcnic_adapter *adapter,
 288                                          struct ethtool_link_ksettings *ecmd)
 289{
 290        struct qlcnic_hardware_context *ahw = adapter->ahw;
 291        u32 speed, reg;
 292        int check_sfp_module = 0, err = 0;
 293        u16 pcifn = ahw->pci_func;
 294        u32 supported, advertising;
 295
 296        /* read which mode */
 297        if (adapter->ahw->port_type == QLCNIC_GBE) {
 298                supported = (SUPPORTED_10baseT_Half |
 299                                   SUPPORTED_10baseT_Full |
 300                                   SUPPORTED_100baseT_Half |
 301                                   SUPPORTED_100baseT_Full |
 302                                   SUPPORTED_1000baseT_Half |
 303                                   SUPPORTED_1000baseT_Full);
 304
 305                advertising = (ADVERTISED_100baseT_Half |
 306                                     ADVERTISED_100baseT_Full |
 307                                     ADVERTISED_1000baseT_Half |
 308                                     ADVERTISED_1000baseT_Full);
 309
 310                ecmd->base.speed = adapter->ahw->link_speed;
 311                ecmd->base.duplex = adapter->ahw->link_duplex;
 312                ecmd->base.autoneg = adapter->ahw->link_autoneg;
 313
 314        } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
 315                u32 val = 0;
 316                val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR, &err);
 317
 318                if (val == QLCNIC_PORT_MODE_802_3_AP) {
 319                        supported = SUPPORTED_1000baseT_Full;
 320                        advertising = ADVERTISED_1000baseT_Full;
 321                } else {
 322                        supported = SUPPORTED_10000baseT_Full;
 323                        advertising = ADVERTISED_10000baseT_Full;
 324                }
 325
 326                if (netif_running(adapter->netdev) && ahw->has_link_events) {
 327                        if (ahw->linkup) {
 328                                reg = QLCRD32(adapter,
 329                                              P3P_LINK_SPEED_REG(pcifn), &err);
 330                                speed = P3P_LINK_SPEED_VAL(pcifn, reg);
 331                                ahw->link_speed = speed * P3P_LINK_SPEED_MHZ;
 332                        }
 333
 334                        ecmd->base.speed = ahw->link_speed;
 335                        ecmd->base.autoneg = ahw->link_autoneg;
 336                        ecmd->base.duplex = ahw->link_duplex;
 337                        goto skip;
 338                }
 339
 340                ecmd->base.speed = SPEED_UNKNOWN;
 341                ecmd->base.duplex = DUPLEX_UNKNOWN;
 342                ecmd->base.autoneg = AUTONEG_DISABLE;
 343        } else
 344                return -EIO;
 345
 346skip:
 347        ecmd->base.phy_address = adapter->ahw->physical_port;
 348
 349        switch (adapter->ahw->board_type) {
 350        case QLCNIC_BRDTYPE_P3P_REF_QG:
 351        case QLCNIC_BRDTYPE_P3P_4_GB:
 352        case QLCNIC_BRDTYPE_P3P_4_GB_MM:
 353                supported |= SUPPORTED_Autoneg;
 354                advertising |= ADVERTISED_Autoneg;
 355                fallthrough;
 356        case QLCNIC_BRDTYPE_P3P_10G_CX4:
 357        case QLCNIC_BRDTYPE_P3P_10G_CX4_LP:
 358        case QLCNIC_BRDTYPE_P3P_10000_BASE_T:
 359                supported |= SUPPORTED_TP;
 360                advertising |= ADVERTISED_TP;
 361                ecmd->base.port = PORT_TP;
 362                ecmd->base.autoneg =  adapter->ahw->link_autoneg;
 363                break;
 364        case QLCNIC_BRDTYPE_P3P_IMEZ:
 365        case QLCNIC_BRDTYPE_P3P_XG_LOM:
 366        case QLCNIC_BRDTYPE_P3P_HMEZ:
 367                supported |= SUPPORTED_MII;
 368                advertising |= ADVERTISED_MII;
 369                ecmd->base.port = PORT_MII;
 370                ecmd->base.autoneg = AUTONEG_DISABLE;
 371                break;
 372        case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS:
 373        case QLCNIC_BRDTYPE_P3P_10G_SFP_CT:
 374        case QLCNIC_BRDTYPE_P3P_10G_SFP_QT:
 375                advertising |= ADVERTISED_TP;
 376                supported |= SUPPORTED_TP;
 377                check_sfp_module = netif_running(adapter->netdev) &&
 378                                   ahw->has_link_events;
 379                fallthrough;
 380        case QLCNIC_BRDTYPE_P3P_10G_XFP:
 381                supported |= SUPPORTED_FIBRE;
 382                advertising |= ADVERTISED_FIBRE;
 383                ecmd->base.port = PORT_FIBRE;
 384                ecmd->base.autoneg = AUTONEG_DISABLE;
 385                break;
 386        case QLCNIC_BRDTYPE_P3P_10G_TP:
 387                if (adapter->ahw->port_type == QLCNIC_XGBE) {
 388                        ecmd->base.autoneg = AUTONEG_DISABLE;
 389                        supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
 390                        advertising |=
 391                                (ADVERTISED_FIBRE | ADVERTISED_TP);
 392                        ecmd->base.port = PORT_FIBRE;
 393                        check_sfp_module = netif_running(adapter->netdev) &&
 394                                           ahw->has_link_events;
 395                } else {
 396                        ecmd->base.autoneg = AUTONEG_ENABLE;
 397                        supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
 398                        advertising |=
 399                                (ADVERTISED_TP | ADVERTISED_Autoneg);
 400                        ecmd->base.port = PORT_TP;
 401                }
 402                break;
 403        default:
 404                dev_err(&adapter->pdev->dev, "Unsupported board model %d\n",
 405                        adapter->ahw->board_type);
 406                return -EIO;
 407        }
 408
 409        if (check_sfp_module) {
 410                switch (adapter->ahw->module_type) {
 411                case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
 412                case LINKEVENT_MODULE_OPTICAL_SRLR:
 413                case LINKEVENT_MODULE_OPTICAL_LRM:
 414                case LINKEVENT_MODULE_OPTICAL_SFP_1G:
 415                        ecmd->base.port = PORT_FIBRE;
 416                        break;
 417                case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
 418                case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
 419                case LINKEVENT_MODULE_TWINAX:
 420                        ecmd->base.port = PORT_TP;
 421                        break;
 422                default:
 423                        ecmd->base.port = PORT_OTHER;
 424                }
 425        }
 426
 427        ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.supported,
 428                                                supported);
 429        ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.advertising,
 430                                                advertising);
 431
 432        return 0;
 433}
 434
 435static int qlcnic_get_link_ksettings(struct net_device *dev,
 436                                     struct ethtool_link_ksettings *ecmd)
 437{
 438        struct qlcnic_adapter *adapter = netdev_priv(dev);
 439
 440        if (qlcnic_82xx_check(adapter))
 441                return qlcnic_82xx_get_link_ksettings(adapter, ecmd);
 442        else if (qlcnic_83xx_check(adapter))
 443                return qlcnic_83xx_get_link_ksettings(adapter, ecmd);
 444
 445        return -EIO;
 446}
 447
 448
 449static int qlcnic_set_port_config(struct qlcnic_adapter *adapter,
 450                                  const struct ethtool_link_ksettings *ecmd)
 451{
 452        u32 ret = 0, config = 0;
 453        /* read which mode */
 454        if (ecmd->base.duplex)
 455                config |= 0x1;
 456
 457        if (ecmd->base.autoneg)
 458                config |= 0x2;
 459
 460        switch (ecmd->base.speed) {
 461        case SPEED_10:
 462                config |= (0 << 8);
 463                break;
 464        case SPEED_100:
 465                config |= (1 << 8);
 466                break;
 467        case SPEED_1000:
 468                config |= (10 << 8);
 469                break;
 470        default:
 471                return -EIO;
 472        }
 473
 474        ret = qlcnic_fw_cmd_set_port(adapter, config);
 475
 476        if (ret == QLCNIC_RCODE_NOT_SUPPORTED)
 477                return -EOPNOTSUPP;
 478        else if (ret)
 479                return -EIO;
 480        return ret;
 481}
 482
 483static int qlcnic_set_link_ksettings(struct net_device *dev,
 484                                     const struct ethtool_link_ksettings *ecmd)
 485{
 486        u32 ret = 0;
 487        struct qlcnic_adapter *adapter = netdev_priv(dev);
 488
 489        if (qlcnic_83xx_check(adapter))
 490                qlcnic_83xx_get_port_type(adapter);
 491
 492        if (adapter->ahw->port_type != QLCNIC_GBE)
 493                return -EOPNOTSUPP;
 494
 495        if (qlcnic_83xx_check(adapter))
 496                ret = qlcnic_83xx_set_link_ksettings(adapter, ecmd);
 497        else
 498                ret = qlcnic_set_port_config(adapter, ecmd);
 499
 500        if (!ret)
 501                return ret;
 502
 503        adapter->ahw->link_speed = ecmd->base.speed;
 504        adapter->ahw->link_duplex = ecmd->base.duplex;
 505        adapter->ahw->link_autoneg = ecmd->base.autoneg;
 506
 507        if (!netif_running(dev))
 508                return 0;
 509
 510        dev->netdev_ops->ndo_stop(dev);
 511        return dev->netdev_ops->ndo_open(dev);
 512}
 513
 514static int qlcnic_82xx_get_registers(struct qlcnic_adapter *adapter,
 515                                     u32 *regs_buff)
 516{
 517        int i, j = 0, err = 0;
 518
 519        for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[j] != -1; j++, i++)
 520                regs_buff[i] = QLC_SHARED_REG_RD32(adapter, diag_registers[j]);
 521        j = 0;
 522        while (ext_diag_registers[j] != -1)
 523                regs_buff[i++] = QLCRD32(adapter, ext_diag_registers[j++],
 524                                         &err);
 525        return i;
 526}
 527
 528static void
 529qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
 530{
 531        struct qlcnic_adapter *adapter = netdev_priv(dev);
 532        struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
 533        struct qlcnic_host_sds_ring *sds_ring;
 534        struct qlcnic_host_rds_ring *rds_rings;
 535        struct qlcnic_host_tx_ring *tx_ring;
 536        u32 *regs_buff = p;
 537        int ring, i = 0;
 538
 539        memset(p, 0, qlcnic_get_regs_len(dev));
 540
 541        regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) |
 542                (adapter->ahw->revision_id << 16) | (adapter->pdev)->device;
 543
 544        regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff));
 545        regs_buff[1] = QLCNIC_MGMT_API_VERSION;
 546
 547        if (adapter->ahw->capabilities & QLC_83XX_ESWITCH_CAPABILITY)
 548                regs_buff[2] = adapter->ahw->max_vnic_func;
 549
 550        if (qlcnic_82xx_check(adapter))
 551                i = qlcnic_82xx_get_registers(adapter, regs_buff);
 552        else
 553                i = qlcnic_83xx_get_registers(adapter, regs_buff);
 554
 555        if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
 556                return;
 557
 558        /* Marker btw regs and TX ring count */
 559        regs_buff[i++] = 0xFFEFCDAB;
 560
 561        regs_buff[i++] = adapter->drv_tx_rings; /* No. of TX ring */
 562        for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
 563                tx_ring = &adapter->tx_ring[ring];
 564                regs_buff[i++] = le32_to_cpu(*(tx_ring->hw_consumer));
 565                regs_buff[i++] = tx_ring->sw_consumer;
 566                regs_buff[i++] = readl(tx_ring->crb_cmd_producer);
 567                regs_buff[i++] = tx_ring->producer;
 568                if (tx_ring->crb_intr_mask)
 569                        regs_buff[i++] = readl(tx_ring->crb_intr_mask);
 570                else
 571                        regs_buff[i++] = QLCNIC_TX_INTR_NOT_CONFIGURED;
 572        }
 573
 574        regs_buff[i++] = adapter->max_rds_rings; /* No. of RX ring */
 575        for (ring = 0; ring < adapter->max_rds_rings; ring++) {
 576                rds_rings = &recv_ctx->rds_rings[ring];
 577                regs_buff[i++] = readl(rds_rings->crb_rcv_producer);
 578                regs_buff[i++] = rds_rings->producer;
 579        }
 580
 581        regs_buff[i++] = adapter->drv_sds_rings; /* No. of SDS ring */
 582        for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
 583                sds_ring = &(recv_ctx->sds_rings[ring]);
 584                regs_buff[i++] = readl(sds_ring->crb_sts_consumer);
 585                regs_buff[i++] = sds_ring->consumer;
 586                regs_buff[i++] = readl(sds_ring->crb_intr_mask);
 587        }
 588}
 589
 590static u32 qlcnic_test_link(struct net_device *dev)
 591{
 592        struct qlcnic_adapter *adapter = netdev_priv(dev);
 593        int err = 0;
 594        u32 val;
 595
 596        if (qlcnic_83xx_check(adapter)) {
 597                val = qlcnic_83xx_test_link(adapter);
 598                return (val & 1) ? 0 : 1;
 599        }
 600        val = QLCRD32(adapter, CRB_XG_STATE_P3P, &err);
 601        if (err == -EIO)
 602                return err;
 603        val = XG_LINK_STATE_P3P(adapter->ahw->pci_func, val);
 604        return (val == XG_LINK_UP_P3P) ? 0 : 1;
 605}
 606
 607static int
 608qlcnic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
 609                      u8 *bytes)
 610{
 611        struct qlcnic_adapter *adapter = netdev_priv(dev);
 612        int offset;
 613        int ret = -1;
 614
 615        if (qlcnic_83xx_check(adapter))
 616                return 0;
 617        if (eeprom->len == 0)
 618                return -EINVAL;
 619
 620        eeprom->magic = (adapter->pdev)->vendor |
 621                        ((adapter->pdev)->device << 16);
 622        offset = eeprom->offset;
 623
 624        if (qlcnic_82xx_check(adapter))
 625                ret = qlcnic_rom_fast_read_words(adapter, offset, bytes,
 626                                                 eeprom->len);
 627        if (ret < 0)
 628                return ret;
 629
 630        return 0;
 631}
 632
 633static void
 634qlcnic_get_ringparam(struct net_device *dev,
 635                struct ethtool_ringparam *ring)
 636{
 637        struct qlcnic_adapter *adapter = netdev_priv(dev);
 638
 639        ring->rx_pending = adapter->num_rxd;
 640        ring->rx_jumbo_pending = adapter->num_jumbo_rxd;
 641        ring->tx_pending = adapter->num_txd;
 642
 643        ring->rx_max_pending = adapter->max_rxd;
 644        ring->rx_jumbo_max_pending = adapter->max_jumbo_rxd;
 645        ring->tx_max_pending = MAX_CMD_DESCRIPTORS;
 646}
 647
 648static u32
 649qlcnic_validate_ringparam(u32 val, u32 min, u32 max, char *r_name)
 650{
 651        u32 num_desc;
 652        num_desc = max(val, min);
 653        num_desc = min(num_desc, max);
 654        num_desc = roundup_pow_of_two(num_desc);
 655
 656        if (val != num_desc) {
 657                printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n",
 658                       qlcnic_driver_name, r_name, num_desc, val);
 659        }
 660
 661        return num_desc;
 662}
 663
 664static int
 665qlcnic_set_ringparam(struct net_device *dev,
 666                struct ethtool_ringparam *ring)
 667{
 668        struct qlcnic_adapter *adapter = netdev_priv(dev);
 669        u16 num_rxd, num_jumbo_rxd, num_txd;
 670
 671        if (ring->rx_mini_pending)
 672                return -EOPNOTSUPP;
 673
 674        num_rxd = qlcnic_validate_ringparam(ring->rx_pending,
 675                        MIN_RCV_DESCRIPTORS, adapter->max_rxd, "rx");
 676
 677        num_jumbo_rxd = qlcnic_validate_ringparam(ring->rx_jumbo_pending,
 678                        MIN_JUMBO_DESCRIPTORS, adapter->max_jumbo_rxd,
 679                                                "rx jumbo");
 680
 681        num_txd = qlcnic_validate_ringparam(ring->tx_pending,
 682                        MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx");
 683
 684        if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd &&
 685                        num_jumbo_rxd == adapter->num_jumbo_rxd)
 686                return 0;
 687
 688        adapter->num_rxd = num_rxd;
 689        adapter->num_jumbo_rxd = num_jumbo_rxd;
 690        adapter->num_txd = num_txd;
 691
 692        return qlcnic_reset_context(adapter);
 693}
 694
 695static int qlcnic_validate_ring_count(struct qlcnic_adapter *adapter,
 696                                      u8 rx_ring, u8 tx_ring)
 697{
 698        if (rx_ring == 0 || tx_ring == 0)
 699                return -EINVAL;
 700
 701        if (rx_ring != 0) {
 702                if (rx_ring > adapter->max_sds_rings) {
 703                        netdev_err(adapter->netdev,
 704                                   "Invalid ring count, SDS ring count %d should not be greater than max %d driver sds rings.\n",
 705                                   rx_ring, adapter->max_sds_rings);
 706                        return -EINVAL;
 707                }
 708        }
 709
 710         if (tx_ring != 0) {
 711                if (tx_ring > adapter->max_tx_rings) {
 712                        netdev_err(adapter->netdev,
 713                                   "Invalid ring count, Tx ring count %d should not be greater than max %d driver Tx rings.\n",
 714                                   tx_ring, adapter->max_tx_rings);
 715                        return -EINVAL;
 716                }
 717        }
 718
 719        return 0;
 720}
 721
 722static void qlcnic_get_channels(struct net_device *dev,
 723                struct ethtool_channels *channel)
 724{
 725        struct qlcnic_adapter *adapter = netdev_priv(dev);
 726
 727        channel->max_rx = adapter->max_sds_rings;
 728        channel->max_tx = adapter->max_tx_rings;
 729        channel->rx_count = adapter->drv_sds_rings;
 730        channel->tx_count = adapter->drv_tx_rings;
 731}
 732
 733static int qlcnic_set_channels(struct net_device *dev,
 734                               struct ethtool_channels *channel)
 735{
 736        struct qlcnic_adapter *adapter = netdev_priv(dev);
 737        int err;
 738
 739        if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
 740                netdev_err(dev, "No RSS/TSS support in non MSI-X mode\n");
 741                return -EINVAL;
 742        }
 743
 744        if (channel->other_count || channel->combined_count)
 745                return -EINVAL;
 746
 747        err = qlcnic_validate_ring_count(adapter, channel->rx_count,
 748                                         channel->tx_count);
 749        if (err)
 750                return err;
 751
 752        if (adapter->drv_sds_rings != channel->rx_count) {
 753                err = qlcnic_validate_rings(adapter, channel->rx_count,
 754                                            QLCNIC_RX_QUEUE);
 755                if (err) {
 756                        netdev_err(dev, "Unable to configure %u SDS rings\n",
 757                                   channel->rx_count);
 758                        return err;
 759                }
 760                adapter->drv_rss_rings = channel->rx_count;
 761        }
 762
 763        if (adapter->drv_tx_rings != channel->tx_count) {
 764                err = qlcnic_validate_rings(adapter, channel->tx_count,
 765                                            QLCNIC_TX_QUEUE);
 766                if (err) {
 767                        netdev_err(dev, "Unable to configure %u Tx rings\n",
 768                                   channel->tx_count);
 769                        return err;
 770                }
 771                adapter->drv_tss_rings = channel->tx_count;
 772        }
 773
 774        adapter->flags |= QLCNIC_TSS_RSS;
 775
 776        err = qlcnic_setup_rings(adapter);
 777        netdev_info(dev, "Allocated %d SDS rings and %d Tx rings\n",
 778                    adapter->drv_sds_rings, adapter->drv_tx_rings);
 779
 780        return err;
 781}
 782
 783static void
 784qlcnic_get_pauseparam(struct net_device *netdev,
 785                          struct ethtool_pauseparam *pause)
 786{
 787        struct qlcnic_adapter *adapter = netdev_priv(netdev);
 788        int port = adapter->ahw->physical_port;
 789        int err = 0;
 790        __u32 val;
 791
 792        if (qlcnic_83xx_check(adapter)) {
 793                qlcnic_83xx_get_pauseparam(adapter, pause);
 794                return;
 795        }
 796        if (adapter->ahw->port_type == QLCNIC_GBE) {
 797                if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
 798                        return;
 799                /* get flow control settings */
 800                val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), &err);
 801                if (err == -EIO)
 802                        return;
 803                pause->rx_pause = qlcnic_gb_get_rx_flowctl(val);
 804                val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, &err);
 805                if (err == -EIO)
 806                        return;
 807                switch (port) {
 808                case 0:
 809                        pause->tx_pause = !(qlcnic_gb_get_gb0_mask(val));
 810                        break;
 811                case 1:
 812                        pause->tx_pause = !(qlcnic_gb_get_gb1_mask(val));
 813                        break;
 814                case 2:
 815                        pause->tx_pause = !(qlcnic_gb_get_gb2_mask(val));
 816                        break;
 817                case 3:
 818                default:
 819                        pause->tx_pause = !(qlcnic_gb_get_gb3_mask(val));
 820                        break;
 821                }
 822        } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
 823                if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
 824                        return;
 825                pause->rx_pause = 1;
 826                val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, &err);
 827                if (err == -EIO)
 828                        return;
 829                if (port == 0)
 830                        pause->tx_pause = !(qlcnic_xg_get_xg0_mask(val));
 831                else
 832                        pause->tx_pause = !(qlcnic_xg_get_xg1_mask(val));
 833        } else {
 834                dev_err(&netdev->dev, "Unknown board type: %x\n",
 835                                        adapter->ahw->port_type);
 836        }
 837}
 838
 839static int
 840qlcnic_set_pauseparam(struct net_device *netdev,
 841                          struct ethtool_pauseparam *pause)
 842{
 843        struct qlcnic_adapter *adapter = netdev_priv(netdev);
 844        int port = adapter->ahw->physical_port;
 845        int err = 0;
 846        __u32 val;
 847
 848        if (qlcnic_83xx_check(adapter))
 849                return qlcnic_83xx_set_pauseparam(adapter, pause);
 850
 851        /* read mode */
 852        if (adapter->ahw->port_type == QLCNIC_GBE) {
 853                if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
 854                        return -EIO;
 855                /* set flow control */
 856                val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), &err);
 857                if (err == -EIO)
 858                        return err;
 859
 860                if (pause->rx_pause)
 861                        qlcnic_gb_rx_flowctl(val);
 862                else
 863                        qlcnic_gb_unset_rx_flowctl(val);
 864
 865                QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port),
 866                                val);
 867                QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), val);
 868                /* set autoneg */
 869                val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, &err);
 870                if (err == -EIO)
 871                        return err;
 872                switch (port) {
 873                case 0:
 874                        if (pause->tx_pause)
 875                                qlcnic_gb_unset_gb0_mask(val);
 876                        else
 877                                qlcnic_gb_set_gb0_mask(val);
 878                        break;
 879                case 1:
 880                        if (pause->tx_pause)
 881                                qlcnic_gb_unset_gb1_mask(val);
 882                        else
 883                                qlcnic_gb_set_gb1_mask(val);
 884                        break;
 885                case 2:
 886                        if (pause->tx_pause)
 887                                qlcnic_gb_unset_gb2_mask(val);
 888                        else
 889                                qlcnic_gb_set_gb2_mask(val);
 890                        break;
 891                case 3:
 892                default:
 893                        if (pause->tx_pause)
 894                                qlcnic_gb_unset_gb3_mask(val);
 895                        else
 896                                qlcnic_gb_set_gb3_mask(val);
 897                        break;
 898                }
 899                QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, val);
 900        } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
 901                if (!pause->rx_pause || pause->autoneg)
 902                        return -EOPNOTSUPP;
 903
 904                if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
 905                        return -EIO;
 906
 907                val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, &err);
 908                if (err == -EIO)
 909                        return err;
 910                if (port == 0) {
 911                        if (pause->tx_pause)
 912                                qlcnic_xg_unset_xg0_mask(val);
 913                        else
 914                                qlcnic_xg_set_xg0_mask(val);
 915                } else {
 916                        if (pause->tx_pause)
 917                                qlcnic_xg_unset_xg1_mask(val);
 918                        else
 919                                qlcnic_xg_set_xg1_mask(val);
 920                }
 921                QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, val);
 922        } else {
 923                dev_err(&netdev->dev, "Unknown board type: %x\n",
 924                                adapter->ahw->port_type);
 925        }
 926        return 0;
 927}
 928
 929static int qlcnic_reg_test(struct net_device *dev)
 930{
 931        struct qlcnic_adapter *adapter = netdev_priv(dev);
 932        u32 data_read;
 933        int err = 0;
 934
 935        if (qlcnic_83xx_check(adapter))
 936                return qlcnic_83xx_reg_test(adapter);
 937
 938        data_read = QLCRD32(adapter, QLCNIC_PCIX_PH_REG(0), &err);
 939        if (err == -EIO)
 940                return err;
 941        if ((data_read & 0xffff) != adapter->pdev->vendor)
 942                return 1;
 943
 944        return 0;
 945}
 946
 947static int qlcnic_eeprom_test(struct net_device *dev)
 948{
 949        struct qlcnic_adapter *adapter = netdev_priv(dev);
 950
 951        if (qlcnic_82xx_check(adapter))
 952                return 0;
 953
 954        return qlcnic_83xx_flash_test(adapter);
 955}
 956
 957static int qlcnic_get_sset_count(struct net_device *dev, int sset)
 958{
 959
 960        struct qlcnic_adapter *adapter = netdev_priv(dev);
 961        switch (sset) {
 962        case ETH_SS_TEST:
 963                return QLCNIC_TEST_LEN;
 964        case ETH_SS_STATS:
 965                return qlcnic_dev_statistics_len(adapter);
 966        default:
 967                return -EOPNOTSUPP;
 968        }
 969}
 970
 971static int qlcnic_irq_test(struct net_device *netdev)
 972{
 973        struct qlcnic_adapter *adapter = netdev_priv(netdev);
 974        struct qlcnic_hardware_context *ahw = adapter->ahw;
 975        struct qlcnic_cmd_args cmd;
 976        int ret, drv_sds_rings = adapter->drv_sds_rings;
 977        int drv_tx_rings = adapter->drv_tx_rings;
 978
 979        if (qlcnic_83xx_check(adapter))
 980                return qlcnic_83xx_interrupt_test(netdev);
 981
 982        if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
 983                return -EIO;
 984
 985        ret = qlcnic_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST);
 986        if (ret)
 987                goto clear_diag_irq;
 988
 989        ahw->diag_cnt = 0;
 990        ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST);
 991        if (ret)
 992                goto free_diag_res;
 993
 994        cmd.req.arg[1] = ahw->pci_func;
 995        ret = qlcnic_issue_cmd(adapter, &cmd);
 996        if (ret)
 997                goto done;
 998
 999        usleep_range(1000, 12000);
1000        ret = !ahw->diag_cnt;
1001
1002done:
1003        qlcnic_free_mbx_args(&cmd);
1004
1005free_diag_res:
1006        qlcnic_diag_free_res(netdev, drv_sds_rings);
1007
1008clear_diag_irq:
1009        adapter->drv_sds_rings = drv_sds_rings;
1010        adapter->drv_tx_rings = drv_tx_rings;
1011        clear_bit(__QLCNIC_RESETTING, &adapter->state);
1012
1013        return ret;
1014}
1015
1016#define QLCNIC_ILB_PKT_SIZE             64
1017#define QLCNIC_NUM_ILB_PKT              16
1018#define QLCNIC_ILB_MAX_RCV_LOOP         10
1019#define QLCNIC_LB_PKT_POLL_DELAY_MSEC   1
1020#define QLCNIC_LB_PKT_POLL_COUNT        20
1021
1022static void qlcnic_create_loopback_buff(unsigned char *data, u8 mac[])
1023{
1024        unsigned char random_data[] = {0xa8, 0x06, 0x45, 0x00};
1025
1026        memset(data, 0x4e, QLCNIC_ILB_PKT_SIZE);
1027
1028        memcpy(data, mac, ETH_ALEN);
1029        memcpy(data + ETH_ALEN, mac, ETH_ALEN);
1030
1031        memcpy(data + 2 * ETH_ALEN, random_data, sizeof(random_data));
1032}
1033
1034int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[])
1035{
1036        unsigned char buff[QLCNIC_ILB_PKT_SIZE];
1037        qlcnic_create_loopback_buff(buff, mac);
1038        return memcmp(data, buff, QLCNIC_ILB_PKT_SIZE);
1039}
1040
1041int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode)
1042{
1043        struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1044        struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0];
1045        struct sk_buff *skb;
1046        int i, loop, cnt = 0;
1047
1048        for (i = 0; i < QLCNIC_NUM_ILB_PKT; i++) {
1049                skb = netdev_alloc_skb(adapter->netdev, QLCNIC_ILB_PKT_SIZE);
1050                if (!skb)
1051                        break;
1052                qlcnic_create_loopback_buff(skb->data, adapter->mac_addr);
1053                skb_put(skb, QLCNIC_ILB_PKT_SIZE);
1054                adapter->ahw->diag_cnt = 0;
1055                qlcnic_xmit_frame(skb, adapter->netdev);
1056                loop = 0;
1057
1058                do {
1059                        msleep(QLCNIC_LB_PKT_POLL_DELAY_MSEC);
1060                        qlcnic_process_rcv_ring_diag(sds_ring);
1061                        if (loop++ > QLCNIC_LB_PKT_POLL_COUNT)
1062                                break;
1063                } while (!adapter->ahw->diag_cnt);
1064
1065                dev_kfree_skb_any(skb);
1066
1067                if (!adapter->ahw->diag_cnt)
1068                        dev_warn(&adapter->pdev->dev,
1069                                 "LB Test: packet #%d was not received\n",
1070                                 i + 1);
1071                else
1072                        cnt++;
1073        }
1074        if (cnt != i) {
1075                dev_err(&adapter->pdev->dev,
1076                        "LB Test: failed, TX[%d], RX[%d]\n", i, cnt);
1077                if (mode != QLCNIC_ILB_MODE)
1078                        dev_warn(&adapter->pdev->dev,
1079                                 "WARNING: Please check loopback cable\n");
1080                return -1;
1081        }
1082        return 0;
1083}
1084
1085static int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
1086{
1087        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1088        int drv_tx_rings = adapter->drv_tx_rings;
1089        int drv_sds_rings = adapter->drv_sds_rings;
1090        struct qlcnic_host_sds_ring *sds_ring;
1091        struct qlcnic_hardware_context *ahw = adapter->ahw;
1092        int loop = 0;
1093        int ret;
1094
1095        if (qlcnic_83xx_check(adapter))
1096                return qlcnic_83xx_loopback_test(netdev, mode);
1097
1098        if (!(ahw->capabilities & QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK)) {
1099                dev_info(&adapter->pdev->dev,
1100                         "Firmware do not support loopback test\n");
1101                return -EOPNOTSUPP;
1102        }
1103
1104        dev_warn(&adapter->pdev->dev, "%s loopback test in progress\n",
1105                 mode == QLCNIC_ILB_MODE ? "internal" : "external");
1106        if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1107                dev_warn(&adapter->pdev->dev,
1108                         "Loopback test not supported in nonprivileged mode\n");
1109                return 0;
1110        }
1111
1112        if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
1113                return -EBUSY;
1114
1115        ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST);
1116        if (ret)
1117                goto clear_it;
1118
1119        sds_ring = &adapter->recv_ctx->sds_rings[0];
1120        ret = qlcnic_set_lb_mode(adapter, mode);
1121        if (ret)
1122                goto free_res;
1123
1124        ahw->diag_cnt = 0;
1125        do {
1126                msleep(500);
1127                qlcnic_process_rcv_ring_diag(sds_ring);
1128                if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
1129                        netdev_info(netdev,
1130                                    "Firmware didn't sent link up event to loopback request\n");
1131                        ret = -ETIMEDOUT;
1132                        goto free_res;
1133                } else if (adapter->ahw->diag_cnt) {
1134                        ret = adapter->ahw->diag_cnt;
1135                        goto free_res;
1136                }
1137        } while (!QLCNIC_IS_LB_CONFIGURED(ahw->loopback_state));
1138
1139        ret = qlcnic_do_lb_test(adapter, mode);
1140
1141        qlcnic_clear_lb_mode(adapter, mode);
1142
1143 free_res:
1144        qlcnic_diag_free_res(netdev, drv_sds_rings);
1145
1146 clear_it:
1147        adapter->drv_sds_rings = drv_sds_rings;
1148        adapter->drv_tx_rings = drv_tx_rings;
1149        clear_bit(__QLCNIC_RESETTING, &adapter->state);
1150        return ret;
1151}
1152
1153static void
1154qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
1155                     u64 *data)
1156{
1157        memset(data, 0, sizeof(u64) * QLCNIC_TEST_LEN);
1158
1159        data[0] = qlcnic_reg_test(dev);
1160        if (data[0])
1161                eth_test->flags |= ETH_TEST_FL_FAILED;
1162
1163        data[1] = (u64) qlcnic_test_link(dev);
1164        if (data[1])
1165                eth_test->flags |= ETH_TEST_FL_FAILED;
1166
1167        if (eth_test->flags & ETH_TEST_FL_OFFLINE) {
1168                data[2] = qlcnic_irq_test(dev);
1169                if (data[2])
1170                        eth_test->flags |= ETH_TEST_FL_FAILED;
1171
1172                data[3] = qlcnic_loopback_test(dev, QLCNIC_ILB_MODE);
1173                if (data[3])
1174                        eth_test->flags |= ETH_TEST_FL_FAILED;
1175
1176                if (eth_test->flags & ETH_TEST_FL_EXTERNAL_LB) {
1177                        data[4] = qlcnic_loopback_test(dev, QLCNIC_ELB_MODE);
1178                        if (data[4])
1179                                eth_test->flags |= ETH_TEST_FL_FAILED;
1180                        eth_test->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE;
1181                }
1182
1183                data[5] = qlcnic_eeprom_test(dev);
1184                if (data[5])
1185                        eth_test->flags |= ETH_TEST_FL_FAILED;
1186        }
1187}
1188
1189static void
1190qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 *data)
1191{
1192        struct qlcnic_adapter *adapter = netdev_priv(dev);
1193        int index, i, num_stats;
1194
1195        switch (stringset) {
1196        case ETH_SS_TEST:
1197                memcpy(data, *qlcnic_gstrings_test,
1198                       QLCNIC_TEST_LEN * ETH_GSTRING_LEN);
1199                break;
1200        case ETH_SS_STATS:
1201                num_stats = ARRAY_SIZE(qlcnic_tx_queue_stats_strings);
1202                for (i = 0; i < adapter->drv_tx_rings; i++) {
1203                        for (index = 0; index < num_stats; index++) {
1204                                sprintf(data, "tx_queue_%d %s", i,
1205                                        qlcnic_tx_queue_stats_strings[index]);
1206                                data += ETH_GSTRING_LEN;
1207                        }
1208                }
1209
1210                for (index = 0; index < QLCNIC_STATS_LEN; index++) {
1211                        memcpy(data + index * ETH_GSTRING_LEN,
1212                               qlcnic_gstrings_stats[index].stat_string,
1213                               ETH_GSTRING_LEN);
1214                }
1215
1216                if (qlcnic_83xx_check(adapter)) {
1217                        num_stats = ARRAY_SIZE(qlcnic_83xx_tx_stats_strings);
1218                        for (i = 0; i < num_stats; i++, index++)
1219                                memcpy(data + index * ETH_GSTRING_LEN,
1220                                       qlcnic_83xx_tx_stats_strings[i],
1221                                       ETH_GSTRING_LEN);
1222                        num_stats = ARRAY_SIZE(qlcnic_83xx_mac_stats_strings);
1223                        for (i = 0; i < num_stats; i++, index++)
1224                                memcpy(data + index * ETH_GSTRING_LEN,
1225                                       qlcnic_83xx_mac_stats_strings[i],
1226                                       ETH_GSTRING_LEN);
1227                        num_stats = ARRAY_SIZE(qlcnic_83xx_rx_stats_strings);
1228                        for (i = 0; i < num_stats; i++, index++)
1229                                memcpy(data + index * ETH_GSTRING_LEN,
1230                                       qlcnic_83xx_rx_stats_strings[i],
1231                                       ETH_GSTRING_LEN);
1232                        return;
1233                } else {
1234                        num_stats = ARRAY_SIZE(qlcnic_83xx_mac_stats_strings);
1235                        for (i = 0; i < num_stats; i++, index++)
1236                                memcpy(data + index * ETH_GSTRING_LEN,
1237                                       qlcnic_83xx_mac_stats_strings[i],
1238                                       ETH_GSTRING_LEN);
1239                }
1240                if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
1241                        return;
1242                num_stats = ARRAY_SIZE(qlcnic_device_gstrings_stats);
1243                for (i = 0; i < num_stats; index++, i++) {
1244                        memcpy(data + index * ETH_GSTRING_LEN,
1245                               qlcnic_device_gstrings_stats[i],
1246                               ETH_GSTRING_LEN);
1247                }
1248        }
1249}
1250
1251static u64 *qlcnic_fill_stats(u64 *data, void *stats, int type)
1252{
1253        if (type == QLCNIC_MAC_STATS) {
1254                struct qlcnic_mac_statistics *mac_stats =
1255                                        (struct qlcnic_mac_statistics *)stats;
1256                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_frames);
1257                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_bytes);
1258                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_mcast_pkts);
1259                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_bcast_pkts);
1260                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_pause_cnt);
1261                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_ctrl_pkt);
1262                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_64b_pkts);
1263                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_127b_pkts);
1264                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_255b_pkts);
1265                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_511b_pkts);
1266                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_1023b_pkts);
1267                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_1518b_pkts);
1268                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_gt_1518b_pkts);
1269                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_frames);
1270                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_bytes);
1271                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_mcast_pkts);
1272                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_bcast_pkts);
1273                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_pause_cnt);
1274                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_ctrl_pkt);
1275                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_64b_pkts);
1276                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_127b_pkts);
1277                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_255b_pkts);
1278                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_511b_pkts);
1279                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_1023b_pkts);
1280                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_1518b_pkts);
1281                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_gt_1518b_pkts);
1282                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_error);
1283                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_small);
1284                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_large);
1285                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_jabber);
1286                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_dropped);
1287                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_crc_error);
1288                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_align_error);
1289        } else if (type == QLCNIC_ESW_STATS) {
1290                struct __qlcnic_esw_statistics *esw_stats =
1291                                (struct __qlcnic_esw_statistics *)stats;
1292                *data++ = QLCNIC_FILL_STATS(esw_stats->unicast_frames);
1293                *data++ = QLCNIC_FILL_STATS(esw_stats->multicast_frames);
1294                *data++ = QLCNIC_FILL_STATS(esw_stats->broadcast_frames);
1295                *data++ = QLCNIC_FILL_STATS(esw_stats->dropped_frames);
1296                *data++ = QLCNIC_FILL_STATS(esw_stats->errors);
1297                *data++ = QLCNIC_FILL_STATS(esw_stats->local_frames);
1298                *data++ = QLCNIC_FILL_STATS(esw_stats->numbytes);
1299        }
1300        return data;
1301}
1302
1303void qlcnic_update_stats(struct qlcnic_adapter *adapter)
1304{
1305        struct qlcnic_tx_queue_stats tx_stats;
1306        struct qlcnic_host_tx_ring *tx_ring;
1307        int ring;
1308
1309        memset(&tx_stats, 0, sizeof(tx_stats));
1310        for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
1311                tx_ring = &adapter->tx_ring[ring];
1312                tx_stats.xmit_on += tx_ring->tx_stats.xmit_on;
1313                tx_stats.xmit_off += tx_ring->tx_stats.xmit_off;
1314                tx_stats.xmit_called += tx_ring->tx_stats.xmit_called;
1315                tx_stats.xmit_finished += tx_ring->tx_stats.xmit_finished;
1316                tx_stats.tx_bytes += tx_ring->tx_stats.tx_bytes;
1317        }
1318
1319        adapter->stats.xmit_on = tx_stats.xmit_on;
1320        adapter->stats.xmit_off = tx_stats.xmit_off;
1321        adapter->stats.xmitcalled = tx_stats.xmit_called;
1322        adapter->stats.xmitfinished = tx_stats.xmit_finished;
1323        adapter->stats.txbytes = tx_stats.tx_bytes;
1324}
1325
1326static u64 *qlcnic_fill_tx_queue_stats(u64 *data, void *stats)
1327{
1328        struct qlcnic_host_tx_ring *tx_ring;
1329
1330        tx_ring = (struct qlcnic_host_tx_ring *)stats;
1331
1332        *data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.xmit_on);
1333        *data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.xmit_off);
1334        *data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.xmit_called);
1335        *data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.xmit_finished);
1336        *data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.tx_bytes);
1337
1338        return data;
1339}
1340
1341static void qlcnic_get_ethtool_stats(struct net_device *dev,
1342                                     struct ethtool_stats *stats, u64 *data)
1343{
1344        struct qlcnic_adapter *adapter = netdev_priv(dev);
1345        struct qlcnic_host_tx_ring *tx_ring;
1346        struct qlcnic_esw_statistics port_stats;
1347        struct qlcnic_mac_statistics mac_stats;
1348        int index, ret, length, size, ring;
1349        char *p;
1350
1351        memset(data, 0, stats->n_stats * sizeof(u64));
1352
1353        for (ring = 0, index = 0; ring < adapter->drv_tx_rings; ring++) {
1354                if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC) {
1355                        tx_ring = &adapter->tx_ring[ring];
1356                        data = qlcnic_fill_tx_queue_stats(data, tx_ring);
1357                        qlcnic_update_stats(adapter);
1358                } else {
1359                        data += QLCNIC_TX_STATS_LEN;
1360                }
1361        }
1362
1363        length = QLCNIC_STATS_LEN;
1364        for (index = 0; index < length; index++) {
1365                p = (char *)adapter + qlcnic_gstrings_stats[index].stat_offset;
1366                size = qlcnic_gstrings_stats[index].sizeof_stat;
1367                *data++ = (size == sizeof(u64)) ? (*(u64 *)p) : ((*(u32 *)p));
1368        }
1369
1370        if (qlcnic_83xx_check(adapter)) {
1371                if (adapter->ahw->linkup)
1372                        qlcnic_83xx_get_stats(adapter, data);
1373                return;
1374        } else {
1375                /* Retrieve MAC statistics from firmware */
1376                memset(&mac_stats, 0, sizeof(struct qlcnic_mac_statistics));
1377                qlcnic_get_mac_stats(adapter, &mac_stats);
1378                data = qlcnic_fill_stats(data, &mac_stats, QLCNIC_MAC_STATS);
1379        }
1380
1381        if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
1382                return;
1383
1384        memset(&port_stats, 0, sizeof(struct qlcnic_esw_statistics));
1385        ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
1386                        QLCNIC_QUERY_RX_COUNTER, &port_stats.rx);
1387        if (ret)
1388                return;
1389
1390        data = qlcnic_fill_stats(data, &port_stats.rx, QLCNIC_ESW_STATS);
1391        ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
1392                        QLCNIC_QUERY_TX_COUNTER, &port_stats.tx);
1393        if (ret)
1394                return;
1395
1396        qlcnic_fill_stats(data, &port_stats.tx, QLCNIC_ESW_STATS);
1397}
1398
1399static int qlcnic_set_led(struct net_device *dev,
1400                          enum ethtool_phys_id_state state)
1401{
1402        struct qlcnic_adapter *adapter = netdev_priv(dev);
1403        int drv_sds_rings = adapter->drv_sds_rings;
1404        int err = -EIO, active = 1;
1405
1406        if (qlcnic_83xx_check(adapter))
1407                return qlcnic_83xx_set_led(dev, state);
1408
1409        if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1410                netdev_warn(dev, "LED test not supported for non "
1411                                "privilege function\n");
1412                return -EOPNOTSUPP;
1413        }
1414
1415        switch (state) {
1416        case ETHTOOL_ID_ACTIVE:
1417                if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state))
1418                        return -EBUSY;
1419
1420                if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1421                        break;
1422
1423                if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
1424                        if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
1425                                break;
1426                        set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
1427                }
1428
1429                if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0) {
1430                        err = 0;
1431                        break;
1432                }
1433
1434                dev_err(&adapter->pdev->dev,
1435                        "Failed to set LED blink state.\n");
1436                break;
1437
1438        case ETHTOOL_ID_INACTIVE:
1439                active = 0;
1440
1441                if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1442                        break;
1443
1444                if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
1445                        if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
1446                                break;
1447                        set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
1448                }
1449
1450                if (adapter->nic_ops->config_led(adapter, 0, 0xf))
1451                        dev_err(&adapter->pdev->dev,
1452                                "Failed to reset LED blink state.\n");
1453
1454                break;
1455
1456        default:
1457                return -EINVAL;
1458        }
1459
1460        if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
1461                qlcnic_diag_free_res(dev, drv_sds_rings);
1462
1463        if (!active || err)
1464                clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
1465
1466        return err;
1467}
1468
1469static void
1470qlcnic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1471{
1472        struct qlcnic_adapter *adapter = netdev_priv(dev);
1473        u32 wol_cfg;
1474        int err = 0;
1475
1476        if (qlcnic_83xx_check(adapter))
1477                return;
1478        wol->supported = 0;
1479        wol->wolopts = 0;
1480
1481        wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV, &err);
1482        if (err == -EIO)
1483                return;
1484        if (wol_cfg & (1UL << adapter->portnum))
1485                wol->supported |= WAKE_MAGIC;
1486
1487        wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG, &err);
1488        if (wol_cfg & (1UL << adapter->portnum))
1489                wol->wolopts |= WAKE_MAGIC;
1490}
1491
1492static int
1493qlcnic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1494{
1495        struct qlcnic_adapter *adapter = netdev_priv(dev);
1496        u32 wol_cfg;
1497        int err = 0;
1498
1499        if (qlcnic_83xx_check(adapter))
1500                return -EOPNOTSUPP;
1501        if (wol->wolopts & ~WAKE_MAGIC)
1502                return -EINVAL;
1503
1504        wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV, &err);
1505        if (err == -EIO)
1506                return err;
1507        if (!(wol_cfg & (1 << adapter->portnum)))
1508                return -EOPNOTSUPP;
1509
1510        wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG, &err);
1511        if (err == -EIO)
1512                return err;
1513        if (wol->wolopts & WAKE_MAGIC)
1514                wol_cfg |= 1UL << adapter->portnum;
1515        else
1516                wol_cfg &= ~(1UL << adapter->portnum);
1517
1518        QLCWR32(adapter, QLCNIC_WOL_CONFIG, wol_cfg);
1519
1520        return 0;
1521}
1522
1523/*
1524 * Set the coalescing parameters. Currently only normal is supported.
1525 * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the
1526 * firmware coalescing to default.
1527 */
1528static int qlcnic_set_intr_coalesce(struct net_device *netdev,
1529                        struct ethtool_coalesce *ethcoal)
1530{
1531        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1532        int err;
1533
1534        if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
1535                return -EINVAL;
1536
1537        /*
1538        * Return Error if unsupported values or
1539        * unsupported parameters are set.
1540        */
1541        if (ethcoal->rx_coalesce_usecs > 0xffff ||
1542            ethcoal->rx_max_coalesced_frames > 0xffff ||
1543            ethcoal->tx_coalesce_usecs > 0xffff ||
1544            ethcoal->tx_max_coalesced_frames > 0xffff)
1545                return -EINVAL;
1546
1547        err = qlcnic_config_intr_coalesce(adapter, ethcoal);
1548
1549        return err;
1550}
1551
1552static int qlcnic_get_intr_coalesce(struct net_device *netdev,
1553                        struct ethtool_coalesce *ethcoal)
1554{
1555        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1556
1557        if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
1558                return -EINVAL;
1559
1560        ethcoal->rx_coalesce_usecs = adapter->ahw->coal.rx_time_us;
1561        ethcoal->rx_max_coalesced_frames = adapter->ahw->coal.rx_packets;
1562        ethcoal->tx_coalesce_usecs = adapter->ahw->coal.tx_time_us;
1563        ethcoal->tx_max_coalesced_frames = adapter->ahw->coal.tx_packets;
1564
1565        return 0;
1566}
1567
1568static u32 qlcnic_get_msglevel(struct net_device *netdev)
1569{
1570        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1571
1572        return adapter->ahw->msg_enable;
1573}
1574
1575static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl)
1576{
1577        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1578
1579        adapter->ahw->msg_enable = msglvl;
1580}
1581
1582int qlcnic_enable_fw_dump_state(struct qlcnic_adapter *adapter)
1583{
1584        struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1585        u32 val;
1586
1587        if (qlcnic_84xx_check(adapter)) {
1588                if (qlcnic_83xx_lock_driver(adapter))
1589                        return -EBUSY;
1590
1591                val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
1592                val &= ~QLC_83XX_IDC_DISABLE_FW_DUMP;
1593                QLCWRX(adapter->ahw, QLC_83XX_IDC_CTRL, val);
1594
1595                qlcnic_83xx_unlock_driver(adapter);
1596        } else {
1597                fw_dump->enable = true;
1598        }
1599
1600        dev_info(&adapter->pdev->dev, "FW dump enabled\n");
1601
1602        return 0;
1603}
1604
1605static int qlcnic_disable_fw_dump_state(struct qlcnic_adapter *adapter)
1606{
1607        struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1608        u32 val;
1609
1610        if (qlcnic_84xx_check(adapter)) {
1611                if (qlcnic_83xx_lock_driver(adapter))
1612                        return -EBUSY;
1613
1614                val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
1615                val |= QLC_83XX_IDC_DISABLE_FW_DUMP;
1616                QLCWRX(adapter->ahw, QLC_83XX_IDC_CTRL, val);
1617
1618                qlcnic_83xx_unlock_driver(adapter);
1619        } else {
1620                fw_dump->enable = false;
1621        }
1622
1623        dev_info(&adapter->pdev->dev, "FW dump disabled\n");
1624
1625        return 0;
1626}
1627
1628bool qlcnic_check_fw_dump_state(struct qlcnic_adapter *adapter)
1629{
1630        struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1631        bool state;
1632        u32 val;
1633
1634        if (qlcnic_84xx_check(adapter)) {
1635                val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
1636                state = (val & QLC_83XX_IDC_DISABLE_FW_DUMP) ? false : true;
1637        } else {
1638                state = fw_dump->enable;
1639        }
1640
1641        return state;
1642}
1643
1644static int
1645qlcnic_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
1646{
1647        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1648        struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1649
1650        if (!fw_dump->tmpl_hdr) {
1651                netdev_err(adapter->netdev, "FW Dump not supported\n");
1652                return -ENOTSUPP;
1653        }
1654
1655        if (fw_dump->clr)
1656                dump->len = fw_dump->tmpl_hdr_size + fw_dump->size;
1657        else
1658                dump->len = 0;
1659
1660        if (!qlcnic_check_fw_dump_state(adapter))
1661                dump->flag = ETH_FW_DUMP_DISABLE;
1662        else
1663                dump->flag = fw_dump->cap_mask;
1664
1665        dump->version = adapter->fw_version;
1666        return 0;
1667}
1668
1669static int
1670qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
1671                        void *buffer)
1672{
1673        int i, copy_sz;
1674        u32 *hdr_ptr;
1675        __le32 *data;
1676        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1677        struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1678
1679        if (!fw_dump->tmpl_hdr) {
1680                netdev_err(netdev, "FW Dump not supported\n");
1681                return -ENOTSUPP;
1682        }
1683
1684        if (!fw_dump->clr) {
1685                netdev_info(netdev, "Dump not available\n");
1686                return -EINVAL;
1687        }
1688
1689        /* Copy template header first */
1690        copy_sz = fw_dump->tmpl_hdr_size;
1691        hdr_ptr = (u32 *)fw_dump->tmpl_hdr;
1692        data = buffer;
1693        for (i = 0; i < copy_sz/sizeof(u32); i++)
1694                *data++ = cpu_to_le32(*hdr_ptr++);
1695
1696        /* Copy captured dump data */
1697        memcpy(buffer + copy_sz, fw_dump->data, fw_dump->size);
1698        dump->len = copy_sz + fw_dump->size;
1699        dump->flag = fw_dump->cap_mask;
1700
1701        /* Free dump area once data has been captured */
1702        vfree(fw_dump->data);
1703        fw_dump->data = NULL;
1704        fw_dump->clr = 0;
1705        netdev_info(netdev, "extracted the FW dump Successfully\n");
1706        return 0;
1707}
1708
1709static int qlcnic_set_dump_mask(struct qlcnic_adapter *adapter, u32 mask)
1710{
1711        struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1712        struct net_device *netdev = adapter->netdev;
1713
1714        if (!qlcnic_check_fw_dump_state(adapter)) {
1715                netdev_info(netdev,
1716                            "Can not change driver mask to 0x%x. FW dump not enabled\n",
1717                            mask);
1718                return -EOPNOTSUPP;
1719        }
1720
1721        fw_dump->cap_mask = mask;
1722
1723        /* Store new capture mask in template header as well*/
1724        qlcnic_store_cap_mask(adapter, fw_dump->tmpl_hdr, mask);
1725
1726        netdev_info(netdev, "Driver mask changed to: 0x%x\n", mask);
1727        return 0;
1728}
1729
1730static int
1731qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
1732{
1733        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1734        struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1735        bool valid_mask = false;
1736        int i, ret = 0;
1737
1738        switch (val->flag) {
1739        case QLCNIC_FORCE_FW_DUMP_KEY:
1740                if (!fw_dump->tmpl_hdr) {
1741                        netdev_err(netdev, "FW dump not supported\n");
1742                        ret = -EOPNOTSUPP;
1743                        break;
1744                }
1745
1746                if (!qlcnic_check_fw_dump_state(adapter)) {
1747                        netdev_info(netdev, "FW dump not enabled\n");
1748                        ret = -EOPNOTSUPP;
1749                        break;
1750                }
1751
1752                if (fw_dump->clr) {
1753                        netdev_info(netdev,
1754                                    "Previous dump not cleared, not forcing dump\n");
1755                        break;
1756                }
1757
1758                netdev_info(netdev, "Forcing a FW dump\n");
1759                qlcnic_dev_request_reset(adapter, val->flag);
1760                break;
1761        case QLCNIC_DISABLE_FW_DUMP:
1762                if (!fw_dump->tmpl_hdr) {
1763                        netdev_err(netdev, "FW dump not supported\n");
1764                        ret = -EOPNOTSUPP;
1765                        break;
1766                }
1767
1768                ret = qlcnic_disable_fw_dump_state(adapter);
1769                break;
1770
1771        case QLCNIC_ENABLE_FW_DUMP:
1772                if (!fw_dump->tmpl_hdr) {
1773                        netdev_err(netdev, "FW dump not supported\n");
1774                        ret = -EOPNOTSUPP;
1775                        break;
1776                }
1777
1778                ret = qlcnic_enable_fw_dump_state(adapter);
1779                break;
1780
1781        case QLCNIC_FORCE_FW_RESET:
1782                netdev_info(netdev, "Forcing a FW reset\n");
1783                qlcnic_dev_request_reset(adapter, val->flag);
1784                adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
1785                break;
1786
1787        case QLCNIC_SET_QUIESCENT:
1788        case QLCNIC_RESET_QUIESCENT:
1789                if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state))
1790                        netdev_info(netdev, "Device is in non-operational state\n");
1791                break;
1792
1793        default:
1794                if (!fw_dump->tmpl_hdr) {
1795                        netdev_err(netdev, "FW dump not supported\n");
1796                        ret = -EOPNOTSUPP;
1797                        break;
1798                }
1799
1800                for (i = 0; i < ARRAY_SIZE(qlcnic_fw_dump_level); i++) {
1801                        if (val->flag == qlcnic_fw_dump_level[i]) {
1802                                valid_mask = true;
1803                                break;
1804                        }
1805                }
1806
1807                if (valid_mask) {
1808                        ret = qlcnic_set_dump_mask(adapter, val->flag);
1809                } else {
1810                        netdev_info(netdev, "Invalid dump level: 0x%x\n",
1811                                    val->flag);
1812                        ret = -EINVAL;
1813                }
1814        }
1815        return ret;
1816}
1817
1818const struct ethtool_ops qlcnic_ethtool_ops = {
1819        .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
1820                                     ETHTOOL_COALESCE_MAX_FRAMES,
1821        .get_drvinfo = qlcnic_get_drvinfo,
1822        .get_regs_len = qlcnic_get_regs_len,
1823        .get_regs = qlcnic_get_regs,
1824        .get_link = ethtool_op_get_link,
1825        .get_eeprom_len = qlcnic_get_eeprom_len,
1826        .get_eeprom = qlcnic_get_eeprom,
1827        .get_ringparam = qlcnic_get_ringparam,
1828        .set_ringparam = qlcnic_set_ringparam,
1829        .get_channels = qlcnic_get_channels,
1830        .set_channels = qlcnic_set_channels,
1831        .get_pauseparam = qlcnic_get_pauseparam,
1832        .set_pauseparam = qlcnic_set_pauseparam,
1833        .get_wol = qlcnic_get_wol,
1834        .set_wol = qlcnic_set_wol,
1835        .self_test = qlcnic_diag_test,
1836        .get_strings = qlcnic_get_strings,
1837        .get_ethtool_stats = qlcnic_get_ethtool_stats,
1838        .get_sset_count = qlcnic_get_sset_count,
1839        .get_coalesce = qlcnic_get_intr_coalesce,
1840        .set_coalesce = qlcnic_set_intr_coalesce,
1841        .set_phys_id = qlcnic_set_led,
1842        .set_msglevel = qlcnic_set_msglevel,
1843        .get_msglevel = qlcnic_get_msglevel,
1844        .get_dump_flag = qlcnic_get_dump_flag,
1845        .get_dump_data = qlcnic_get_dump_data,
1846        .set_dump = qlcnic_set_dump,
1847        .get_link_ksettings = qlcnic_get_link_ksettings,
1848        .set_link_ksettings = qlcnic_set_link_ksettings,
1849};
1850
1851const struct ethtool_ops qlcnic_sriov_vf_ethtool_ops = {
1852        .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
1853                                     ETHTOOL_COALESCE_MAX_FRAMES,
1854        .get_drvinfo            = qlcnic_get_drvinfo,
1855        .get_regs_len           = qlcnic_get_regs_len,
1856        .get_regs               = qlcnic_get_regs,
1857        .get_link               = ethtool_op_get_link,
1858        .get_eeprom_len         = qlcnic_get_eeprom_len,
1859        .get_eeprom             = qlcnic_get_eeprom,
1860        .get_ringparam          = qlcnic_get_ringparam,
1861        .set_ringparam          = qlcnic_set_ringparam,
1862        .get_channels           = qlcnic_get_channels,
1863        .get_pauseparam         = qlcnic_get_pauseparam,
1864        .get_wol                = qlcnic_get_wol,
1865        .get_strings            = qlcnic_get_strings,
1866        .get_ethtool_stats      = qlcnic_get_ethtool_stats,
1867        .get_sset_count         = qlcnic_get_sset_count,
1868        .get_coalesce           = qlcnic_get_intr_coalesce,
1869        .set_coalesce           = qlcnic_set_intr_coalesce,
1870        .set_msglevel           = qlcnic_set_msglevel,
1871        .get_msglevel           = qlcnic_get_msglevel,
1872        .get_link_ksettings     = qlcnic_get_link_ksettings,
1873};
1874
1875const struct ethtool_ops qlcnic_ethtool_failed_ops = {
1876        .get_drvinfo            = qlcnic_get_drvinfo,
1877        .set_msglevel           = qlcnic_set_msglevel,
1878        .get_msglevel           = qlcnic_get_msglevel,
1879        .set_dump               = qlcnic_set_dump,
1880        .get_link_ksettings     = qlcnic_get_link_ksettings,
1881};
1882