linux/drivers/net/qlcnic/qlcnic_ethtool.c
<<
>>
Prefs
   1/*
   2 * QLogic qlcnic NIC Driver
   3 * Copyright (c)  2009-2010 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)
  25
  26static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
  27        {"xmit_called",
  28                QLC_SIZEOF(stats.xmitcalled), QLC_OFF(stats.xmitcalled)},
  29        {"xmit_finished",
  30                QLC_SIZEOF(stats.xmitfinished), QLC_OFF(stats.xmitfinished)},
  31        {"rx_dropped",
  32                QLC_SIZEOF(stats.rxdropped), QLC_OFF(stats.rxdropped)},
  33        {"tx_dropped",
  34                QLC_SIZEOF(stats.txdropped), QLC_OFF(stats.txdropped)},
  35        {"csummed",
  36                QLC_SIZEOF(stats.csummed), QLC_OFF(stats.csummed)},
  37        {"rx_pkts",
  38                QLC_SIZEOF(stats.rx_pkts), QLC_OFF(stats.rx_pkts)},
  39        {"lro_pkts",
  40                QLC_SIZEOF(stats.lro_pkts), QLC_OFF(stats.lro_pkts)},
  41        {"rx_bytes",
  42                QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)},
  43        {"tx_bytes",
  44                QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)},
  45        {"lrobytes",
  46                QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)},
  47        {"lso_frames",
  48                QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)},
  49        {"xmit_on",
  50                QLC_SIZEOF(stats.xmit_on), QLC_OFF(stats.xmit_on)},
  51        {"xmit_off",
  52                QLC_SIZEOF(stats.xmit_off), QLC_OFF(stats.xmit_off)},
  53        {"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure),
  54                QLC_OFF(stats.skb_alloc_failure)},
  55        {"null rxbuf",
  56                QLC_SIZEOF(stats.null_rxbuf), QLC_OFF(stats.null_rxbuf)},
  57        {"rx dma map error", QLC_SIZEOF(stats.rx_dma_map_error),
  58                                         QLC_OFF(stats.rx_dma_map_error)},
  59        {"tx dma map error", QLC_SIZEOF(stats.tx_dma_map_error),
  60                                         QLC_OFF(stats.tx_dma_map_error)},
  61
  62};
  63
  64static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {
  65        "rx unicast frames",
  66        "rx multicast frames",
  67        "rx broadcast frames",
  68        "rx dropped frames",
  69        "rx errors",
  70        "rx local frames",
  71        "rx numbytes",
  72        "tx unicast frames",
  73        "tx multicast frames",
  74        "tx broadcast frames",
  75        "tx dropped frames",
  76        "tx errors",
  77        "tx local frames",
  78        "tx numbytes",
  79};
  80
  81#define QLCNIC_STATS_LEN        ARRAY_SIZE(qlcnic_gstrings_stats)
  82#define QLCNIC_DEVICE_STATS_LEN ARRAY_SIZE(qlcnic_device_gstrings_stats)
  83
  84static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = {
  85        "Register_Test_on_offline",
  86        "Link_Test_on_offline",
  87        "Interrupt_Test_offline"
  88};
  89
  90#define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test)
  91
  92#define QLCNIC_RING_REGS_COUNT  20
  93#define QLCNIC_RING_REGS_LEN    (QLCNIC_RING_REGS_COUNT * sizeof(u32))
  94#define QLCNIC_MAX_EEPROM_LEN   1024
  95
  96static const u32 diag_registers[] = {
  97        CRB_CMDPEG_STATE,
  98        CRB_RCVPEG_STATE,
  99        CRB_XG_STATE_P3P,
 100        CRB_FW_CAPABILITIES_1,
 101        ISR_INT_STATE_REG,
 102        QLCNIC_CRB_DRV_ACTIVE,
 103        QLCNIC_CRB_DEV_STATE,
 104        QLCNIC_CRB_DRV_STATE,
 105        QLCNIC_CRB_DRV_SCRATCH,
 106        QLCNIC_CRB_DEV_PARTITION_INFO,
 107        QLCNIC_CRB_DRV_IDC_VER,
 108        QLCNIC_PEG_ALIVE_COUNTER,
 109        QLCNIC_PEG_HALT_STATUS1,
 110        QLCNIC_PEG_HALT_STATUS2,
 111        QLCNIC_CRB_PEG_NET_0+0x3c,
 112        QLCNIC_CRB_PEG_NET_1+0x3c,
 113        QLCNIC_CRB_PEG_NET_2+0x3c,
 114        QLCNIC_CRB_PEG_NET_4+0x3c,
 115        -1
 116};
 117
 118#define QLCNIC_MGMT_API_VERSION 2
 119#define QLCNIC_DEV_INFO_SIZE    1
 120#define QLCNIC_ETHTOOL_REGS_VER 2
 121static int qlcnic_get_regs_len(struct net_device *dev)
 122{
 123        return sizeof(diag_registers) + QLCNIC_RING_REGS_LEN +
 124                                QLCNIC_DEV_INFO_SIZE + 1;
 125}
 126
 127static int qlcnic_get_eeprom_len(struct net_device *dev)
 128{
 129        return QLCNIC_FLASH_TOTAL_SIZE;
 130}
 131
 132static void
 133qlcnic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
 134{
 135        struct qlcnic_adapter *adapter = netdev_priv(dev);
 136        u32 fw_major, fw_minor, fw_build;
 137
 138        fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR);
 139        fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR);
 140        fw_build = QLCRD32(adapter, QLCNIC_FW_VERSION_SUB);
 141        sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build);
 142
 143        strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
 144        strlcpy(drvinfo->driver, qlcnic_driver_name, 32);
 145        strlcpy(drvinfo->version, QLCNIC_LINUX_VERSIONID, 32);
 146}
 147
 148static int
 149qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 150{
 151        struct qlcnic_adapter *adapter = netdev_priv(dev);
 152        int check_sfp_module = 0;
 153        u16 pcifn = adapter->ahw.pci_func;
 154
 155        /* read which mode */
 156        if (adapter->ahw.port_type == QLCNIC_GBE) {
 157                ecmd->supported = (SUPPORTED_10baseT_Half |
 158                                   SUPPORTED_10baseT_Full |
 159                                   SUPPORTED_100baseT_Half |
 160                                   SUPPORTED_100baseT_Full |
 161                                   SUPPORTED_1000baseT_Half |
 162                                   SUPPORTED_1000baseT_Full);
 163
 164                ecmd->advertising = (ADVERTISED_100baseT_Half |
 165                                     ADVERTISED_100baseT_Full |
 166                                     ADVERTISED_1000baseT_Half |
 167                                     ADVERTISED_1000baseT_Full);
 168
 169                ecmd->speed = adapter->link_speed;
 170                ecmd->duplex = adapter->link_duplex;
 171                ecmd->autoneg = adapter->link_autoneg;
 172
 173        } else if (adapter->ahw.port_type == QLCNIC_XGBE) {
 174                u32 val;
 175
 176                val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR);
 177                if (val == QLCNIC_PORT_MODE_802_3_AP) {
 178                        ecmd->supported = SUPPORTED_1000baseT_Full;
 179                        ecmd->advertising = ADVERTISED_1000baseT_Full;
 180                } else {
 181                        ecmd->supported = SUPPORTED_10000baseT_Full;
 182                        ecmd->advertising = ADVERTISED_10000baseT_Full;
 183                }
 184
 185                if (netif_running(dev) && adapter->has_link_events) {
 186                        ecmd->speed = adapter->link_speed;
 187                        ecmd->autoneg = adapter->link_autoneg;
 188                        ecmd->duplex = adapter->link_duplex;
 189                        goto skip;
 190                }
 191
 192                val = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn));
 193                ecmd->speed = P3P_LINK_SPEED_MHZ *
 194                        P3P_LINK_SPEED_VAL(pcifn, val);
 195                ecmd->duplex = DUPLEX_FULL;
 196                ecmd->autoneg = AUTONEG_DISABLE;
 197        } else
 198                return -EIO;
 199
 200skip:
 201        ecmd->phy_address = adapter->physical_port;
 202        ecmd->transceiver = XCVR_EXTERNAL;
 203
 204        switch (adapter->ahw.board_type) {
 205        case QLCNIC_BRDTYPE_P3P_REF_QG:
 206        case QLCNIC_BRDTYPE_P3P_4_GB:
 207        case QLCNIC_BRDTYPE_P3P_4_GB_MM:
 208
 209                ecmd->supported |= SUPPORTED_Autoneg;
 210                ecmd->advertising |= ADVERTISED_Autoneg;
 211        case QLCNIC_BRDTYPE_P3P_10G_CX4:
 212        case QLCNIC_BRDTYPE_P3P_10G_CX4_LP:
 213        case QLCNIC_BRDTYPE_P3P_10000_BASE_T:
 214                ecmd->supported |= SUPPORTED_TP;
 215                ecmd->advertising |= ADVERTISED_TP;
 216                ecmd->port = PORT_TP;
 217                ecmd->autoneg =  adapter->link_autoneg;
 218                break;
 219        case QLCNIC_BRDTYPE_P3P_IMEZ:
 220        case QLCNIC_BRDTYPE_P3P_XG_LOM:
 221        case QLCNIC_BRDTYPE_P3P_HMEZ:
 222                ecmd->supported |= SUPPORTED_MII;
 223                ecmd->advertising |= ADVERTISED_MII;
 224                ecmd->port = PORT_MII;
 225                ecmd->autoneg = AUTONEG_DISABLE;
 226                break;
 227        case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS:
 228        case QLCNIC_BRDTYPE_P3P_10G_SFP_CT:
 229        case QLCNIC_BRDTYPE_P3P_10G_SFP_QT:
 230                ecmd->advertising |= ADVERTISED_TP;
 231                ecmd->supported |= SUPPORTED_TP;
 232                check_sfp_module = netif_running(dev) &&
 233                        adapter->has_link_events;
 234        case QLCNIC_BRDTYPE_P3P_10G_XFP:
 235                ecmd->supported |= SUPPORTED_FIBRE;
 236                ecmd->advertising |= ADVERTISED_FIBRE;
 237                ecmd->port = PORT_FIBRE;
 238                ecmd->autoneg = AUTONEG_DISABLE;
 239                break;
 240        case QLCNIC_BRDTYPE_P3P_10G_TP:
 241                if (adapter->ahw.port_type == QLCNIC_XGBE) {
 242                        ecmd->autoneg = AUTONEG_DISABLE;
 243                        ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
 244                        ecmd->advertising |=
 245                                (ADVERTISED_FIBRE | ADVERTISED_TP);
 246                        ecmd->port = PORT_FIBRE;
 247                        check_sfp_module = netif_running(dev) &&
 248                                adapter->has_link_events;
 249                } else {
 250                        ecmd->autoneg = AUTONEG_ENABLE;
 251                        ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
 252                        ecmd->advertising |=
 253                                (ADVERTISED_TP | ADVERTISED_Autoneg);
 254                        ecmd->port = PORT_TP;
 255                }
 256                break;
 257        default:
 258                dev_err(&adapter->pdev->dev, "Unsupported board model %d\n",
 259                        adapter->ahw.board_type);
 260                return -EIO;
 261        }
 262
 263        if (check_sfp_module) {
 264                switch (adapter->module_type) {
 265                case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
 266                case LINKEVENT_MODULE_OPTICAL_SRLR:
 267                case LINKEVENT_MODULE_OPTICAL_LRM:
 268                case LINKEVENT_MODULE_OPTICAL_SFP_1G:
 269                        ecmd->port = PORT_FIBRE;
 270                        break;
 271                case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
 272                case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
 273                case LINKEVENT_MODULE_TWINAX:
 274                        ecmd->port = PORT_TP;
 275                        break;
 276                default:
 277                        ecmd->port = PORT_OTHER;
 278                }
 279        }
 280
 281        return 0;
 282}
 283
 284static int
 285qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 286{
 287        struct qlcnic_adapter *adapter = netdev_priv(dev);
 288        __u32 status;
 289
 290        /* read which mode */
 291        if (adapter->ahw.port_type == QLCNIC_GBE) {
 292                /* autonegotiation */
 293                if (qlcnic_fw_cmd_set_phy(adapter,
 294                               QLCNIC_NIU_GB_MII_MGMT_ADDR_AUTONEG,
 295                               ecmd->autoneg) != 0)
 296                        return -EIO;
 297                else
 298                        adapter->link_autoneg = ecmd->autoneg;
 299
 300                if (qlcnic_fw_cmd_query_phy(adapter,
 301                              QLCNIC_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
 302                              &status) != 0)
 303                        return -EIO;
 304
 305                switch (ecmd->speed) {
 306                case SPEED_10:
 307                        qlcnic_set_phy_speed(status, 0);
 308                        break;
 309                case SPEED_100:
 310                        qlcnic_set_phy_speed(status, 1);
 311                        break;
 312                case SPEED_1000:
 313                        qlcnic_set_phy_speed(status, 2);
 314                        break;
 315                }
 316
 317                if (ecmd->duplex == DUPLEX_HALF)
 318                        qlcnic_clear_phy_duplex(status);
 319                if (ecmd->duplex == DUPLEX_FULL)
 320                        qlcnic_set_phy_duplex(status);
 321                if (qlcnic_fw_cmd_set_phy(adapter,
 322                               QLCNIC_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
 323                               *((int *)&status)) != 0)
 324                        return -EIO;
 325                else {
 326                        adapter->link_speed = ecmd->speed;
 327                        adapter->link_duplex = ecmd->duplex;
 328                }
 329        } else
 330                return -EOPNOTSUPP;
 331
 332        if (!netif_running(dev))
 333                return 0;
 334
 335        dev->netdev_ops->ndo_stop(dev);
 336        return dev->netdev_ops->ndo_open(dev);
 337}
 338
 339static void
 340qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
 341{
 342        struct qlcnic_adapter *adapter = netdev_priv(dev);
 343        struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
 344        struct qlcnic_host_sds_ring *sds_ring;
 345        u32 *regs_buff = p;
 346        int ring, i = 0, j = 0;
 347
 348        memset(p, 0, qlcnic_get_regs_len(dev));
 349        regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) |
 350                (adapter->ahw.revision_id << 16) | (adapter->pdev)->device;
 351
 352        regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff));
 353        regs_buff[1] = QLCNIC_MGMT_API_VERSION;
 354
 355        for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[j] != -1; j++, i++)
 356                regs_buff[i] = QLCRD32(adapter, diag_registers[j]);
 357
 358        if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
 359                return;
 360
 361        regs_buff[i++] = 0xFFEFCDAB; /* Marker btw regs and ring count*/
 362
 363        regs_buff[i++] = 1; /* No. of tx ring */
 364        regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
 365        regs_buff[i++] = readl(adapter->tx_ring->crb_cmd_producer);
 366
 367        regs_buff[i++] = 2; /* No. of rx ring */
 368        regs_buff[i++] = readl(recv_ctx->rds_rings[0].crb_rcv_producer);
 369        regs_buff[i++] = readl(recv_ctx->rds_rings[1].crb_rcv_producer);
 370
 371        regs_buff[i++] = adapter->max_sds_rings;
 372
 373        for (ring = 0; ring < adapter->max_sds_rings; ring++) {
 374                sds_ring = &(recv_ctx->sds_rings[ring]);
 375                regs_buff[i++] = readl(sds_ring->crb_sts_consumer);
 376        }
 377}
 378
 379static u32 qlcnic_test_link(struct net_device *dev)
 380{
 381        struct qlcnic_adapter *adapter = netdev_priv(dev);
 382        u32 val;
 383
 384        val = QLCRD32(adapter, CRB_XG_STATE_P3P);
 385        val = XG_LINK_STATE_P3P(adapter->ahw.pci_func, val);
 386        return (val == XG_LINK_UP_P3P) ? 0 : 1;
 387}
 388
 389static int
 390qlcnic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
 391                      u8 *bytes)
 392{
 393        struct qlcnic_adapter *adapter = netdev_priv(dev);
 394        int offset;
 395        int ret;
 396
 397        if (eeprom->len == 0)
 398                return -EINVAL;
 399
 400        eeprom->magic = (adapter->pdev)->vendor |
 401                        ((adapter->pdev)->device << 16);
 402        offset = eeprom->offset;
 403
 404        ret = qlcnic_rom_fast_read_words(adapter, offset, bytes,
 405                                                eeprom->len);
 406        if (ret < 0)
 407                return ret;
 408
 409        return 0;
 410}
 411
 412static void
 413qlcnic_get_ringparam(struct net_device *dev,
 414                struct ethtool_ringparam *ring)
 415{
 416        struct qlcnic_adapter *adapter = netdev_priv(dev);
 417
 418        ring->rx_pending = adapter->num_rxd;
 419        ring->rx_jumbo_pending = adapter->num_jumbo_rxd;
 420        ring->tx_pending = adapter->num_txd;
 421
 422        ring->rx_max_pending = adapter->max_rxd;
 423        ring->rx_jumbo_max_pending = adapter->max_jumbo_rxd;
 424        ring->tx_max_pending = MAX_CMD_DESCRIPTORS;
 425
 426        ring->rx_mini_max_pending = 0;
 427        ring->rx_mini_pending = 0;
 428}
 429
 430static u32
 431qlcnic_validate_ringparam(u32 val, u32 min, u32 max, char *r_name)
 432{
 433        u32 num_desc;
 434        num_desc = max(val, min);
 435        num_desc = min(num_desc, max);
 436        num_desc = roundup_pow_of_two(num_desc);
 437
 438        if (val != num_desc) {
 439                printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n",
 440                       qlcnic_driver_name, r_name, num_desc, val);
 441        }
 442
 443        return num_desc;
 444}
 445
 446static int
 447qlcnic_set_ringparam(struct net_device *dev,
 448                struct ethtool_ringparam *ring)
 449{
 450        struct qlcnic_adapter *adapter = netdev_priv(dev);
 451        u16 num_rxd, num_jumbo_rxd, num_txd;
 452
 453        if (ring->rx_mini_pending)
 454                return -EOPNOTSUPP;
 455
 456        num_rxd = qlcnic_validate_ringparam(ring->rx_pending,
 457                        MIN_RCV_DESCRIPTORS, adapter->max_rxd, "rx");
 458
 459        num_jumbo_rxd = qlcnic_validate_ringparam(ring->rx_jumbo_pending,
 460                        MIN_JUMBO_DESCRIPTORS, adapter->max_jumbo_rxd,
 461                                                "rx jumbo");
 462
 463        num_txd = qlcnic_validate_ringparam(ring->tx_pending,
 464                        MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx");
 465
 466        if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd &&
 467                        num_jumbo_rxd == adapter->num_jumbo_rxd)
 468                return 0;
 469
 470        adapter->num_rxd = num_rxd;
 471        adapter->num_jumbo_rxd = num_jumbo_rxd;
 472        adapter->num_txd = num_txd;
 473
 474        return qlcnic_reset_context(adapter);
 475}
 476
 477static void
 478qlcnic_get_pauseparam(struct net_device *netdev,
 479                          struct ethtool_pauseparam *pause)
 480{
 481        struct qlcnic_adapter *adapter = netdev_priv(netdev);
 482        int port = adapter->physical_port;
 483        __u32 val;
 484
 485        if (adapter->ahw.port_type == QLCNIC_GBE) {
 486                if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
 487                        return;
 488                /* get flow control settings */
 489                val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port));
 490                pause->rx_pause = qlcnic_gb_get_rx_flowctl(val);
 491                val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL);
 492                switch (port) {
 493                case 0:
 494                        pause->tx_pause = !(qlcnic_gb_get_gb0_mask(val));
 495                        break;
 496                case 1:
 497                        pause->tx_pause = !(qlcnic_gb_get_gb1_mask(val));
 498                        break;
 499                case 2:
 500                        pause->tx_pause = !(qlcnic_gb_get_gb2_mask(val));
 501                        break;
 502                case 3:
 503                default:
 504                        pause->tx_pause = !(qlcnic_gb_get_gb3_mask(val));
 505                        break;
 506                }
 507        } else if (adapter->ahw.port_type == QLCNIC_XGBE) {
 508                if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
 509                        return;
 510                pause->rx_pause = 1;
 511                val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL);
 512                if (port == 0)
 513                        pause->tx_pause = !(qlcnic_xg_get_xg0_mask(val));
 514                else
 515                        pause->tx_pause = !(qlcnic_xg_get_xg1_mask(val));
 516        } else {
 517                dev_err(&netdev->dev, "Unknown board type: %x\n",
 518                                        adapter->ahw.port_type);
 519        }
 520}
 521
 522static int
 523qlcnic_set_pauseparam(struct net_device *netdev,
 524                          struct ethtool_pauseparam *pause)
 525{
 526        struct qlcnic_adapter *adapter = netdev_priv(netdev);
 527        int port = adapter->physical_port;
 528        __u32 val;
 529
 530        /* read mode */
 531        if (adapter->ahw.port_type == QLCNIC_GBE) {
 532                if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
 533                        return -EIO;
 534                /* set flow control */
 535                val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port));
 536
 537                if (pause->rx_pause)
 538                        qlcnic_gb_rx_flowctl(val);
 539                else
 540                        qlcnic_gb_unset_rx_flowctl(val);
 541
 542                QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port),
 543                                val);
 544                /* set autoneg */
 545                val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL);
 546                switch (port) {
 547                case 0:
 548                        if (pause->tx_pause)
 549                                qlcnic_gb_unset_gb0_mask(val);
 550                        else
 551                                qlcnic_gb_set_gb0_mask(val);
 552                        break;
 553                case 1:
 554                        if (pause->tx_pause)
 555                                qlcnic_gb_unset_gb1_mask(val);
 556                        else
 557                                qlcnic_gb_set_gb1_mask(val);
 558                        break;
 559                case 2:
 560                        if (pause->tx_pause)
 561                                qlcnic_gb_unset_gb2_mask(val);
 562                        else
 563                                qlcnic_gb_set_gb2_mask(val);
 564                        break;
 565                case 3:
 566                default:
 567                        if (pause->tx_pause)
 568                                qlcnic_gb_unset_gb3_mask(val);
 569                        else
 570                                qlcnic_gb_set_gb3_mask(val);
 571                        break;
 572                }
 573                QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, val);
 574        } else if (adapter->ahw.port_type == QLCNIC_XGBE) {
 575                if (!pause->rx_pause || pause->autoneg)
 576                        return -EOPNOTSUPP;
 577
 578                if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
 579                        return -EIO;
 580
 581                val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL);
 582                if (port == 0) {
 583                        if (pause->tx_pause)
 584                                qlcnic_xg_unset_xg0_mask(val);
 585                        else
 586                                qlcnic_xg_set_xg0_mask(val);
 587                } else {
 588                        if (pause->tx_pause)
 589                                qlcnic_xg_unset_xg1_mask(val);
 590                        else
 591                                qlcnic_xg_set_xg1_mask(val);
 592                }
 593                QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, val);
 594        } else {
 595                dev_err(&netdev->dev, "Unknown board type: %x\n",
 596                                adapter->ahw.port_type);
 597        }
 598        return 0;
 599}
 600
 601static int qlcnic_reg_test(struct net_device *dev)
 602{
 603        struct qlcnic_adapter *adapter = netdev_priv(dev);
 604        u32 data_read;
 605
 606        data_read = QLCRD32(adapter, QLCNIC_PCIX_PH_REG(0));
 607        if ((data_read & 0xffff) != adapter->pdev->vendor)
 608                return 1;
 609
 610        return 0;
 611}
 612
 613static int qlcnic_get_sset_count(struct net_device *dev, int sset)
 614{
 615        struct qlcnic_adapter *adapter = netdev_priv(dev);
 616        switch (sset) {
 617        case ETH_SS_TEST:
 618                return QLCNIC_TEST_LEN;
 619        case ETH_SS_STATS:
 620                if (adapter->flags & QLCNIC_ESWITCH_ENABLED)
 621                        return QLCNIC_STATS_LEN + QLCNIC_DEVICE_STATS_LEN;
 622                return QLCNIC_STATS_LEN;
 623        default:
 624                return -EOPNOTSUPP;
 625        }
 626}
 627
 628static int qlcnic_irq_test(struct net_device *netdev)
 629{
 630        struct qlcnic_adapter *adapter = netdev_priv(netdev);
 631        int max_sds_rings = adapter->max_sds_rings;
 632        int ret;
 633
 634        if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
 635                return -EIO;
 636
 637        ret = qlcnic_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST);
 638        if (ret)
 639                goto clear_it;
 640
 641        adapter->diag_cnt = 0;
 642        ret = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func,
 643                        adapter->fw_hal_version, adapter->portnum,
 644                        0, 0, 0x00000011);
 645        if (ret)
 646                goto done;
 647
 648        msleep(10);
 649
 650        ret = !adapter->diag_cnt;
 651
 652done:
 653        qlcnic_diag_free_res(netdev, max_sds_rings);
 654
 655clear_it:
 656        adapter->max_sds_rings = max_sds_rings;
 657        clear_bit(__QLCNIC_RESETTING, &adapter->state);
 658        return ret;
 659}
 660
 661static void
 662qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
 663                     u64 *data)
 664{
 665        memset(data, 0, sizeof(u64) * QLCNIC_TEST_LEN);
 666
 667        data[0] = qlcnic_reg_test(dev);
 668        if (data[0])
 669                eth_test->flags |= ETH_TEST_FL_FAILED;
 670
 671        data[1] = (u64) qlcnic_test_link(dev);
 672        if (data[1])
 673                eth_test->flags |= ETH_TEST_FL_FAILED;
 674
 675        if (eth_test->flags & ETH_TEST_FL_OFFLINE) {
 676                data[2] = qlcnic_irq_test(dev);
 677                if (data[2])
 678                        eth_test->flags |= ETH_TEST_FL_FAILED;
 679
 680
 681        }
 682}
 683
 684static void
 685qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 * data)
 686{
 687        struct qlcnic_adapter *adapter = netdev_priv(dev);
 688        int index, i;
 689
 690        switch (stringset) {
 691        case ETH_SS_TEST:
 692                memcpy(data, *qlcnic_gstrings_test,
 693                       QLCNIC_TEST_LEN * ETH_GSTRING_LEN);
 694                break;
 695        case ETH_SS_STATS:
 696                for (index = 0; index < QLCNIC_STATS_LEN; index++) {
 697                        memcpy(data + index * ETH_GSTRING_LEN,
 698                               qlcnic_gstrings_stats[index].stat_string,
 699                               ETH_GSTRING_LEN);
 700                }
 701                if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
 702                        return;
 703                for (i = 0; i < QLCNIC_DEVICE_STATS_LEN; index++, i++) {
 704                        memcpy(data + index * ETH_GSTRING_LEN,
 705                               qlcnic_device_gstrings_stats[i],
 706                               ETH_GSTRING_LEN);
 707                }
 708        }
 709}
 710
 711#define QLCNIC_FILL_ESWITCH_STATS(VAL1) \
 712        (((VAL1) == QLCNIC_ESW_STATS_NOT_AVAIL) ? 0 : VAL1)
 713
 714static void
 715qlcnic_fill_device_stats(int *index, u64 *data,
 716                struct __qlcnic_esw_statistics *stats)
 717{
 718        int ind = *index;
 719
 720        data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->unicast_frames);
 721        data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->multicast_frames);
 722        data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->broadcast_frames);
 723        data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->dropped_frames);
 724        data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->errors);
 725        data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->local_frames);
 726        data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->numbytes);
 727
 728        *index = ind;
 729}
 730
 731static void
 732qlcnic_get_ethtool_stats(struct net_device *dev,
 733                             struct ethtool_stats *stats, u64 * data)
 734{
 735        struct qlcnic_adapter *adapter = netdev_priv(dev);
 736        struct qlcnic_esw_statistics port_stats;
 737        int index, ret;
 738
 739        for (index = 0; index < QLCNIC_STATS_LEN; index++) {
 740                char *p =
 741                    (char *)adapter +
 742                    qlcnic_gstrings_stats[index].stat_offset;
 743                data[index] =
 744                    (qlcnic_gstrings_stats[index].sizeof_stat ==
 745                     sizeof(u64)) ? *(u64 *)p:(*(u32 *)p);
 746        }
 747
 748        if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
 749                return;
 750
 751        memset(&port_stats, 0, sizeof(struct qlcnic_esw_statistics));
 752        ret = qlcnic_get_port_stats(adapter, adapter->ahw.pci_func,
 753                        QLCNIC_QUERY_RX_COUNTER, &port_stats.rx);
 754        if (ret)
 755                return;
 756
 757        qlcnic_fill_device_stats(&index, data, &port_stats.rx);
 758
 759        ret = qlcnic_get_port_stats(adapter, adapter->ahw.pci_func,
 760                        QLCNIC_QUERY_TX_COUNTER, &port_stats.tx);
 761        if (ret)
 762                return;
 763
 764        qlcnic_fill_device_stats(&index, data, &port_stats.tx);
 765}
 766
 767static int qlcnic_set_tx_csum(struct net_device *dev, u32 data)
 768{
 769        struct qlcnic_adapter *adapter = netdev_priv(dev);
 770
 771        if ((adapter->flags & QLCNIC_ESWITCH_ENABLED))
 772                return -EOPNOTSUPP;
 773        if (data)
 774                dev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
 775        else
 776                dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
 777
 778        return 0;
 779
 780}
 781static u32 qlcnic_get_tx_csum(struct net_device *dev)
 782{
 783        return dev->features & NETIF_F_IP_CSUM;
 784}
 785
 786static u32 qlcnic_get_rx_csum(struct net_device *dev)
 787{
 788        struct qlcnic_adapter *adapter = netdev_priv(dev);
 789        return adapter->rx_csum;
 790}
 791
 792static int qlcnic_set_rx_csum(struct net_device *dev, u32 data)
 793{
 794        struct qlcnic_adapter *adapter = netdev_priv(dev);
 795
 796        if ((adapter->flags & QLCNIC_ESWITCH_ENABLED))
 797                return -EOPNOTSUPP;
 798        if (!!data) {
 799                adapter->rx_csum = !!data;
 800                return 0;
 801        }
 802
 803        if (dev->features & NETIF_F_LRO) {
 804                if (qlcnic_config_hw_lro(adapter, QLCNIC_LRO_DISABLED))
 805                        return -EIO;
 806
 807                dev->features &= ~NETIF_F_LRO;
 808                qlcnic_send_lro_cleanup(adapter);
 809                dev_info(&adapter->pdev->dev,
 810                                        "disabling LRO as rx_csum is off\n");
 811        }
 812        adapter->rx_csum = !!data;
 813        return 0;
 814}
 815
 816static u32 qlcnic_get_tso(struct net_device *dev)
 817{
 818        return (dev->features & (NETIF_F_TSO | NETIF_F_TSO6)) != 0;
 819}
 820
 821static int qlcnic_set_tso(struct net_device *dev, u32 data)
 822{
 823        struct qlcnic_adapter *adapter = netdev_priv(dev);
 824        if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO))
 825                return -EOPNOTSUPP;
 826        if (data)
 827                dev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
 828        else
 829                dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
 830
 831        return 0;
 832}
 833
 834static int qlcnic_blink_led(struct net_device *dev, u32 val)
 835{
 836        struct qlcnic_adapter *adapter = netdev_priv(dev);
 837        int max_sds_rings = adapter->max_sds_rings;
 838        int dev_down = 0;
 839        int ret;
 840
 841        if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
 842                dev_down = 1;
 843                if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
 844                        return -EIO;
 845
 846                ret = qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST);
 847                if (ret) {
 848                        clear_bit(__QLCNIC_RESETTING, &adapter->state);
 849                        return ret;
 850                }
 851        }
 852
 853        ret = adapter->nic_ops->config_led(adapter, 1, 0xf);
 854        if (ret) {
 855                dev_err(&adapter->pdev->dev,
 856                        "Failed to set LED blink state.\n");
 857                goto done;
 858        }
 859
 860        msleep_interruptible(val * 1000);
 861
 862        ret = adapter->nic_ops->config_led(adapter, 0, 0xf);
 863        if (ret) {
 864                dev_err(&adapter->pdev->dev,
 865                        "Failed to reset LED blink state.\n");
 866                goto done;
 867        }
 868
 869done:
 870        if (dev_down) {
 871                qlcnic_diag_free_res(dev, max_sds_rings);
 872                clear_bit(__QLCNIC_RESETTING, &adapter->state);
 873        }
 874        return ret;
 875
 876}
 877
 878static void
 879qlcnic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 880{
 881        struct qlcnic_adapter *adapter = netdev_priv(dev);
 882        u32 wol_cfg;
 883
 884        wol->supported = 0;
 885        wol->wolopts = 0;
 886
 887        wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
 888        if (wol_cfg & (1UL << adapter->portnum))
 889                wol->supported |= WAKE_MAGIC;
 890
 891        wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
 892        if (wol_cfg & (1UL << adapter->portnum))
 893                wol->wolopts |= WAKE_MAGIC;
 894}
 895
 896static int
 897qlcnic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 898{
 899        struct qlcnic_adapter *adapter = netdev_priv(dev);
 900        u32 wol_cfg;
 901
 902        if (wol->wolopts & ~WAKE_MAGIC)
 903                return -EOPNOTSUPP;
 904
 905        wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
 906        if (!(wol_cfg & (1 << adapter->portnum)))
 907                return -EOPNOTSUPP;
 908
 909        wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
 910        if (wol->wolopts & WAKE_MAGIC)
 911                wol_cfg |= 1UL << adapter->portnum;
 912        else
 913                wol_cfg &= ~(1UL << adapter->portnum);
 914
 915        QLCWR32(adapter, QLCNIC_WOL_CONFIG, wol_cfg);
 916
 917        return 0;
 918}
 919
 920/*
 921 * Set the coalescing parameters. Currently only normal is supported.
 922 * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the
 923 * firmware coalescing to default.
 924 */
 925static int qlcnic_set_intr_coalesce(struct net_device *netdev,
 926                        struct ethtool_coalesce *ethcoal)
 927{
 928        struct qlcnic_adapter *adapter = netdev_priv(netdev);
 929
 930        if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
 931                return -EINVAL;
 932
 933        /*
 934        * Return Error if unsupported values or
 935        * unsupported parameters are set.
 936        */
 937        if (ethcoal->rx_coalesce_usecs > 0xffff ||
 938                ethcoal->rx_max_coalesced_frames > 0xffff ||
 939                ethcoal->tx_coalesce_usecs > 0xffff ||
 940                ethcoal->tx_max_coalesced_frames > 0xffff ||
 941                ethcoal->rx_coalesce_usecs_irq ||
 942                ethcoal->rx_max_coalesced_frames_irq ||
 943                ethcoal->tx_coalesce_usecs_irq ||
 944                ethcoal->tx_max_coalesced_frames_irq ||
 945                ethcoal->stats_block_coalesce_usecs ||
 946                ethcoal->use_adaptive_rx_coalesce ||
 947                ethcoal->use_adaptive_tx_coalesce ||
 948                ethcoal->pkt_rate_low ||
 949                ethcoal->rx_coalesce_usecs_low ||
 950                ethcoal->rx_max_coalesced_frames_low ||
 951                ethcoal->tx_coalesce_usecs_low ||
 952                ethcoal->tx_max_coalesced_frames_low ||
 953                ethcoal->pkt_rate_high ||
 954                ethcoal->rx_coalesce_usecs_high ||
 955                ethcoal->rx_max_coalesced_frames_high ||
 956                ethcoal->tx_coalesce_usecs_high ||
 957                ethcoal->tx_max_coalesced_frames_high)
 958                return -EINVAL;
 959
 960        if (!ethcoal->rx_coalesce_usecs ||
 961                !ethcoal->rx_max_coalesced_frames) {
 962                adapter->coal.flags = QLCNIC_INTR_DEFAULT;
 963                adapter->coal.normal.data.rx_time_us =
 964                        QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US;
 965                adapter->coal.normal.data.rx_packets =
 966                        QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS;
 967        } else {
 968                adapter->coal.flags = 0;
 969                adapter->coal.normal.data.rx_time_us =
 970                ethcoal->rx_coalesce_usecs;
 971                adapter->coal.normal.data.rx_packets =
 972                ethcoal->rx_max_coalesced_frames;
 973        }
 974        adapter->coal.normal.data.tx_time_us = ethcoal->tx_coalesce_usecs;
 975        adapter->coal.normal.data.tx_packets =
 976        ethcoal->tx_max_coalesced_frames;
 977
 978        qlcnic_config_intr_coalesce(adapter);
 979
 980        return 0;
 981}
 982
 983static int qlcnic_get_intr_coalesce(struct net_device *netdev,
 984                        struct ethtool_coalesce *ethcoal)
 985{
 986        struct qlcnic_adapter *adapter = netdev_priv(netdev);
 987
 988        if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
 989                return -EINVAL;
 990
 991        ethcoal->rx_coalesce_usecs = adapter->coal.normal.data.rx_time_us;
 992        ethcoal->tx_coalesce_usecs = adapter->coal.normal.data.tx_time_us;
 993        ethcoal->rx_max_coalesced_frames =
 994                adapter->coal.normal.data.rx_packets;
 995        ethcoal->tx_max_coalesced_frames =
 996                adapter->coal.normal.data.tx_packets;
 997
 998        return 0;
 999}
