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        static const 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                                    struct kernel_ethtool_coalesce *kernel_coal,
1532                                    struct netlink_ext_ack *extack)
1533{
1534        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1535        int err;
1536
1537        if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
1538                return -EINVAL;
1539
1540        /*
1541        * Return Error if unsupported values or
1542        * unsupported parameters are set.
1543        */
1544        if (ethcoal->rx_coalesce_usecs > 0xffff ||
1545            ethcoal->rx_max_coalesced_frames > 0xffff ||
1546            ethcoal->tx_coalesce_usecs > 0xffff ||
1547            ethcoal->tx_max_coalesced_frames > 0xffff)
1548                return -EINVAL;
1549
1550        err = qlcnic_config_intr_coalesce(adapter, ethcoal);
1551
1552        return err;
1553}
1554
1555static int qlcnic_get_intr_coalesce(struct net_device *netdev,
1556                                    struct ethtool_coalesce *ethcoal,
1557                                    struct kernel_ethtool_coalesce *kernel_coal,
1558                                    struct netlink_ext_ack *extack)
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        .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
1825                                     ETHTOOL_COALESCE_MAX_FRAMES,
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        .get_link_ksettings = qlcnic_get_link_ksettings,
1853        .set_link_ksettings = qlcnic_set_link_ksettings,
1854};
1855
1856const struct ethtool_ops qlcnic_sriov_vf_ethtool_ops = {
1857        .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
1858                                     ETHTOOL_COALESCE_MAX_FRAMES,
1859        .get_drvinfo            = qlcnic_get_drvinfo,
1860        .get_regs_len           = qlcnic_get_regs_len,
1861        .get_regs               = qlcnic_get_regs,
1862        .get_link               = ethtool_op_get_link,
1863        .get_eeprom_len         = qlcnic_get_eeprom_len,
1864        .get_eeprom             = qlcnic_get_eeprom,
1865        .get_ringparam          = qlcnic_get_ringparam,
1866        .set_ringparam          = qlcnic_set_ringparam,
1867        .get_channels           = qlcnic_get_channels,
1868        .get_pauseparam         = qlcnic_get_pauseparam,
1869        .get_wol                = qlcnic_get_wol,
1870        .get_strings            = qlcnic_get_strings,
1871        .get_ethtool_stats      = qlcnic_get_ethtool_stats,
1872        .get_sset_count         = qlcnic_get_sset_count,
1873        .get_coalesce           = qlcnic_get_intr_coalesce,
1874        .set_coalesce           = qlcnic_set_intr_coalesce,
1875        .set_msglevel           = qlcnic_set_msglevel,
1876        .get_msglevel           = qlcnic_get_msglevel,
1877        .get_link_ksettings     = qlcnic_get_link_ksettings,
1878};
1879
1880const struct ethtool_ops qlcnic_ethtool_failed_ops = {
1881        .get_drvinfo            = qlcnic_get_drvinfo,
1882        .set_msglevel           = qlcnic_set_msglevel,
1883        .get_msglevel           = qlcnic_get_msglevel,
1884        .set_dump               = qlcnic_set_dump,
1885        .get_link_ksettings     = qlcnic_get_link_ksettings,
1886};
1887