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