1000
1001static int qlcnic_set_flags(struct net_device *netdev, u32 data)
1002{
1003        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1004        int hw_lro;
1005
1006        if (data & ~ETH_FLAG_LRO)
1007                return -EINVAL;
1008
1009        if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO))
1010                return -EINVAL;
1011
1012        if (!adapter->rx_csum) {
1013                dev_info(&adapter->pdev->dev, "rx csum is off, "
1014                        "cannot toggle lro\n");
1015                return -EINVAL;
1016        }
1017
1018        if ((data & ETH_FLAG_LRO) && (netdev->features & NETIF_F_LRO))
1019                return 0;
1020
1021        if (data & ETH_FLAG_LRO) {
1022                hw_lro = QLCNIC_LRO_ENABLED;
1023                netdev->features |= NETIF_F_LRO;
1024        } else {
1025                hw_lro = 0;
1026                netdev->features &= ~NETIF_F_LRO;
1027        }
1028
1029        if (qlcnic_config_hw_lro(adapter, hw_lro))
1030                return -EIO;
1031
1032        if ((hw_lro == 0) && qlcnic_send_lro_cleanup(adapter))
1033                return -EIO;
1034
1035
1036        return 0;
1037}
1038
1039static u32 qlcnic_get_msglevel(struct net_device *netdev)
1040{
1041        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1042
1043        return adapter->msg_enable;
1044}
1045
1046static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl)
1047{
1048        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1049
1050        adapter->msg_enable = msglvl;
1051}
1052
1053const struct ethtool_ops qlcnic_ethtool_ops = {
1054        .get_settings = qlcnic_get_settings,
1055        .set_settings = qlcnic_set_settings,
1056        .get_drvinfo = qlcnic_get_drvinfo,
1057        .get_regs_len = qlcnic_get_regs_len,
1058        .get_regs = qlcnic_get_regs,
1059        .get_link = ethtool_op_get_link,
1060        .get_eeprom_len = qlcnic_get_eeprom_len,
1061        .get_eeprom = qlcnic_get_eeprom,
1062        .get_ringparam = qlcnic_get_ringparam,
1063        .set_ringparam = qlcnic_set_ringparam,
1064        .get_pauseparam = qlcnic_get_pauseparam,
1065        .set_pauseparam = qlcnic_set_pauseparam,
1066        .get_tx_csum = qlcnic_get_tx_csum,
1067        .set_tx_csum = qlcnic_set_tx_csum,
1068        .set_sg = ethtool_op_set_sg,
1069        .get_tso = qlcnic_get_tso,
1070        .set_tso = qlcnic_set_tso,
1071        .get_wol = qlcnic_get_wol,
1072        .set_wol = qlcnic_set_wol,
1073        .self_test = qlcnic_diag_test,
1074        .get_strings = qlcnic_get_strings,
1075        .get_ethtool_stats = qlcnic_get_ethtool_stats,
1076        .get_sset_count = qlcnic_get_sset_count,
1077        .get_rx_csum = qlcnic_get_rx_csum,
1078        .set_rx_csum = qlcnic_set_rx_csum,
1079        .get_coalesce = qlcnic_get_intr_coalesce,
1080        .set_coalesce = qlcnic_set_intr_coalesce,
1081        .get_flags = ethtool_op_get_flags,
1082        .set_flags = qlcnic_set_flags,
1083        .phys_id = qlcnic_blink_led,
1084        .set_msglevel = qlcnic_set_msglevel,
1085        .get_msglevel = qlcnic_get_msglevel,
1086};
1087