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