linux/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
<<
>>
Prefs
   1/*
   2 * Linux network driver for QLogic BR-series Converged Network Adapter.
   3 *
   4 * This program is free software; you can redistribute it and/or modify it
   5 * under the terms of the GNU General Public License (GPL) Version 2 as
   6 * published by the Free Software Foundation
   7 *
   8 * This program is distributed in the hope that it will be useful, but
   9 * WITHOUT ANY WARRANTY; without even the implied warranty of
  10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11 * General Public License for more details.
  12 */
  13/*
  14 * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
  15 * Copyright (c) 2014-2015 QLogic Corporation
  16 * All rights reserved
  17 * www.qlogic.com
  18 */
  19
  20#include "cna.h"
  21
  22#include <linux/netdevice.h>
  23#include <linux/skbuff.h>
  24#include <linux/ethtool.h>
  25#include <linux/rtnetlink.h>
  26
  27#include "bna.h"
  28
  29#include "bnad.h"
  30
  31#define BNAD_NUM_TXF_COUNTERS 12
  32#define BNAD_NUM_RXF_COUNTERS 10
  33#define BNAD_NUM_CQ_COUNTERS (3 + 5)
  34#define BNAD_NUM_RXQ_COUNTERS 6
  35#define BNAD_NUM_TXQ_COUNTERS 5
  36
  37#define BNAD_ETHTOOL_STATS_NUM                                          \
  38        (sizeof(struct rtnl_link_stats64) / sizeof(u64) +       \
  39        sizeof(struct bnad_drv_stats) / sizeof(u64) +           \
  40        offsetof(struct bfi_enet_stats, rxf_stats[0]) / sizeof(u64))
  41
  42static const char *bnad_net_stats_strings[BNAD_ETHTOOL_STATS_NUM] = {
  43        "rx_packets",
  44        "tx_packets",
  45        "rx_bytes",
  46        "tx_bytes",
  47        "rx_errors",
  48        "tx_errors",
  49        "rx_dropped",
  50        "tx_dropped",
  51        "multicast",
  52        "collisions",
  53
  54        "rx_length_errors",
  55        "rx_over_errors",
  56        "rx_crc_errors",
  57        "rx_frame_errors",
  58        "rx_fifo_errors",
  59        "rx_missed_errors",
  60
  61        "tx_aborted_errors",
  62        "tx_carrier_errors",
  63        "tx_fifo_errors",
  64        "tx_heartbeat_errors",
  65        "tx_window_errors",
  66
  67        "rx_compressed",
  68        "tx_compressed",
  69
  70        "netif_queue_stop",
  71        "netif_queue_wakeup",
  72        "netif_queue_stopped",
  73        "tso4",
  74        "tso6",
  75        "tso_err",
  76        "tcpcsum_offload",
  77        "udpcsum_offload",
  78        "csum_help",
  79        "tx_skb_too_short",
  80        "tx_skb_stopping",
  81        "tx_skb_max_vectors",
  82        "tx_skb_mss_too_long",
  83        "tx_skb_tso_too_short",
  84        "tx_skb_tso_prepare",
  85        "tx_skb_non_tso_too_long",
  86        "tx_skb_tcp_hdr",
  87        "tx_skb_udp_hdr",
  88        "tx_skb_csum_err",
  89        "tx_skb_headlen_too_long",
  90        "tx_skb_headlen_zero",
  91        "tx_skb_frag_zero",
  92        "tx_skb_len_mismatch",
  93        "tx_skb_map_failed",
  94        "hw_stats_updates",
  95        "netif_rx_dropped",
  96
  97        "link_toggle",
  98        "cee_toggle",
  99
 100        "rxp_info_alloc_failed",
 101        "mbox_intr_disabled",
 102        "mbox_intr_enabled",
 103        "tx_unmap_q_alloc_failed",
 104        "rx_unmap_q_alloc_failed",
 105        "rxbuf_alloc_failed",
 106        "rxbuf_map_failed",
 107
 108        "mac_stats_clr_cnt",
 109        "mac_frame_64",
 110        "mac_frame_65_127",
 111        "mac_frame_128_255",
 112        "mac_frame_256_511",
 113        "mac_frame_512_1023",
 114        "mac_frame_1024_1518",
 115        "mac_frame_1518_1522",
 116        "mac_rx_bytes",
 117        "mac_rx_packets",
 118        "mac_rx_fcs_error",
 119        "mac_rx_multicast",
 120        "mac_rx_broadcast",
 121        "mac_rx_control_frames",
 122        "mac_rx_pause",
 123        "mac_rx_unknown_opcode",
 124        "mac_rx_alignment_error",
 125        "mac_rx_frame_length_error",
 126        "mac_rx_code_error",
 127        "mac_rx_carrier_sense_error",
 128        "mac_rx_undersize",
 129        "mac_rx_oversize",
 130        "mac_rx_fragments",
 131        "mac_rx_jabber",
 132        "mac_rx_drop",
 133
 134        "mac_tx_bytes",
 135        "mac_tx_packets",
 136        "mac_tx_multicast",
 137        "mac_tx_broadcast",
 138        "mac_tx_pause",
 139        "mac_tx_deferral",
 140        "mac_tx_excessive_deferral",
 141        "mac_tx_single_collision",
 142        "mac_tx_muliple_collision",
 143        "mac_tx_late_collision",
 144        "mac_tx_excessive_collision",
 145        "mac_tx_total_collision",
 146        "mac_tx_pause_honored",
 147        "mac_tx_drop",
 148        "mac_tx_jabber",
 149        "mac_tx_fcs_error",
 150        "mac_tx_control_frame",
 151        "mac_tx_oversize",
 152        "mac_tx_undersize",
 153        "mac_tx_fragments",
 154
 155        "bpc_tx_pause_0",
 156        "bpc_tx_pause_1",
 157        "bpc_tx_pause_2",
 158        "bpc_tx_pause_3",
 159        "bpc_tx_pause_4",
 160        "bpc_tx_pause_5",
 161        "bpc_tx_pause_6",
 162        "bpc_tx_pause_7",
 163        "bpc_tx_zero_pause_0",
 164        "bpc_tx_zero_pause_1",
 165        "bpc_tx_zero_pause_2",
 166        "bpc_tx_zero_pause_3",
 167        "bpc_tx_zero_pause_4",
 168        "bpc_tx_zero_pause_5",
 169        "bpc_tx_zero_pause_6",
 170        "bpc_tx_zero_pause_7",
 171        "bpc_tx_first_pause_0",
 172        "bpc_tx_first_pause_1",
 173        "bpc_tx_first_pause_2",
 174        "bpc_tx_first_pause_3",
 175        "bpc_tx_first_pause_4",
 176        "bpc_tx_first_pause_5",
 177        "bpc_tx_first_pause_6",
 178        "bpc_tx_first_pause_7",
 179
 180        "bpc_rx_pause_0",
 181        "bpc_rx_pause_1",
 182        "bpc_rx_pause_2",
 183        "bpc_rx_pause_3",
 184        "bpc_rx_pause_4",
 185        "bpc_rx_pause_5",
 186        "bpc_rx_pause_6",
 187        "bpc_rx_pause_7",
 188        "bpc_rx_zero_pause_0",
 189        "bpc_rx_zero_pause_1",
 190        "bpc_rx_zero_pause_2",
 191        "bpc_rx_zero_pause_3",
 192        "bpc_rx_zero_pause_4",
 193        "bpc_rx_zero_pause_5",
 194        "bpc_rx_zero_pause_6",
 195        "bpc_rx_zero_pause_7",
 196        "bpc_rx_first_pause_0",
 197        "bpc_rx_first_pause_1",
 198        "bpc_rx_first_pause_2",
 199        "bpc_rx_first_pause_3",
 200        "bpc_rx_first_pause_4",
 201        "bpc_rx_first_pause_5",
 202        "bpc_rx_first_pause_6",
 203        "bpc_rx_first_pause_7",
 204
 205        "rad_rx_frames",
 206        "rad_rx_octets",
 207        "rad_rx_vlan_frames",
 208        "rad_rx_ucast",
 209        "rad_rx_ucast_octets",
 210        "rad_rx_ucast_vlan",
 211        "rad_rx_mcast",
 212        "rad_rx_mcast_octets",
 213        "rad_rx_mcast_vlan",
 214        "rad_rx_bcast",
 215        "rad_rx_bcast_octets",
 216        "rad_rx_bcast_vlan",
 217        "rad_rx_drops",
 218
 219        "rlb_rad_rx_frames",
 220        "rlb_rad_rx_octets",
 221        "rlb_rad_rx_vlan_frames",
 222        "rlb_rad_rx_ucast",
 223        "rlb_rad_rx_ucast_octets",
 224        "rlb_rad_rx_ucast_vlan",
 225        "rlb_rad_rx_mcast",
 226        "rlb_rad_rx_mcast_octets",
 227        "rlb_rad_rx_mcast_vlan",
 228        "rlb_rad_rx_bcast",
 229        "rlb_rad_rx_bcast_octets",
 230        "rlb_rad_rx_bcast_vlan",
 231        "rlb_rad_rx_drops",
 232
 233        "fc_rx_ucast_octets",
 234        "fc_rx_ucast",
 235        "fc_rx_ucast_vlan",
 236        "fc_rx_mcast_octets",
 237        "fc_rx_mcast",
 238        "fc_rx_mcast_vlan",
 239        "fc_rx_bcast_octets",
 240        "fc_rx_bcast",
 241        "fc_rx_bcast_vlan",
 242
 243        "fc_tx_ucast_octets",
 244        "fc_tx_ucast",
 245        "fc_tx_ucast_vlan",
 246        "fc_tx_mcast_octets",
 247        "fc_tx_mcast",
 248        "fc_tx_mcast_vlan",
 249        "fc_tx_bcast_octets",
 250        "fc_tx_bcast",
 251        "fc_tx_bcast_vlan",
 252        "fc_tx_parity_errors",
 253        "fc_tx_timeout",
 254        "fc_tx_fid_parity_errors",
 255};
 256
 257static int
 258bnad_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
 259{
 260        cmd->supported = SUPPORTED_10000baseT_Full;
 261        cmd->advertising = ADVERTISED_10000baseT_Full;
 262        cmd->autoneg = AUTONEG_DISABLE;
 263        cmd->supported |= SUPPORTED_FIBRE;
 264        cmd->advertising |= ADVERTISED_FIBRE;
 265        cmd->port = PORT_FIBRE;
 266        cmd->phy_address = 0;
 267
 268        if (netif_carrier_ok(netdev)) {
 269                ethtool_cmd_speed_set(cmd, SPEED_10000);
 270                cmd->duplex = DUPLEX_FULL;
 271        } else {
 272                ethtool_cmd_speed_set(cmd, SPEED_UNKNOWN);
 273                cmd->duplex = DUPLEX_UNKNOWN;
 274        }
 275        cmd->transceiver = XCVR_EXTERNAL;
 276        cmd->maxtxpkt = 0;
 277        cmd->maxrxpkt = 0;
 278
 279        return 0;
 280}
 281
 282static int
 283bnad_set_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
 284{
 285        /* 10G full duplex setting supported only */
 286        if (cmd->autoneg == AUTONEG_ENABLE)
 287                return -EOPNOTSUPP; else {
 288                if ((ethtool_cmd_speed(cmd) == SPEED_10000)
 289                    && (cmd->duplex == DUPLEX_FULL))
 290                        return 0;
 291        }
 292
 293        return -EOPNOTSUPP;
 294}
 295
 296static void
 297bnad_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
 298{
 299        struct bnad *bnad = netdev_priv(netdev);
 300        struct bfa_ioc_attr *ioc_attr;
 301        unsigned long flags;
 302
 303        strlcpy(drvinfo->driver, BNAD_NAME, sizeof(drvinfo->driver));
 304        strlcpy(drvinfo->version, BNAD_VERSION, sizeof(drvinfo->version));
 305
 306        ioc_attr = kzalloc(sizeof(*ioc_attr), GFP_KERNEL);
 307        if (ioc_attr) {
 308                spin_lock_irqsave(&bnad->bna_lock, flags);
 309                bfa_nw_ioc_get_attr(&bnad->bna.ioceth.ioc, ioc_attr);
 310                spin_unlock_irqrestore(&bnad->bna_lock, flags);
 311
 312                strlcpy(drvinfo->fw_version, ioc_attr->adapter_attr.fw_ver,
 313                        sizeof(drvinfo->fw_version));
 314                kfree(ioc_attr);
 315        }
 316
 317        strlcpy(drvinfo->bus_info, pci_name(bnad->pcidev),
 318                sizeof(drvinfo->bus_info));
 319}
 320
 321static void
 322bnad_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wolinfo)
 323{
 324        wolinfo->supported = 0;
 325        wolinfo->wolopts = 0;
 326}
 327
 328static int
 329bnad_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
 330{
 331        struct bnad *bnad = netdev_priv(netdev);
 332        unsigned long flags;
 333
 334        /* Lock rqd. to access bnad->bna_lock */
 335        spin_lock_irqsave(&bnad->bna_lock, flags);
 336        coalesce->use_adaptive_rx_coalesce =
 337                (bnad->cfg_flags & BNAD_CF_DIM_ENABLED) ? true : false;
 338        spin_unlock_irqrestore(&bnad->bna_lock, flags);
 339
 340        coalesce->rx_coalesce_usecs = bnad->rx_coalescing_timeo *
 341                                        BFI_COALESCING_TIMER_UNIT;
 342        coalesce->tx_coalesce_usecs = bnad->tx_coalescing_timeo *
 343                                        BFI_COALESCING_TIMER_UNIT;
 344        coalesce->tx_max_coalesced_frames = BFI_TX_INTERPKT_COUNT;
 345
 346        return 0;
 347}
 348
 349static int
 350bnad_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
 351{
 352        struct bnad *bnad = netdev_priv(netdev);
 353        unsigned long flags;
 354        int to_del = 0;
 355
 356        if (coalesce->rx_coalesce_usecs == 0 ||
 357            coalesce->rx_coalesce_usecs >
 358            BFI_MAX_COALESCING_TIMEO * BFI_COALESCING_TIMER_UNIT)
 359                return -EINVAL;
 360
 361        if (coalesce->tx_coalesce_usecs == 0 ||
 362            coalesce->tx_coalesce_usecs >
 363            BFI_MAX_COALESCING_TIMEO * BFI_COALESCING_TIMER_UNIT)
 364                return -EINVAL;
 365
 366        mutex_lock(&bnad->conf_mutex);
 367        /*
 368         * Do not need to store rx_coalesce_usecs here
 369         * Every time DIM is disabled, we can get it from the
 370         * stack.
 371         */
 372        spin_lock_irqsave(&bnad->bna_lock, flags);
 373        if (coalesce->use_adaptive_rx_coalesce) {
 374                if (!(bnad->cfg_flags & BNAD_CF_DIM_ENABLED)) {
 375                        bnad->cfg_flags |= BNAD_CF_DIM_ENABLED;
 376                        bnad_dim_timer_start(bnad);
 377                }
 378        } else {
 379                if (bnad->cfg_flags & BNAD_CF_DIM_ENABLED) {
 380                        bnad->cfg_flags &= ~BNAD_CF_DIM_ENABLED;
 381                        if (bnad->cfg_flags & BNAD_CF_DIM_ENABLED &&
 382                            test_bit(BNAD_RF_DIM_TIMER_RUNNING,
 383                            &bnad->run_flags)) {
 384                                clear_bit(BNAD_RF_DIM_TIMER_RUNNING,
 385                                                        &bnad->run_flags);
 386                                to_del = 1;
 387                        }
 388                        spin_unlock_irqrestore(&bnad->bna_lock, flags);
 389                        if (to_del)
 390                                del_timer_sync(&bnad->dim_timer);
 391                        spin_lock_irqsave(&bnad->bna_lock, flags);
 392                        bnad_rx_coalescing_timeo_set(bnad);
 393                }
 394        }
 395        if (bnad->tx_coalescing_timeo != coalesce->tx_coalesce_usecs /
 396                                        BFI_COALESCING_TIMER_UNIT) {
 397                bnad->tx_coalescing_timeo = coalesce->tx_coalesce_usecs /
 398                                                BFI_COALESCING_TIMER_UNIT;
 399                bnad_tx_coalescing_timeo_set(bnad);
 400        }
 401
 402        if (bnad->rx_coalescing_timeo != coalesce->rx_coalesce_usecs /
 403                                        BFI_COALESCING_TIMER_UNIT) {
 404                bnad->rx_coalescing_timeo = coalesce->rx_coalesce_usecs /
 405                                                BFI_COALESCING_TIMER_UNIT;
 406
 407                if (!(bnad->cfg_flags & BNAD_CF_DIM_ENABLED))
 408                        bnad_rx_coalescing_timeo_set(bnad);
 409
 410        }
 411
 412        /* Add Tx Inter-pkt DMA count?  */
 413
 414        spin_unlock_irqrestore(&bnad->bna_lock, flags);
 415
 416        mutex_unlock(&bnad->conf_mutex);
 417        return 0;
 418}
 419
 420static void
 421bnad_get_ringparam(struct net_device *netdev,
 422                   struct ethtool_ringparam *ringparam)
 423{
 424        struct bnad *bnad = netdev_priv(netdev);
 425
 426        ringparam->rx_max_pending = BNAD_MAX_RXQ_DEPTH;
 427        ringparam->tx_max_pending = BNAD_MAX_TXQ_DEPTH;
 428
 429        ringparam->rx_pending = bnad->rxq_depth;
 430        ringparam->tx_pending = bnad->txq_depth;
 431}
 432
 433static int
 434bnad_set_ringparam(struct net_device *netdev,
 435                   struct ethtool_ringparam *ringparam)
 436{
 437        int i, current_err, err = 0;
 438        struct bnad *bnad = netdev_priv(netdev);
 439        unsigned long flags;
 440
 441        mutex_lock(&bnad->conf_mutex);
 442        if (ringparam->rx_pending == bnad->rxq_depth &&
 443            ringparam->tx_pending == bnad->txq_depth) {
 444                mutex_unlock(&bnad->conf_mutex);
 445                return 0;
 446        }
 447
 448        if (ringparam->rx_pending < BNAD_MIN_Q_DEPTH ||
 449            ringparam->rx_pending > BNAD_MAX_RXQ_DEPTH ||
 450            !is_power_of_2(ringparam->rx_pending)) {
 451                mutex_unlock(&bnad->conf_mutex);
 452                return -EINVAL;
 453        }
 454        if (ringparam->tx_pending < BNAD_MIN_Q_DEPTH ||
 455            ringparam->tx_pending > BNAD_MAX_TXQ_DEPTH ||
 456            !is_power_of_2(ringparam->tx_pending)) {
 457                mutex_unlock(&bnad->conf_mutex);
 458                return -EINVAL;
 459        }
 460
 461        if (ringparam->rx_pending != bnad->rxq_depth) {
 462                bnad->rxq_depth = ringparam->rx_pending;
 463                if (!netif_running(netdev)) {
 464                        mutex_unlock(&bnad->conf_mutex);
 465                        return 0;
 466                }
 467
 468                for (i = 0; i < bnad->num_rx; i++) {
 469                        if (!bnad->rx_info[i].rx)
 470                                continue;
 471                        bnad_destroy_rx(bnad, i);
 472                        current_err = bnad_setup_rx(bnad, i);
 473                        if (current_err && !err)
 474                                err = current_err;
 475                }
 476
 477                if (!err && bnad->rx_info[0].rx) {
 478                        /* restore rx configuration */
 479                        bnad_restore_vlans(bnad, 0);
 480                        bnad_enable_default_bcast(bnad);
 481                        spin_lock_irqsave(&bnad->bna_lock, flags);
 482                        bnad_mac_addr_set_locked(bnad, netdev->dev_addr);
 483                        spin_unlock_irqrestore(&bnad->bna_lock, flags);
 484                        bnad->cfg_flags &= ~(BNAD_CF_ALLMULTI |
 485                                             BNAD_CF_PROMISC);
 486                        bnad_set_rx_mode(netdev);
 487                }
 488        }
 489        if (ringparam->tx_pending != bnad->txq_depth) {
 490                bnad->txq_depth = ringparam->tx_pending;
 491                if (!netif_running(netdev)) {
 492                        mutex_unlock(&bnad->conf_mutex);
 493                        return 0;
 494                }
 495
 496                for (i = 0; i < bnad->num_tx; i++) {
 497                        if (!bnad->tx_info[i].tx)
 498                                continue;
 499                        bnad_destroy_tx(bnad, i);
 500                        current_err = bnad_setup_tx(bnad, i);
 501                        if (current_err && !err)
 502                                err = current_err;
 503                }
 504        }
 505
 506        mutex_unlock(&bnad->conf_mutex);
 507        return err;
 508}
 509
 510static void
 511bnad_get_pauseparam(struct net_device *netdev,
 512                    struct ethtool_pauseparam *pauseparam)
 513{
 514        struct bnad *bnad = netdev_priv(netdev);
 515
 516        pauseparam->autoneg = 0;
 517        pauseparam->rx_pause = bnad->bna.enet.pause_config.rx_pause;
 518        pauseparam->tx_pause = bnad->bna.enet.pause_config.tx_pause;
 519}
 520
 521static int
 522bnad_set_pauseparam(struct net_device *netdev,
 523                    struct ethtool_pauseparam *pauseparam)
 524{
 525        struct bnad *bnad = netdev_priv(netdev);
 526        struct bna_pause_config pause_config;
 527        unsigned long flags;
 528
 529        if (pauseparam->autoneg == AUTONEG_ENABLE)
 530                return -EINVAL;
 531
 532        mutex_lock(&bnad->conf_mutex);
 533        if (pauseparam->rx_pause != bnad->bna.enet.pause_config.rx_pause ||
 534            pauseparam->tx_pause != bnad->bna.enet.pause_config.tx_pause) {
 535                pause_config.rx_pause = pauseparam->rx_pause;
 536                pause_config.tx_pause = pauseparam->tx_pause;
 537                spin_lock_irqsave(&bnad->bna_lock, flags);
 538                bna_enet_pause_config(&bnad->bna.enet, &pause_config);
 539                spin_unlock_irqrestore(&bnad->bna_lock, flags);
 540        }
 541        mutex_unlock(&bnad->conf_mutex);
 542        return 0;
 543}
 544
 545static void
 546bnad_get_strings(struct net_device *netdev, u32 stringset, u8 *string)
 547{
 548        struct bnad *bnad = netdev_priv(netdev);
 549        int i, j, q_num;
 550        u32 bmap;
 551
 552        mutex_lock(&bnad->conf_mutex);
 553
 554        switch (stringset) {
 555        case ETH_SS_STATS:
 556                for (i = 0; i < BNAD_ETHTOOL_STATS_NUM; i++) {
 557                        BUG_ON(!(strlen(bnad_net_stats_strings[i]) <
 558                                   ETH_GSTRING_LEN));
 559                        memcpy(string, bnad_net_stats_strings[i],
 560                               ETH_GSTRING_LEN);
 561                        string += ETH_GSTRING_LEN;
 562                }
 563                bmap = bna_tx_rid_mask(&bnad->bna);
 564                for (i = 0; bmap; i++) {
 565                        if (bmap & 1) {
 566                                sprintf(string, "txf%d_ucast_octets", i);
 567                                string += ETH_GSTRING_LEN;
 568                                sprintf(string, "txf%d_ucast", i);
 569                                string += ETH_GSTRING_LEN;
 570                                sprintf(string, "txf%d_ucast_vlan", i);
 571                                string += ETH_GSTRING_LEN;
 572                                sprintf(string, "txf%d_mcast_octets", i);
 573                                string += ETH_GSTRING_LEN;
 574                                sprintf(string, "txf%d_mcast", i);
 575                                string += ETH_GSTRING_LEN;
 576                                sprintf(string, "txf%d_mcast_vlan", i);
 577                                string += ETH_GSTRING_LEN;
 578                                sprintf(string, "txf%d_bcast_octets", i);
 579                                string += ETH_GSTRING_LEN;
 580                                sprintf(string, "txf%d_bcast", i);
 581                                string += ETH_GSTRING_LEN;
 582                                sprintf(string, "txf%d_bcast_vlan", i);
 583                                string += ETH_GSTRING_LEN;
 584                                sprintf(string, "txf%d_errors", i);
 585                                string += ETH_GSTRING_LEN;
 586                                sprintf(string, "txf%d_filter_vlan", i);
 587                                string += ETH_GSTRING_LEN;
 588                                sprintf(string, "txf%d_filter_mac_sa", i);
 589                                string += ETH_GSTRING_LEN;
 590                        }
 591                        bmap >>= 1;
 592                }
 593
 594                bmap = bna_rx_rid_mask(&bnad->bna);
 595                for (i = 0; bmap; i++) {
 596                        if (bmap & 1) {
 597                                sprintf(string, "rxf%d_ucast_octets", i);
 598                                string += ETH_GSTRING_LEN;
 599                                sprintf(string, "rxf%d_ucast", i);
 600                                string += ETH_GSTRING_LEN;
 601                                sprintf(string, "rxf%d_ucast_vlan", i);
 602                                string += ETH_GSTRING_LEN;
 603                                sprintf(string, "rxf%d_mcast_octets", i);
 604                                string += ETH_GSTRING_LEN;
 605                                sprintf(string, "rxf%d_mcast", i);
 606                                string += ETH_GSTRING_LEN;
 607                                sprintf(string, "rxf%d_mcast_vlan", i);
 608                                string += ETH_GSTRING_LEN;
 609                                sprintf(string, "rxf%d_bcast_octets", i);
 610                                string += ETH_GSTRING_LEN;
 611                                sprintf(string, "rxf%d_bcast", i);
 612                                string += ETH_GSTRING_LEN;
 613                                sprintf(string, "rxf%d_bcast_vlan", i);
 614                                string += ETH_GSTRING_LEN;
 615                                sprintf(string, "rxf%d_frame_drops", i);
 616                                string += ETH_GSTRING_LEN;
 617                        }
 618                        bmap >>= 1;
 619                }
 620
 621                q_num = 0;
 622                for (i = 0; i < bnad->num_rx; i++) {
 623                        if (!bnad->rx_info[i].rx)
 624                                continue;
 625                        for (j = 0; j < bnad->num_rxp_per_rx; j++) {
 626                                sprintf(string, "cq%d_producer_index", q_num);
 627                                string += ETH_GSTRING_LEN;
 628                                sprintf(string, "cq%d_consumer_index", q_num);
 629                                string += ETH_GSTRING_LEN;
 630                                sprintf(string, "cq%d_hw_producer_index",
 631                                        q_num);
 632                                string += ETH_GSTRING_LEN;
 633                                sprintf(string, "cq%d_intr", q_num);
 634                                string += ETH_GSTRING_LEN;
 635                                sprintf(string, "cq%d_poll", q_num);
 636                                string += ETH_GSTRING_LEN;
 637                                sprintf(string, "cq%d_schedule", q_num);
 638                                string += ETH_GSTRING_LEN;
 639                                sprintf(string, "cq%d_keep_poll", q_num);
 640                                string += ETH_GSTRING_LEN;
 641                                sprintf(string, "cq%d_complete", q_num);
 642                                string += ETH_GSTRING_LEN;
 643                                q_num++;
 644                        }
 645                }
 646
 647                q_num = 0;
 648                for (i = 0; i < bnad->num_rx; i++) {
 649                        if (!bnad->rx_info[i].rx)
 650                                continue;
 651                        for (j = 0; j < bnad->num_rxp_per_rx; j++) {
 652                                sprintf(string, "rxq%d_packets", q_num);
 653                                string += ETH_GSTRING_LEN;
 654                                sprintf(string, "rxq%d_bytes", q_num);
 655                                string += ETH_GSTRING_LEN;
 656                                sprintf(string, "rxq%d_packets_with_error",
 657                                                                q_num);
 658                                string += ETH_GSTRING_LEN;
 659                                sprintf(string, "rxq%d_allocbuf_failed", q_num);
 660                                string += ETH_GSTRING_LEN;
 661                                sprintf(string, "rxq%d_producer_index", q_num);
 662                                string += ETH_GSTRING_LEN;
 663                                sprintf(string, "rxq%d_consumer_index", q_num);
 664                                string += ETH_GSTRING_LEN;
 665                                q_num++;
 666                                if (bnad->rx_info[i].rx_ctrl[j].ccb &&
 667                                        bnad->rx_info[i].rx_ctrl[j].ccb->
 668                                        rcb[1] &&
 669                                        bnad->rx_info[i].rx_ctrl[j].ccb->
 670                                        rcb[1]->rxq) {
 671                                        sprintf(string, "rxq%d_packets", q_num);
 672                                        string += ETH_GSTRING_LEN;
 673                                        sprintf(string, "rxq%d_bytes", q_num);
 674                                        string += ETH_GSTRING_LEN;
 675                                        sprintf(string,
 676                                        "rxq%d_packets_with_error", q_num);
 677                                        string += ETH_GSTRING_LEN;
 678                                        sprintf(string, "rxq%d_allocbuf_failed",
 679                                                                q_num);
 680                                        string += ETH_GSTRING_LEN;
 681                                        sprintf(string, "rxq%d_producer_index",
 682                                                                q_num);
 683                                        string += ETH_GSTRING_LEN;
 684                                        sprintf(string, "rxq%d_consumer_index",
 685                                                                q_num);
 686                                        string += ETH_GSTRING_LEN;
 687                                        q_num++;
 688                                }
 689                        }
 690                }
 691
 692                q_num = 0;
 693                for (i = 0; i < bnad->num_tx; i++) {
 694                        if (!bnad->tx_info[i].tx)
 695                                continue;
 696                        for (j = 0; j < bnad->num_txq_per_tx; j++) {
 697                                sprintf(string, "txq%d_packets", q_num);
 698                                string += ETH_GSTRING_LEN;
 699                                sprintf(string, "txq%d_bytes", q_num);
 700                                string += ETH_GSTRING_LEN;
 701                                sprintf(string, "txq%d_producer_index", q_num);
 702                                string += ETH_GSTRING_LEN;
 703                                sprintf(string, "txq%d_consumer_index", q_num);
 704                                string += ETH_GSTRING_LEN;
 705                                sprintf(string, "txq%d_hw_consumer_index",
 706                                                                        q_num);
 707                                string += ETH_GSTRING_LEN;
 708                                q_num++;
 709                        }
 710                }
 711
 712                break;
 713
 714        default:
 715                break;
 716        }
 717
 718        mutex_unlock(&bnad->conf_mutex);
 719}
 720
 721static int
 722bnad_get_stats_count_locked(struct net_device *netdev)
 723{
 724        struct bnad *bnad = netdev_priv(netdev);
 725        int i, j, count = 0, rxf_active_num = 0, txf_active_num = 0;
 726        u32 bmap;
 727
 728        bmap = bna_tx_rid_mask(&bnad->bna);
 729        for (i = 0; bmap; i++) {
 730                if (bmap & 1)
 731                        txf_active_num++;
 732                bmap >>= 1;
 733        }
 734        bmap = bna_rx_rid_mask(&bnad->bna);
 735        for (i = 0; bmap; i++) {
 736                if (bmap & 1)
 737                        rxf_active_num++;
 738                bmap >>= 1;
 739        }
 740        count = BNAD_ETHTOOL_STATS_NUM +
 741                txf_active_num * BNAD_NUM_TXF_COUNTERS +
 742                rxf_active_num * BNAD_NUM_RXF_COUNTERS;
 743
 744        for (i = 0; i < bnad->num_rx; i++) {
 745                if (!bnad->rx_info[i].rx)
 746                        continue;
 747                count += bnad->num_rxp_per_rx * BNAD_NUM_CQ_COUNTERS;
 748                count += bnad->num_rxp_per_rx * BNAD_NUM_RXQ_COUNTERS;
 749                for (j = 0; j < bnad->num_rxp_per_rx; j++)
 750                        if (bnad->rx_info[i].rx_ctrl[j].ccb &&
 751                                bnad->rx_info[i].rx_ctrl[j].ccb->rcb[1] &&
 752                                bnad->rx_info[i].rx_ctrl[j].ccb->rcb[1]->rxq)
 753                                count +=  BNAD_NUM_RXQ_COUNTERS;
 754        }
 755
 756        for (i = 0; i < bnad->num_tx; i++) {
 757                if (!bnad->tx_info[i].tx)
 758                        continue;
 759                count += bnad->num_txq_per_tx * BNAD_NUM_TXQ_COUNTERS;
 760        }
 761        return count;
 762}
 763
 764static int
 765bnad_per_q_stats_fill(struct bnad *bnad, u64 *buf, int bi)
 766{
 767        int i, j;
 768        struct bna_rcb *rcb = NULL;
 769        struct bna_tcb *tcb = NULL;
 770
 771        for (i = 0; i < bnad->num_rx; i++) {
 772                if (!bnad->rx_info[i].rx)
 773                        continue;
 774                for (j = 0; j < bnad->num_rxp_per_rx; j++)
 775                        if (bnad->rx_info[i].rx_ctrl[j].ccb &&
 776                                bnad->rx_info[i].rx_ctrl[j].ccb->rcb[0] &&
 777                                bnad->rx_info[i].rx_ctrl[j].ccb->rcb[0]->rxq) {
 778                                buf[bi++] = bnad->rx_info[i].rx_ctrl[j].
 779                                                ccb->producer_index;
 780                                buf[bi++] = 0; /* ccb->consumer_index */
 781                                buf[bi++] = *(bnad->rx_info[i].rx_ctrl[j].
 782                                                ccb->hw_producer_index);
 783
 784                                buf[bi++] = bnad->rx_info[i].
 785                                                rx_ctrl[j].rx_intr_ctr;
 786                                buf[bi++] = bnad->rx_info[i].
 787                                                rx_ctrl[j].rx_poll_ctr;
 788                                buf[bi++] = bnad->rx_info[i].
 789                                                rx_ctrl[j].rx_schedule;
 790                                buf[bi++] = bnad->rx_info[i].
 791                                                rx_ctrl[j].rx_keep_poll;
 792                                buf[bi++] = bnad->rx_info[i].
 793                                                rx_ctrl[j].rx_complete;
 794                        }
 795        }
 796        for (i = 0; i < bnad->num_rx; i++) {
 797                if (!bnad->rx_info[i].rx)
 798                        continue;
 799                for (j = 0; j < bnad->num_rxp_per_rx; j++)
 800                        if (bnad->rx_info[i].rx_ctrl[j].ccb) {
 801                                if (bnad->rx_info[i].rx_ctrl[j].ccb->rcb[0] &&
 802                                        bnad->rx_info[i].rx_ctrl[j].ccb->
 803                                        rcb[0]->rxq) {
 804                                        rcb = bnad->rx_info[i].rx_ctrl[j].
 805                                                        ccb->rcb[0];
 806                                        buf[bi++] = rcb->rxq->rx_packets;
 807                                        buf[bi++] = rcb->rxq->rx_bytes;
 808                                        buf[bi++] = rcb->rxq->
 809                                                        rx_packets_with_error;
 810                                        buf[bi++] = rcb->rxq->
 811                                                        rxbuf_alloc_failed;
 812                                        buf[bi++] = rcb->rxq->rxbuf_map_failed;
 813                                        buf[bi++] = rcb->producer_index;
 814                                        buf[bi++] = rcb->consumer_index;
 815                                }
 816                                if (bnad->rx_info[i].rx_ctrl[j].ccb->rcb[1] &&
 817                                        bnad->rx_info[i].rx_ctrl[j].ccb->
 818                                        rcb[1]->rxq) {
 819                                        rcb = bnad->rx_info[i].rx_ctrl[j].
 820                                                                ccb->rcb[1];
 821                                        buf[bi++] = rcb->rxq->rx_packets;
 822                                        buf[bi++] = rcb->rxq->rx_bytes;
 823                                        buf[bi++] = rcb->rxq->
 824                                                        rx_packets_with_error;
 825                                        buf[bi++] = rcb->rxq->
 826                                                        rxbuf_alloc_failed;
 827                                        buf[bi++] = rcb->rxq->rxbuf_map_failed;
 828                                        buf[bi++] = rcb->producer_index;
 829                                        buf[bi++] = rcb->consumer_index;
 830                                }
 831                        }
 832        }
 833
 834        for (i = 0; i < bnad->num_tx; i++) {
 835                if (!bnad->tx_info[i].tx)
 836                        continue;
 837                for (j = 0; j < bnad->num_txq_per_tx; j++)
 838                        if (bnad->tx_info[i].tcb[j] &&
 839                                bnad->tx_info[i].tcb[j]->txq) {
 840                                tcb = bnad->tx_info[i].tcb[j];
 841                                buf[bi++] = tcb->txq->tx_packets;
 842                                buf[bi++] = tcb->txq->tx_bytes;
 843                                buf[bi++] = tcb->producer_index;
 844                                buf[bi++] = tcb->consumer_index;
 845                                buf[bi++] = *(tcb->hw_consumer_index);
 846                        }
 847        }
 848
 849        return bi;
 850}
 851
 852static void
 853bnad_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats,
 854                       u64 *buf)
 855{
 856        struct bnad *bnad = netdev_priv(netdev);
 857        int i, j, bi;
 858        unsigned long flags;
 859        struct rtnl_link_stats64 *net_stats64;
 860        u64 *stats64;
 861        u32 bmap;
 862
 863        mutex_lock(&bnad->conf_mutex);
 864        if (bnad_get_stats_count_locked(netdev) != stats->n_stats) {
 865                mutex_unlock(&bnad->conf_mutex);
 866                return;
 867        }
 868
 869        /*
 870         * Used bna_lock to sync reads from bna_stats, which is written
 871         * under the same lock
 872         */
 873        spin_lock_irqsave(&bnad->bna_lock, flags);
 874        bi = 0;
 875        memset(buf, 0, stats->n_stats * sizeof(u64));
 876
 877        net_stats64 = (struct rtnl_link_stats64 *)buf;
 878        bnad_netdev_qstats_fill(bnad, net_stats64);
 879        bnad_netdev_hwstats_fill(bnad, net_stats64);
 880
 881        bi = sizeof(*net_stats64) / sizeof(u64);
 882
 883        /* Get netif_queue_stopped from stack */
 884        bnad->stats.drv_stats.netif_queue_stopped = netif_queue_stopped(netdev);
 885
 886        /* Fill driver stats into ethtool buffers */
 887        stats64 = (u64 *)&bnad->stats.drv_stats;
 888        for (i = 0; i < sizeof(struct bnad_drv_stats) / sizeof(u64); i++)
 889                buf[bi++] = stats64[i];
 890
 891        /* Fill hardware stats excluding the rxf/txf into ethtool bufs */
 892        stats64 = (u64 *) &bnad->stats.bna_stats->hw_stats;
 893        for (i = 0;
 894             i < offsetof(struct bfi_enet_stats, rxf_stats[0]) /
 895                sizeof(u64);
 896             i++)
 897                buf[bi++] = stats64[i];
 898
 899        /* Fill txf stats into ethtool buffers */
 900        bmap = bna_tx_rid_mask(&bnad->bna);
 901        for (i = 0; bmap; i++) {
 902                if (bmap & 1) {
 903                        stats64 = (u64 *)&bnad->stats.bna_stats->
 904                                                hw_stats.txf_stats[i];
 905                        for (j = 0; j < sizeof(struct bfi_enet_stats_txf) /
 906                                        sizeof(u64); j++)
 907                                buf[bi++] = stats64[j];
 908                }
 909                bmap >>= 1;
 910        }
 911
 912        /*  Fill rxf stats into ethtool buffers */
 913        bmap = bna_rx_rid_mask(&bnad->bna);
 914        for (i = 0; bmap; i++) {
 915                if (bmap & 1) {
 916                        stats64 = (u64 *)&bnad->stats.bna_stats->
 917                                                hw_stats.rxf_stats[i];
 918                        for (j = 0; j < sizeof(struct bfi_enet_stats_rxf) /
 919                                        sizeof(u64); j++)
 920                                buf[bi++] = stats64[j];
 921                }
 922                bmap >>= 1;
 923        }
 924
 925        /* Fill per Q stats into ethtool buffers */
 926        bi = bnad_per_q_stats_fill(bnad, buf, bi);
 927
 928        spin_unlock_irqrestore(&bnad->bna_lock, flags);
 929
 930        mutex_unlock(&bnad->conf_mutex);
 931}
 932
 933static int
 934bnad_get_sset_count(struct net_device *netdev, int sset)
 935{
 936        switch (sset) {
 937        case ETH_SS_STATS:
 938                return bnad_get_stats_count_locked(netdev);
 939        default:
 940                return -EOPNOTSUPP;
 941        }
 942}
 943
 944static u32
 945bnad_get_flash_partition_by_offset(struct bnad *bnad, u32 offset,
 946                                u32 *base_offset)
 947{
 948        struct bfa_flash_attr *flash_attr;
 949        struct bnad_iocmd_comp fcomp;
 950        u32 i, flash_part = 0, ret;
 951        unsigned long flags = 0;
 952
 953        flash_attr = kzalloc(sizeof(struct bfa_flash_attr), GFP_KERNEL);
 954        if (!flash_attr)
 955                return 0;
 956
 957        fcomp.bnad = bnad;
 958        fcomp.comp_status = 0;
 959
 960        init_completion(&fcomp.comp);
 961        spin_lock_irqsave(&bnad->bna_lock, flags);
 962        ret = bfa_nw_flash_get_attr(&bnad->bna.flash, flash_attr,
 963                                bnad_cb_completion, &fcomp);
 964        if (ret != BFA_STATUS_OK) {
 965                spin_unlock_irqrestore(&bnad->bna_lock, flags);
 966                kfree(flash_attr);
 967                return 0;
 968        }
 969        spin_unlock_irqrestore(&bnad->bna_lock, flags);
 970        wait_for_completion(&fcomp.comp);
 971        ret = fcomp.comp_status;
 972
 973        /* Check for the flash type & base offset value */
 974        if (ret == BFA_STATUS_OK) {
 975                for (i = 0; i < flash_attr->npart; i++) {
 976                        if (offset >= flash_attr->part[i].part_off &&
 977                            offset < (flash_attr->part[i].part_off +
 978                                      flash_attr->part[i].part_size)) {
 979                                flash_part = flash_attr->part[i].part_type;
 980                                *base_offset = flash_attr->part[i].part_off;
 981                                break;
 982                        }
 983                }
 984        }
 985        kfree(flash_attr);
 986        return flash_part;
 987}
 988
 989static int
 990bnad_get_eeprom_len(struct net_device *netdev)
 991{
 992        return BFA_TOTAL_FLASH_SIZE;
 993}
 994
 995static int
 996bnad_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
 997                u8 *bytes)
 998{
 999        struct bnad *bnad = netdev_priv(netdev);
1000        struct bnad_iocmd_comp fcomp;
1001        u32 flash_part = 0, base_offset = 0;
1002        unsigned long flags = 0;
1003        int ret = 0;
1004
1005        /* Fill the magic value */
1006        eeprom->magic = bnad->pcidev->vendor | (bnad->pcidev->device << 16);
1007
1008        /* Query the flash partition based on the offset */
1009        flash_part = bnad_get_flash_partition_by_offset(bnad,
1010                                eeprom->offset, &base_offset);
1011        if (flash_part == 0)
1012                return -EFAULT;
1013
1014        fcomp.bnad = bnad;
1015        fcomp.comp_status = 0;
1016
1017        init_completion(&fcomp.comp);
1018        spin_lock_irqsave(&bnad->bna_lock, flags);
1019        ret = bfa_nw_flash_read_part(&bnad->bna.flash, flash_part,
1020                                bnad->id, bytes, eeprom->len,
1021                                eeprom->offset - base_offset,
1022                                bnad_cb_completion, &fcomp);
1023        if (ret != BFA_STATUS_OK) {
1024                spin_unlock_irqrestore(&bnad->bna_lock, flags);
1025                goto done;
1026        }
1027
1028        spin_unlock_irqrestore(&bnad->bna_lock, flags);
1029        wait_for_completion(&fcomp.comp);
1030        ret = fcomp.comp_status;
1031done:
1032        return ret;
1033}
1034
1035static int
1036bnad_set_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
1037                u8 *bytes)
1038{
1039        struct bnad *bnad = netdev_priv(netdev);
1040        struct bnad_iocmd_comp fcomp;
1041        u32 flash_part = 0, base_offset = 0;
1042        unsigned long flags = 0;
1043        int ret = 0;
1044
1045        /* Check if the flash update request is valid */
1046        if (eeprom->magic != (bnad->pcidev->vendor |
1047                             (bnad->pcidev->device << 16)))
1048                return -EINVAL;
1049
1050        /* Query the flash partition based on the offset */
1051        flash_part = bnad_get_flash_partition_by_offset(bnad,
1052                                eeprom->offset, &base_offset);
1053        if (flash_part == 0)
1054                return -EFAULT;
1055
1056        fcomp.bnad = bnad;
1057        fcomp.comp_status = 0;
1058
1059        init_completion(&fcomp.comp);
1060        spin_lock_irqsave(&bnad->bna_lock, flags);
1061        ret = bfa_nw_flash_update_part(&bnad->bna.flash, flash_part,
1062                                bnad->id, bytes, eeprom->len,
1063                                eeprom->offset - base_offset,
1064                                bnad_cb_completion, &fcomp);
1065        if (ret != BFA_STATUS_OK) {
1066                spin_unlock_irqrestore(&bnad->bna_lock, flags);
1067                goto done;
1068        }
1069
1070        spin_unlock_irqrestore(&bnad->bna_lock, flags);
1071        wait_for_completion(&fcomp.comp);
1072        ret = fcomp.comp_status;
1073done:
1074        return ret;
1075}
1076
1077static int
1078bnad_flash_device(struct net_device *netdev, struct ethtool_flash *eflash)
1079{
1080        struct bnad *bnad = netdev_priv(netdev);
1081        struct bnad_iocmd_comp fcomp;
1082        const struct firmware *fw;
1083        int ret = 0;
1084
1085        ret = request_firmware(&fw, eflash->data, &bnad->pcidev->dev);
1086        if (ret) {
1087                netdev_err(netdev, "can't load firmware %s\n", eflash->data);
1088                goto out;
1089        }
1090
1091        fcomp.bnad = bnad;
1092        fcomp.comp_status = 0;
1093
1094        init_completion(&fcomp.comp);
1095        spin_lock_irq(&bnad->bna_lock);
1096        ret = bfa_nw_flash_update_part(&bnad->bna.flash, BFA_FLASH_PART_FWIMG,
1097                                bnad->id, (u8 *)fw->data, fw->size, 0,
1098                                bnad_cb_completion, &fcomp);
1099        if (ret != BFA_STATUS_OK) {
1100                netdev_warn(netdev, "flash update failed with err=%d\n", ret);
1101                ret = -EIO;
1102                spin_unlock_irq(&bnad->bna_lock);
1103                goto out;
1104        }
1105
1106        spin_unlock_irq(&bnad->bna_lock);
1107        wait_for_completion(&fcomp.comp);
1108        if (fcomp.comp_status != BFA_STATUS_OK) {
1109                ret = -EIO;
1110                netdev_warn(netdev,
1111                            "firmware image update failed with err=%d\n",
1112                            fcomp.comp_status);
1113        }
1114out:
1115        release_firmware(fw);
1116        return ret;
1117}
1118
1119static const struct ethtool_ops bnad_ethtool_ops = {
1120        .get_settings = bnad_get_settings,
1121        .set_settings = bnad_set_settings,
1122        .get_drvinfo = bnad_get_drvinfo,
1123        .get_wol = bnad_get_wol,
1124        .get_link = ethtool_op_get_link,
1125        .get_coalesce = bnad_get_coalesce,
1126        .set_coalesce = bnad_set_coalesce,
1127        .get_ringparam = bnad_get_ringparam,
1128        .set_ringparam = bnad_set_ringparam,
1129        .get_pauseparam = bnad_get_pauseparam,
1130        .set_pauseparam = bnad_set_pauseparam,
1131        .get_strings = bnad_get_strings,
1132        .get_ethtool_stats = bnad_get_ethtool_stats,
1133        .get_sset_count = bnad_get_sset_count,
1134        .get_eeprom_len = bnad_get_eeprom_len,
1135        .get_eeprom = bnad_get_eeprom,
1136        .set_eeprom = bnad_set_eeprom,
1137        .flash_device = bnad_flash_device,
1138        .get_ts_info = ethtool_op_get_ts_info,
1139};
1140
1141void
1142bnad_set_ethtool_ops(struct net_device *netdev)
1143{
1144        netdev->ethtool_ops = &bnad_ethtool_ops;
1145}
1146