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                        goto error;
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) {
1075error:
1076                dev_err(&adapter->pdev->dev,
1077                        "LB Test: failed, TX[%d], RX[%d]\n", i, cnt);
1078                if (mode != QLCNIC_ILB_MODE)
1079                        dev_warn(&adapter->pdev->dev,
1080                                 "WARNING: Please check loopback cable\n");
1081                return -1;
1082        }
1083        return 0;
1084}
1085
1086static int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
1087{
1088        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1089        int drv_tx_rings = adapter->drv_tx_rings;
1090        int drv_sds_rings = adapter->drv_sds_rings;
1091        struct qlcnic_host_sds_ring *sds_ring;
1092        struct qlcnic_hardware_context *ahw = adapter->ahw;
1093        int loop = 0;
1094        int ret;
1095
1096        if (qlcnic_83xx_check(adapter))
1097                return qlcnic_83xx_loopback_test(netdev, mode);
1098
1099        if (!(ahw->capabilities & QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK)) {
1100                dev_info(&adapter->pdev->dev,
1101                         "Firmware do not support loopback test\n");
1102                return -EOPNOTSUPP;
1103        }
1104
1105        dev_warn(&adapter->pdev->dev, "%s loopback test in progress\n",
1106                 mode == QLCNIC_ILB_MODE ? "internal" : "external");
1107        if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1108                dev_warn(&adapter->pdev->dev,
1109                         "Loopback test not supported in nonprivileged mode\n");
1110                return 0;
1111        }
1112
1113        if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
1114                return -EBUSY;
1115
1116        ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST);
1117        if (ret)
1118                goto clear_it;
1119
1120        sds_ring = &adapter->recv_ctx->sds_rings[0];
1121        ret = qlcnic_set_lb_mode(adapter, mode);
1122        if (ret)
1123                goto free_res;
1124
1125        ahw->diag_cnt = 0;
1126        do {
1127                msleep(500);
1128                qlcnic_process_rcv_ring_diag(sds_ring);
1129                if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
1130                        netdev_info(netdev,
1131                                    "Firmware didn't sent link up event to loopback request\n");
1132                        ret = -ETIMEDOUT;
1133                        goto free_res;
1134                } else if (adapter->ahw->diag_cnt) {
1135                        ret = adapter->ahw->diag_cnt;
1136                        goto free_res;
1137                }
1138        } while (!QLCNIC_IS_LB_CONFIGURED(ahw->loopback_state));
1139
1140        ret = qlcnic_do_lb_test(adapter, mode);
1141
1142        qlcnic_clear_lb_mode(adapter, mode);
1143
1144 free_res:
1145        qlcnic_diag_free_res(netdev, drv_sds_rings);
1146
1147 clear_it:
1148        adapter->drv_sds_rings = drv_sds_rings;
1149        adapter->drv_tx_rings = drv_tx_rings;
1150        clear_bit(__QLCNIC_RESETTING, &adapter->state);
1151        return ret;
1152}
1153
1154static void
1155qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
1156                     u64 *data)
1157{
1158        memset(data, 0, sizeof(u64) * QLCNIC_TEST_LEN);
1159
1160        data[0] = qlcnic_reg_test(dev);
1161        if (data[0])
1162                eth_test->flags |= ETH_TEST_FL_FAILED;
1163
1164        data[1] = (u64) qlcnic_test_link(dev);
1165        if (data[1])
1166                eth_test->flags |= ETH_TEST_FL_FAILED;
1167
1168        if (eth_test->flags & ETH_TEST_FL_OFFLINE) {
1169                data[2] = qlcnic_irq_test(dev);
1170                if (data[2])
1171                        eth_test->flags |= ETH_TEST_FL_FAILED;
1172
1173                data[3] = qlcnic_loopback_test(dev, QLCNIC_ILB_MODE);
1174                if (data[3])
1175                        eth_test->flags |= ETH_TEST_FL_FAILED;
1176
1177                if (eth_test->flags & ETH_TEST_FL_EXTERNAL_LB) {
1178                        data[4] = qlcnic_loopback_test(dev, QLCNIC_ELB_MODE);
1179                        if (data[4])
1180                                eth_test->flags |= ETH_TEST_FL_FAILED;
1181                        eth_test->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE;
1182                }
1183
1184                data[5] = qlcnic_eeprom_test(dev);
1185                if (data[5])
1186                        eth_test->flags |= ETH_TEST_FL_FAILED;
1187        }
1188}
1189
1190static void
1191qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 *data)
1192{
1193        struct qlcnic_adapter *adapter = netdev_priv(dev);
1194        int index, i, num_stats;
1195
1196        switch (stringset) {
1197        case ETH_SS_TEST:
1198                memcpy(data, *qlcnic_gstrings_test,
1199                       QLCNIC_TEST_LEN * ETH_GSTRING_LEN);
1200                break;
1201        case ETH_SS_STATS:
1202                num_stats = ARRAY_SIZE(qlcnic_tx_queue_stats_strings);
1203                for (i = 0; i < adapter->drv_tx_rings; i++) {
1204                        for (index = 0; index < num_stats; index++) {
1205                                sprintf(data, "tx_queue_%d %s", i,
1206                                        qlcnic_tx_queue_stats_strings[index]);
1207                                data += ETH_GSTRING_LEN;
1208                        }
1209                }
1210
1211                for (index = 0; index < QLCNIC_STATS_LEN; index++) {
1212                        memcpy(data + index * ETH_GSTRING_LEN,
1213                               qlcnic_gstrings_stats[index].stat_string,
1214                               ETH_GSTRING_LEN);
1215                }
1216
1217                if (qlcnic_83xx_check(adapter)) {
1218                        num_stats = ARRAY_SIZE(qlcnic_83xx_tx_stats_strings);
1219                        for (i = 0; i < num_stats; i++, index++)
1220                                memcpy(data + index * ETH_GSTRING_LEN,
1221                                       qlcnic_83xx_tx_stats_strings[i],
1222                                       ETH_GSTRING_LEN);
1223                        num_stats = ARRAY_SIZE(qlcnic_83xx_mac_stats_strings);
1224                        for (i = 0; i < num_stats; i++, index++)
1225                                memcpy(data + index * ETH_GSTRING_LEN,
1226                                       qlcnic_83xx_mac_stats_strings[i],
1227                                       ETH_GSTRING_LEN);
1228                        num_stats = ARRAY_SIZE(qlcnic_83xx_rx_stats_strings);
1229                        for (i = 0; i < num_stats; i++, index++)
1230                                memcpy(data + index * ETH_GSTRING_LEN,
1231                                       qlcnic_83xx_rx_stats_strings[i],
1232                                       ETH_GSTRING_LEN);
1233                        return;
1234                } else {
1235                        num_stats = ARRAY_SIZE(qlcnic_83xx_mac_stats_strings);
1236                        for (i = 0; i < num_stats; i++, index++)
1237                                memcpy(data + index * ETH_GSTRING_LEN,
1238                                       qlcnic_83xx_mac_stats_strings[i],
1239                                       ETH_GSTRING_LEN);
1240                }
1241                if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
1242                        return;
1243                num_stats = ARRAY_SIZE(qlcnic_device_gstrings_stats);
1244                for (i = 0; i < num_stats; index++, i++) {
1245                        memcpy(data + index * ETH_GSTRING_LEN,
1246                               qlcnic_device_gstrings_stats[i],
1247                               ETH_GSTRING_LEN);
1248                }
1249        }
1250}
1251
1252static u64 *qlcnic_fill_stats(u64 *data, void *stats, int type)
1253{
1254        if (type == QLCNIC_MAC_STATS) {
1255                struct qlcnic_mac_statistics *mac_stats =
1256                                        (struct qlcnic_mac_statistics *)stats;
1257                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_frames);
1258                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_bytes);
1259                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_mcast_pkts);
1260                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_bcast_pkts);
1261                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_pause_cnt);
1262                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_ctrl_pkt);
1263                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_64b_pkts);
1264                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_127b_pkts);
1265                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_255b_pkts);
1266                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_511b_pkts);
1267                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_1023b_pkts);
1268                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_lt_1518b_pkts);
1269                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_tx_gt_1518b_pkts);
1270                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_frames);
1271                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_bytes);
1272                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_mcast_pkts);
1273                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_bcast_pkts);
1274                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_pause_cnt);
1275                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_ctrl_pkt);
1276                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_64b_pkts);
1277                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_127b_pkts);
1278                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_255b_pkts);
1279                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_511b_pkts);
1280                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_1023b_pkts);
1281                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_lt_1518b_pkts);
1282                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_gt_1518b_pkts);
1283                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_error);
1284                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_small);
1285                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_length_large);
1286                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_jabber);
1287                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_dropped);
1288                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_rx_crc_error);
1289                *data++ = QLCNIC_FILL_STATS(mac_stats->mac_align_error);
1290        } else if (type == QLCNIC_ESW_STATS) {
1291                struct __qlcnic_esw_statistics *esw_stats =
1292                                (struct __qlcnic_esw_statistics *)stats;
1293                *data++ = QLCNIC_FILL_STATS(esw_stats->unicast_frames);
1294                *data++ = QLCNIC_FILL_STATS(esw_stats->multicast_frames);
1295                *data++ = QLCNIC_FILL_STATS(esw_stats->broadcast_frames);
1296                *data++ = QLCNIC_FILL_STATS(esw_stats->dropped_frames);
1297                *data++ = QLCNIC_FILL_STATS(esw_stats->errors);
1298                *data++ = QLCNIC_FILL_STATS(esw_stats->local_frames);
1299                *data++ = QLCNIC_FILL_STATS(esw_stats->numbytes);
1300        }
1301        return data;
1302}
1303
1304void qlcnic_update_stats(struct qlcnic_adapter *adapter)
1305{
1306        struct qlcnic_tx_queue_stats tx_stats;
1307        struct qlcnic_host_tx_ring *tx_ring;
1308        int ring;
1309
1310        memset(&tx_stats, 0, sizeof(tx_stats));
1311        for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
1312                tx_ring = &adapter->tx_ring[ring];
1313                tx_stats.xmit_on += tx_ring->tx_stats.xmit_on;
1314                tx_stats.xmit_off += tx_ring->tx_stats.xmit_off;
1315                tx_stats.xmit_called += tx_ring->tx_stats.xmit_called;
1316                tx_stats.xmit_finished += tx_ring->tx_stats.xmit_finished;
1317                tx_stats.tx_bytes += tx_ring->tx_stats.tx_bytes;
1318        }
1319
1320        adapter->stats.xmit_on = tx_stats.xmit_on;
1321        adapter->stats.xmit_off = tx_stats.xmit_off;
1322        adapter->stats.xmitcalled = tx_stats.xmit_called;
1323        adapter->stats.xmitfinished = tx_stats.xmit_finished;
1324        adapter->stats.txbytes = tx_stats.tx_bytes;
1325}
1326
1327static u64 *qlcnic_fill_tx_queue_stats(u64 *data, void *stats)
1328{
1329        struct qlcnic_host_tx_ring *tx_ring;
1330
1331        tx_ring = (struct qlcnic_host_tx_ring *)stats;
1332
1333        *data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.xmit_on);
1334        *data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.xmit_off);
1335        *data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.xmit_called);
1336        *data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.xmit_finished);
1337        *data++ = QLCNIC_FILL_STATS(tx_ring->tx_stats.tx_bytes);
1338
1339        return data;
1340}
1341
1342static void qlcnic_get_ethtool_stats(struct net_device *dev,
1343                                     struct ethtool_stats *stats, u64 *data)
1344{
1345        struct qlcnic_adapter *adapter = netdev_priv(dev);
1346        struct qlcnic_host_tx_ring *tx_ring;
1347        struct qlcnic_esw_statistics port_stats;
1348        struct qlcnic_mac_statistics mac_stats;
1349        int index, ret, length, size, ring;
1350        char *p;
1351
1352        memset(data, 0, stats->n_stats * sizeof(u64));
1353
1354        for (ring = 0, index = 0; ring < adapter->drv_tx_rings; ring++) {
1355                if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC) {
1356                        tx_ring = &adapter->tx_ring[ring];
1357                        data = qlcnic_fill_tx_queue_stats(data, tx_ring);
1358                        qlcnic_update_stats(adapter);
1359                } else {
1360                        data += QLCNIC_TX_STATS_LEN;
1361                }
1362        }
1363
1364        length = QLCNIC_STATS_LEN;
1365        for (index = 0; index < length; index++) {
1366                p = (char *)adapter + qlcnic_gstrings_stats[index].stat_offset;
1367                size = qlcnic_gstrings_stats[index].sizeof_stat;
1368                *data++ = (size == sizeof(u64)) ? (*(u64 *)p) : ((*(u32 *)p));
1369        }
1370
1371        if (qlcnic_83xx_check(adapter)) {
1372                if (adapter->ahw->linkup)
1373                        qlcnic_83xx_get_stats(adapter, data);
1374                return;
1375        } else {
1376                /* Retrieve MAC statistics from firmware */
1377                memset(&mac_stats, 0, sizeof(struct qlcnic_mac_statistics));
1378                qlcnic_get_mac_stats(adapter, &mac_stats);
1379                data = qlcnic_fill_stats(data, &mac_stats, QLCNIC_MAC_STATS);
1380        }
1381
1382        if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
1383                return;
1384
1385        memset(&port_stats, 0, sizeof(struct qlcnic_esw_statistics));
1386        ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
1387                        QLCNIC_QUERY_RX_COUNTER, &port_stats.rx);
1388        if (ret)
1389                return;
1390
1391        data = qlcnic_fill_stats(data, &port_stats.rx, QLCNIC_ESW_STATS);
1392        ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
1393                        QLCNIC_QUERY_TX_COUNTER, &port_stats.tx);
1394        if (ret)
1395                return;
1396
1397        qlcnic_fill_stats(data, &port_stats.tx, QLCNIC_ESW_STATS);
1398}
1399
1400static int qlcnic_set_led(struct net_device *dev,
1401                          enum ethtool_phys_id_state state)
1402{
1403        struct qlcnic_adapter *adapter = netdev_priv(dev);
1404        int drv_sds_rings = adapter->drv_sds_rings;
1405        int err = -EIO, active = 1;
1406
1407        if (qlcnic_83xx_check(adapter))
1408                return qlcnic_83xx_set_led(dev, state);
1409
1410        if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1411                netdev_warn(dev, "LED test not supported for non "
1412                                "privilege function\n");
1413                return -EOPNOTSUPP;
1414        }
1415
1416        switch (state) {
1417        case ETHTOOL_ID_ACTIVE:
1418                if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state))
1419                        return -EBUSY;
1420
1421                if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1422                        break;
1423
1424                if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
1425                        if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
1426                                break;
1427                        set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
1428                }
1429
1430                if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0) {
1431                        err = 0;
1432                        break;
1433                }
1434
1435                dev_err(&adapter->pdev->dev,
1436                        "Failed to set LED blink state.\n");
1437                break;
1438
1439        case ETHTOOL_ID_INACTIVE:
1440                active = 0;
1441
1442                if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1443                        break;
1444
1445                if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
1446                        if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST))
1447                                break;
1448                        set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
1449                }
1450
1451                if (adapter->nic_ops->config_led(adapter, 0, 0xf))
1452                        dev_err(&adapter->pdev->dev,
1453                                "Failed to reset LED blink state.\n");
1454
1455                break;
1456
1457        default:
1458                return -EINVAL;
1459        }
1460
1461        if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
1462                qlcnic_diag_free_res(dev, drv_sds_rings);
1463
1464        if (!active || err)
1465                clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
1466
1467        return err;
1468}
1469
1470static void
1471qlcnic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1472{
1473        struct qlcnic_adapter *adapter = netdev_priv(dev);
1474        u32 wol_cfg;
1475        int err = 0;
1476
1477        if (qlcnic_83xx_check(adapter))
1478                return;
1479        wol->supported = 0;
1480        wol->wolopts = 0;
1481
1482        wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV, &err);
1483        if (err == -EIO)
1484                return;
1485        if (wol_cfg & (1UL << adapter->portnum))
1486                wol->supported |= WAKE_MAGIC;
1487
1488        wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG, &err);
1489        if (wol_cfg & (1UL << adapter->portnum))
1490                wol->wolopts |= WAKE_MAGIC;
1491}
1492
1493static int
1494qlcnic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1495{
1496        struct qlcnic_adapter *adapter = netdev_priv(dev);
1497        u32 wol_cfg;
1498        int err = 0;
1499
1500        if (qlcnic_83xx_check(adapter))
1501                return -EOPNOTSUPP;
1502        if (wol->wolopts & ~WAKE_MAGIC)
1503                return -EINVAL;
1504
1505        wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV, &err);
1506        if (err == -EIO)
1507                return err;
1508        if (!(wol_cfg & (1 << adapter->portnum)))
1509                return -EOPNOTSUPP;
1510
1511        wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG, &err);
1512        if (err == -EIO)
1513                return err;
1514        if (wol->wolopts & WAKE_MAGIC)
1515                wol_cfg |= 1UL << adapter->portnum;
1516        else
1517                wol_cfg &= ~(1UL << adapter->portnum);
1518
1519        QLCWR32(adapter, QLCNIC_WOL_CONFIG, wol_cfg);
1520
1521        return 0;
1522}
1523
1524/*
1525 * Set the coalescing parameters. Currently only normal is supported.
1526 * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the
1527 * firmware coalescing to default.
1528 */
1529static int qlcnic_set_intr_coalesce(struct net_device *netdev,
1530                        struct ethtool_coalesce *ethcoal)
1531{
1532        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1533        int err;
1534
1535        if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
1536                return -EINVAL;
1537
1538        /*
1539        * Return Error if unsupported values or
1540        * unsupported parameters are set.
1541        */
1542        if (ethcoal->rx_coalesce_usecs > 0xffff ||
1543            ethcoal->rx_max_coalesced_frames > 0xffff ||
1544            ethcoal->tx_coalesce_usecs > 0xffff ||
1545            ethcoal->tx_max_coalesced_frames > 0xffff)
1546                return -EINVAL;
1547
1548        err = qlcnic_config_intr_coalesce(adapter, ethcoal);
1549
1550        return err;
1551}
1552
1553static int qlcnic_get_intr_coalesce(struct net_device *netdev,
1554                        struct ethtool_coalesce *ethcoal)
1555{
1556        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1557
1558        if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
1559                return -EINVAL;
1560
1561        ethcoal->rx_coalesce_usecs = adapter->ahw->coal.rx_time_us;
1562        ethcoal->rx_max_coalesced_frames = adapter->ahw->coal.rx_packets;
1563        ethcoal->tx_coalesce_usecs = adapter->ahw->coal.tx_time_us;
1564        ethcoal->tx_max_coalesced_frames = adapter->ahw->coal.tx_packets;
1565
1566        return 0;
1567}
1568
1569static u32 qlcnic_get_msglevel(struct net_device *netdev)
1570{
1571        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1572
1573        return adapter->ahw->msg_enable;
1574}
1575
1576static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl)
1577{
1578        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1579
1580        adapter->ahw->msg_enable = msglvl;
1581}
1582
1583int qlcnic_enable_fw_dump_state(struct qlcnic_adapter *adapter)
1584{
1585        struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1586        u32 val;
1587
1588        if (qlcnic_84xx_check(adapter)) {
1589                if (qlcnic_83xx_lock_driver(adapter))
1590                        return -EBUSY;
1591
1592                val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
1593                val &= ~QLC_83XX_IDC_DISABLE_FW_DUMP;
1594                QLCWRX(adapter->ahw, QLC_83XX_IDC_CTRL, val);
1595
1596                qlcnic_83xx_unlock_driver(adapter);
1597        } else {
1598                fw_dump->enable = true;
1599        }
1600
1601        dev_info(&adapter->pdev->dev, "FW dump enabled\n");
1602
1603        return 0;
1604}
1605
1606static int qlcnic_disable_fw_dump_state(struct qlcnic_adapter *adapter)
1607{
1608        struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1609        u32 val;
1610
1611        if (qlcnic_84xx_check(adapter)) {
1612                if (qlcnic_83xx_lock_driver(adapter))
1613                        return -EBUSY;
1614
1615                val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
1616                val |= QLC_83XX_IDC_DISABLE_FW_DUMP;
1617                QLCWRX(adapter->ahw, QLC_83XX_IDC_CTRL, val);
1618
1619                qlcnic_83xx_unlock_driver(adapter);
1620        } else {
1621                fw_dump->enable = false;
1622        }
1623
1624        dev_info(&adapter->pdev->dev, "FW dump disabled\n");
1625
1626        return 0;
1627}
1628
1629bool qlcnic_check_fw_dump_state(struct qlcnic_adapter *adapter)
1630{
1631        struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1632        bool state;
1633        u32 val;
1634
1635        if (qlcnic_84xx_check(adapter)) {
1636                val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL);
1637                state = (val & QLC_83XX_IDC_DISABLE_FW_DUMP) ? false : true;
1638        } else {
1639                state = fw_dump->enable;
1640        }
1641
1642        return state;
1643}
1644
1645static int
1646qlcnic_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
1647{
1648        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1649        struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1650
1651        if (!fw_dump->tmpl_hdr) {
1652                netdev_err(adapter->netdev, "FW Dump not supported\n");
1653                return -ENOTSUPP;
1654        }
1655
1656        if (fw_dump->clr)
1657                dump->len = fw_dump->tmpl_hdr_size + fw_dump->size;
1658        else
1659                dump->len = 0;
1660
1661        if (!qlcnic_check_fw_dump_state(adapter))
1662                dump->flag = ETH_FW_DUMP_DISABLE;
1663        else
1664                dump->flag = fw_dump->cap_mask;
1665
1666        dump->version = adapter->fw_version;
1667        return 0;
1668}
1669
1670static int
1671qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
1672                        void *buffer)
1673{
1674        int i, copy_sz;
1675        u32 *hdr_ptr;
1676        __le32 *data;
1677        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1678        struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1679
1680        if (!fw_dump->tmpl_hdr) {
1681                netdev_err(netdev, "FW Dump not supported\n");
1682                return -ENOTSUPP;
1683        }
1684
1685        if (!fw_dump->clr) {
1686                netdev_info(netdev, "Dump not available\n");
1687                return -EINVAL;
1688        }
1689
1690        /* Copy template header first */
1691        copy_sz = fw_dump->tmpl_hdr_size;
1692        hdr_ptr = (u32 *)fw_dump->tmpl_hdr;
1693        data = buffer;
1694        for (i = 0; i < copy_sz/sizeof(u32); i++)
1695                *data++ = cpu_to_le32(*hdr_ptr++);
1696
1697        /* Copy captured dump data */
1698        memcpy(buffer + copy_sz, fw_dump->data, fw_dump->size);
1699        dump->len = copy_sz + fw_dump->size;
1700        dump->flag = fw_dump->cap_mask;
1701
1702        /* Free dump area once data has been captured */
1703        vfree(fw_dump->data);
1704        fw_dump->data = NULL;
1705        fw_dump->clr = 0;
1706        netdev_info(netdev, "extracted the FW dump Successfully\n");
1707        return 0;
1708}
1709
1710static int qlcnic_set_dump_mask(struct qlcnic_adapter *adapter, u32 mask)
1711{
1712        struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1713        struct net_device *netdev = adapter->netdev;
1714
1715        if (!qlcnic_check_fw_dump_state(adapter)) {
1716                netdev_info(netdev,
1717                            "Can not change driver mask to 0x%x. FW dump not enabled\n",
1718                            mask);
1719                return -EOPNOTSUPP;
1720        }
1721
1722        fw_dump->cap_mask = mask;
1723
1724        /* Store new capture mask in template header as well*/
1725        qlcnic_store_cap_mask(adapter, fw_dump->tmpl_hdr, mask);
1726
1727        netdev_info(netdev, "Driver mask changed to: 0x%x\n", mask);
1728        return 0;
1729}
1730
1731static int
1732qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
1733{
1734        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1735        struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
1736        bool valid_mask = false;
1737        int i, ret = 0;
1738
1739        switch (val->flag) {
1740        case QLCNIC_FORCE_FW_DUMP_KEY:
1741                if (!fw_dump->tmpl_hdr) {
1742                        netdev_err(netdev, "FW dump not supported\n");
1743                        ret = -EOPNOTSUPP;
1744                        break;
1745                }
1746
1747                if (!qlcnic_check_fw_dump_state(adapter)) {
1748                        netdev_info(netdev, "FW dump not enabled\n");
1749                        ret = -EOPNOTSUPP;
1750                        break;
1751                }
1752
1753                if (fw_dump->clr) {
1754                        netdev_info(netdev,
1755                                    "Previous dump not cleared, not forcing dump\n");
1756                        break;
1757                }
1758
1759                netdev_info(netdev, "Forcing a FW dump\n");
1760                qlcnic_dev_request_reset(adapter, val->flag);
1761                break;
1762        case QLCNIC_DISABLE_FW_DUMP:
1763                if (!fw_dump->tmpl_hdr) {
1764                        netdev_err(netdev, "FW dump not supported\n");
1765                        ret = -EOPNOTSUPP;
1766                        break;
1767                }
1768
1769                ret = qlcnic_disable_fw_dump_state(adapter);
1770                break;
1771
1772        case QLCNIC_ENABLE_FW_DUMP:
1773                if (!fw_dump->tmpl_hdr) {
1774                        netdev_err(netdev, "FW dump not supported\n");
1775                        ret = -EOPNOTSUPP;
1776                        break;
1777                }
1778
1779                ret = qlcnic_enable_fw_dump_state(adapter);
1780                break;
1781
1782        case QLCNIC_FORCE_FW_RESET:
1783                netdev_info(netdev, "Forcing a FW reset\n");
1784                qlcnic_dev_request_reset(adapter, val->flag);
1785                adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
1786                break;
1787
1788        case QLCNIC_SET_QUIESCENT:
1789        case QLCNIC_RESET_QUIESCENT:
1790                if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state))
1791                        netdev_info(netdev, "Device is in non-operational state\n");
1792                break;
1793
1794        default:
1795                if (!fw_dump->tmpl_hdr) {
1796                        netdev_err(netdev, "FW dump not supported\n");
1797                        ret = -EOPNOTSUPP;
1798                        break;
1799                }
1800
1801                for (i = 0; i < ARRAY_SIZE(qlcnic_fw_dump_level); i++) {
1802                        if (val->flag == qlcnic_fw_dump_level[i]) {
1803                                valid_mask = true;
1804                                break;
1805                        }
1806                }
1807
1808                if (valid_mask) {
1809                        ret = qlcnic_set_dump_mask(adapter, val->flag);
1810                } else {
1811                        netdev_info(netdev, "Invalid dump level: 0x%x\n",
1812                                    val->flag);
1813                        ret = -EINVAL;
1814                }
1815        }
1816        return ret;
1817}
1818
1819const struct ethtool_ops qlcnic_ethtool_ops = {
1820        .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
1821                                     ETHTOOL_COALESCE_MAX_FRAMES,
1822        .get_drvinfo = qlcnic_get_drvinfo,
1823        .get_regs_len = qlcnic_get_regs_len,
1824        .get_regs = qlcnic_get_regs,
1825        .get_link = ethtool_op_get_link,
1826        .get_eeprom_len = qlcnic_get_eeprom_len,
1827        .get_eeprom = qlcnic_get_eeprom,
1828        .get_ringparam = qlcnic_get_ringparam,
1829        .set_ringparam = qlcnic_set_ringparam,
1830        .get_channels = qlcnic_get_channels,
1831        .set_channels = qlcnic_set_channels,
1832        .get_pauseparam = qlcnic_get_pauseparam,
1833        .set_pauseparam = qlcnic_set_pauseparam,
1834        .get_wol = qlcnic_get_wol,
1835        .set_wol = qlcnic_set_wol,
1836        .self_test = qlcnic_diag_test,
1837        .get_strings = qlcnic_get_strings,
1838        .get_ethtool_stats = qlcnic_get_ethtool_stats,
1839        .get_sset_count = qlcnic_get_sset_count,
1840        .get_coalesce = qlcnic_get_intr_coalesce,
1841        .set_coalesce = qlcnic_set_intr_coalesce,
1842        .set_phys_id = qlcnic_set_led,
1843        .set_msglevel = qlcnic_set_msglevel,
1844        .get_msglevel = qlcnic_get_msglevel,
1845        .get_dump_flag = qlcnic_get_dump_flag,
1846        .get_dump_data = qlcnic_get_dump_data,
1847        .set_dump = qlcnic_set_dump,
1848        .get_link_ksettings = qlcnic_get_link_ksettings,
1849        .set_link_ksettings = qlcnic_set_link_ksettings,
1850};
1851
1852const struct ethtool_ops qlcnic_sriov_vf_ethtool_ops = {
1853        .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
1854                                     ETHTOOL_COALESCE_MAX_FRAMES,
1855        .get_drvinfo            = qlcnic_get_drvinfo,
1856        .get_regs_len           = qlcnic_get_regs_len,
1857        .get_regs               = qlcnic_get_regs,
1858        .get_link               = ethtool_op_get_link,
1859        .get_eeprom_len         = qlcnic_get_eeprom_len,
1860        .get_eeprom             = qlcnic_get_eeprom,
1861        .get_ringparam          = qlcnic_get_ringparam,
1862        .set_ringparam          = qlcnic_set_ringparam,
1863        .get_channels           = qlcnic_get_channels,
1864        .get_pauseparam         = qlcnic_get_pauseparam,
1865        .get_wol                = qlcnic_get_wol,
1866        .get_strings            = qlcnic_get_strings,
1867        .get_ethtool_stats      = qlcnic_get_ethtool_stats,
1868        .get_sset_count         = qlcnic_get_sset_count,
1869        .get_coalesce           = qlcnic_get_intr_coalesce,
1870        .set_coalesce           = qlcnic_set_intr_coalesce,
1871        .set_msglevel           = qlcnic_set_msglevel,
1872        .get_msglevel           = qlcnic_get_msglevel,
1873        .get_link_ksettings     = qlcnic_get_link_ksettings,
1874};
1875
1876const struct ethtool_ops qlcnic_ethtool_failed_ops = {
1877        .get_drvinfo            = qlcnic_get_drvinfo,
1878        .set_msglevel           = qlcnic_set_msglevel,
1879        .get_msglevel           = qlcnic_get_msglevel,
1880        .set_dump               = qlcnic_set_dump,
1881        .get_link_ksettings     = qlcnic_get_link_ksettings,
1882};
1883