linux/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
<<
>>
Prefs
   1/*******************************************************************************
   2 *
   3 * Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
   4 * Copyright(c) 2013 - 2016 Intel Corporation.
   5 *
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms and conditions of the GNU General Public License,
   8 * version 2, as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope it will be useful, but WITHOUT
  11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13 * more details.
  14 *
  15 * You should have received a copy of the GNU General Public License along
  16 * with this program.  If not, see <http://www.gnu.org/licenses/>.
  17 *
  18 * The full GNU General Public License is included in this distribution in
  19 * the file called "COPYING".
  20 *
  21 * Contact Information:
  22 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
  23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  24 *
  25 ******************************************************************************/
  26
  27/* ethtool support for i40evf */
  28#include "i40evf.h"
  29
  30#include <linux/uaccess.h>
  31
  32struct i40evf_stats {
  33        char stat_string[ETH_GSTRING_LEN];
  34        int stat_offset;
  35};
  36
  37#define I40EVF_STAT(_name, _stat) { \
  38        .stat_string = _name, \
  39        .stat_offset = offsetof(struct i40evf_adapter, _stat) \
  40}
  41
  42/* All stats are u64, so we don't need to track the size of the field. */
  43static const struct i40evf_stats i40evf_gstrings_stats[] = {
  44        I40EVF_STAT("rx_bytes", current_stats.rx_bytes),
  45        I40EVF_STAT("rx_unicast", current_stats.rx_unicast),
  46        I40EVF_STAT("rx_multicast", current_stats.rx_multicast),
  47        I40EVF_STAT("rx_broadcast", current_stats.rx_broadcast),
  48        I40EVF_STAT("rx_discards", current_stats.rx_discards),
  49        I40EVF_STAT("rx_unknown_protocol", current_stats.rx_unknown_protocol),
  50        I40EVF_STAT("tx_bytes", current_stats.tx_bytes),
  51        I40EVF_STAT("tx_unicast", current_stats.tx_unicast),
  52        I40EVF_STAT("tx_multicast", current_stats.tx_multicast),
  53        I40EVF_STAT("tx_broadcast", current_stats.tx_broadcast),
  54        I40EVF_STAT("tx_discards", current_stats.tx_discards),
  55        I40EVF_STAT("tx_errors", current_stats.tx_errors),
  56};
  57
  58#define I40EVF_GLOBAL_STATS_LEN ARRAY_SIZE(i40evf_gstrings_stats)
  59#define I40EVF_QUEUE_STATS_LEN(_dev) \
  60        (((struct i40evf_adapter *)\
  61                netdev_priv(_dev))->num_active_queues \
  62                  * 2 * (sizeof(struct i40e_queue_stats) / sizeof(u64)))
  63#define I40EVF_STATS_LEN(_dev) \
  64        (I40EVF_GLOBAL_STATS_LEN + I40EVF_QUEUE_STATS_LEN(_dev))
  65
  66static const char i40evf_priv_flags_strings[][ETH_GSTRING_LEN] = {
  67        "packet-split",
  68};
  69
  70#define I40EVF_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40evf_priv_flags_strings)
  71
  72/**
  73 * i40evf_get_settings - Get Link Speed and Duplex settings
  74 * @netdev: network interface device structure
  75 * @ecmd: ethtool command
  76 *
  77 * Reports speed/duplex settings. Because this is a VF, we don't know what
  78 * kind of link we really have, so we fake it.
  79 **/
  80static int i40evf_get_settings(struct net_device *netdev,
  81                               struct ethtool_cmd *ecmd)
  82{
  83        /* In the future the VF will be able to query the PF for
  84         * some information - for now use a dummy value
  85         */
  86        ecmd->supported = 0;
  87        ecmd->autoneg = AUTONEG_DISABLE;
  88        ecmd->transceiver = XCVR_DUMMY1;
  89        ecmd->port = PORT_NONE;
  90
  91        return 0;
  92}
  93
  94/**
  95 * i40evf_get_sset_count - Get length of string set
  96 * @netdev: network interface device structure
  97 * @sset: id of string set
  98 *
  99 * Reports size of string table. This driver only supports
 100 * strings for statistics.
 101 **/
 102static int i40evf_get_sset_count(struct net_device *netdev, int sset)
 103{
 104        if (sset == ETH_SS_STATS)
 105                return I40EVF_STATS_LEN(netdev);
 106        else if (sset == ETH_SS_PRIV_FLAGS)
 107                return I40EVF_PRIV_FLAGS_STR_LEN;
 108        else
 109                return -EINVAL;
 110}
 111
 112/**
 113 * i40evf_get_ethtool_stats - report device statistics
 114 * @netdev: network interface device structure
 115 * @stats: ethtool statistics structure
 116 * @data: pointer to data buffer
 117 *
 118 * All statistics are added to the data buffer as an array of u64.
 119 **/
 120static void i40evf_get_ethtool_stats(struct net_device *netdev,
 121                                     struct ethtool_stats *stats, u64 *data)
 122{
 123        struct i40evf_adapter *adapter = netdev_priv(netdev);
 124        int i, j;
 125        char *p;
 126
 127        for (i = 0; i < I40EVF_GLOBAL_STATS_LEN; i++) {
 128                p = (char *)adapter + i40evf_gstrings_stats[i].stat_offset;
 129                data[i] =  *(u64 *)p;
 130        }
 131        for (j = 0; j < adapter->num_active_queues; j++) {
 132                data[i++] = adapter->tx_rings[j].stats.packets;
 133                data[i++] = adapter->tx_rings[j].stats.bytes;
 134        }
 135        for (j = 0; j < adapter->num_active_queues; j++) {
 136                data[i++] = adapter->rx_rings[j].stats.packets;
 137                data[i++] = adapter->rx_rings[j].stats.bytes;
 138        }
 139}
 140
 141/**
 142 * i40evf_get_strings - Get string set
 143 * @netdev: network interface device structure
 144 * @sset: id of string set
 145 * @data: buffer for string data
 146 *
 147 * Builds stats string table.
 148 **/
 149static void i40evf_get_strings(struct net_device *netdev, u32 sset, u8 *data)
 150{
 151        struct i40evf_adapter *adapter = netdev_priv(netdev);
 152        u8 *p = data;
 153        int i;
 154
 155        if (sset == ETH_SS_STATS) {
 156                for (i = 0; i < I40EVF_GLOBAL_STATS_LEN; i++) {
 157                        memcpy(p, i40evf_gstrings_stats[i].stat_string,
 158                               ETH_GSTRING_LEN);
 159                        p += ETH_GSTRING_LEN;
 160                }
 161                for (i = 0; i < adapter->num_active_queues; i++) {
 162                        snprintf(p, ETH_GSTRING_LEN, "tx-%u.packets", i);
 163                        p += ETH_GSTRING_LEN;
 164                        snprintf(p, ETH_GSTRING_LEN, "tx-%u.bytes", i);
 165                        p += ETH_GSTRING_LEN;
 166                }
 167                for (i = 0; i < adapter->num_active_queues; i++) {
 168                        snprintf(p, ETH_GSTRING_LEN, "rx-%u.packets", i);
 169                        p += ETH_GSTRING_LEN;
 170                        snprintf(p, ETH_GSTRING_LEN, "rx-%u.bytes", i);
 171                        p += ETH_GSTRING_LEN;
 172                }
 173        } else if (sset == ETH_SS_PRIV_FLAGS) {
 174                for (i = 0; i < I40EVF_PRIV_FLAGS_STR_LEN; i++) {
 175                        memcpy(data, i40evf_priv_flags_strings[i],
 176                               ETH_GSTRING_LEN);
 177                        data += ETH_GSTRING_LEN;
 178                }
 179        }
 180}
 181
 182/**
 183 * i40evf_get_msglevel - Get debug message level
 184 * @netdev: network interface device structure
 185 *
 186 * Returns current debug message level.
 187 **/
 188static u32 i40evf_get_msglevel(struct net_device *netdev)
 189{
 190        struct i40evf_adapter *adapter = netdev_priv(netdev);
 191
 192        return adapter->msg_enable;
 193}
 194
 195/**
 196 * i40evf_set_msglevel - Set debug message level
 197 * @netdev: network interface device structure
 198 * @data: message level
 199 *
 200 * Set current debug message level. Higher values cause the driver to
 201 * be noisier.
 202 **/
 203static void i40evf_set_msglevel(struct net_device *netdev, u32 data)
 204{
 205        struct i40evf_adapter *adapter = netdev_priv(netdev);
 206
 207        if (I40E_DEBUG_USER & data)
 208                adapter->hw.debug_mask = data;
 209        adapter->msg_enable = data;
 210}
 211
 212/**
 213 * i40evf_get_drvinfo - Get driver info
 214 * @netdev: network interface device structure
 215 * @drvinfo: ethool driver info structure
 216 *
 217 * Returns information about the driver and device for display to the user.
 218 **/
 219static void i40evf_get_drvinfo(struct net_device *netdev,
 220                               struct ethtool_drvinfo *drvinfo)
 221{
 222        struct i40evf_adapter *adapter = netdev_priv(netdev);
 223
 224        strlcpy(drvinfo->driver, i40evf_driver_name, 32);
 225        strlcpy(drvinfo->version, i40evf_driver_version, 32);
 226        strlcpy(drvinfo->fw_version, "N/A", 4);
 227        strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
 228        drvinfo->n_priv_flags = I40EVF_PRIV_FLAGS_STR_LEN;
 229}
 230
 231/**
 232 * i40evf_get_ringparam - Get ring parameters
 233 * @netdev: network interface device structure
 234 * @ring: ethtool ringparam structure
 235 *
 236 * Returns current ring parameters. TX and RX rings are reported separately,
 237 * but the number of rings is not reported.
 238 **/
 239static void i40evf_get_ringparam(struct net_device *netdev,
 240                                 struct ethtool_ringparam *ring)
 241{
 242        struct i40evf_adapter *adapter = netdev_priv(netdev);
 243
 244        ring->rx_max_pending = I40EVF_MAX_RXD;
 245        ring->tx_max_pending = I40EVF_MAX_TXD;
 246        ring->rx_pending = adapter->rx_desc_count;
 247        ring->tx_pending = adapter->tx_desc_count;
 248}
 249
 250/**
 251 * i40evf_set_ringparam - Set ring parameters
 252 * @netdev: network interface device structure
 253 * @ring: ethtool ringparam structure
 254 *
 255 * Sets ring parameters. TX and RX rings are controlled separately, but the
 256 * number of rings is not specified, so all rings get the same settings.
 257 **/
 258static int i40evf_set_ringparam(struct net_device *netdev,
 259                                struct ethtool_ringparam *ring)
 260{
 261        struct i40evf_adapter *adapter = netdev_priv(netdev);
 262        u32 new_rx_count, new_tx_count;
 263
 264        if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
 265                return -EINVAL;
 266
 267        new_tx_count = clamp_t(u32, ring->tx_pending,
 268                               I40EVF_MIN_TXD,
 269                               I40EVF_MAX_TXD);
 270        new_tx_count = ALIGN(new_tx_count, I40EVF_REQ_DESCRIPTOR_MULTIPLE);
 271
 272        new_rx_count = clamp_t(u32, ring->rx_pending,
 273                               I40EVF_MIN_RXD,
 274                               I40EVF_MAX_RXD);
 275        new_rx_count = ALIGN(new_rx_count, I40EVF_REQ_DESCRIPTOR_MULTIPLE);
 276
 277        /* if nothing to do return success */
 278        if ((new_tx_count == adapter->tx_desc_count) &&
 279            (new_rx_count == adapter->rx_desc_count))
 280                return 0;
 281
 282        adapter->tx_desc_count = new_tx_count;
 283        adapter->rx_desc_count = new_rx_count;
 284
 285        if (netif_running(netdev)) {
 286                adapter->flags |= I40EVF_FLAG_RESET_NEEDED;
 287                schedule_work(&adapter->reset_task);
 288        }
 289
 290        return 0;
 291}
 292
 293/**
 294 * i40evf_get_coalesce - Get interrupt coalescing settings
 295 * @netdev: network interface device structure
 296 * @ec: ethtool coalesce structure
 297 *
 298 * Returns current coalescing settings. This is referred to elsewhere in the
 299 * driver as Interrupt Throttle Rate, as this is how the hardware describes
 300 * this functionality.
 301 **/
 302static int i40evf_get_coalesce(struct net_device *netdev,
 303                               struct ethtool_coalesce *ec)
 304{
 305        struct i40evf_adapter *adapter = netdev_priv(netdev);
 306        struct i40e_vsi *vsi = &adapter->vsi;
 307
 308        ec->tx_max_coalesced_frames = vsi->work_limit;
 309        ec->rx_max_coalesced_frames = vsi->work_limit;
 310
 311        if (ITR_IS_DYNAMIC(vsi->rx_itr_setting))
 312                ec->use_adaptive_rx_coalesce = 1;
 313
 314        if (ITR_IS_DYNAMIC(vsi->tx_itr_setting))
 315                ec->use_adaptive_tx_coalesce = 1;
 316
 317        ec->rx_coalesce_usecs = vsi->rx_itr_setting & ~I40E_ITR_DYNAMIC;
 318        ec->tx_coalesce_usecs = vsi->tx_itr_setting & ~I40E_ITR_DYNAMIC;
 319
 320        return 0;
 321}
 322
 323/**
 324 * i40evf_set_coalesce - Set interrupt coalescing settings
 325 * @netdev: network interface device structure
 326 * @ec: ethtool coalesce structure
 327 *
 328 * Change current coalescing settings.
 329 **/
 330static int i40evf_set_coalesce(struct net_device *netdev,
 331                               struct ethtool_coalesce *ec)
 332{
 333        struct i40evf_adapter *adapter = netdev_priv(netdev);
 334        struct i40e_hw *hw = &adapter->hw;
 335        struct i40e_vsi *vsi = &adapter->vsi;
 336        struct i40e_q_vector *q_vector;
 337        int i;
 338
 339        if (ec->tx_max_coalesced_frames_irq || ec->rx_max_coalesced_frames_irq)
 340                vsi->work_limit = ec->tx_max_coalesced_frames_irq;
 341
 342        if ((ec->rx_coalesce_usecs >= (I40E_MIN_ITR << 1)) &&
 343            (ec->rx_coalesce_usecs <= (I40E_MAX_ITR << 1)))
 344                vsi->rx_itr_setting = ec->rx_coalesce_usecs;
 345
 346        else
 347                return -EINVAL;
 348
 349        if ((ec->tx_coalesce_usecs >= (I40E_MIN_ITR << 1)) &&
 350            (ec->tx_coalesce_usecs <= (I40E_MAX_ITR << 1)))
 351                vsi->tx_itr_setting = ec->tx_coalesce_usecs;
 352        else if (ec->use_adaptive_tx_coalesce)
 353                vsi->tx_itr_setting = (I40E_ITR_DYNAMIC |
 354                                       ITR_REG_TO_USEC(I40E_ITR_RX_DEF));
 355        else
 356                return -EINVAL;
 357
 358        if (ec->use_adaptive_rx_coalesce)
 359                vsi->rx_itr_setting |= I40E_ITR_DYNAMIC;
 360        else
 361                vsi->rx_itr_setting &= ~I40E_ITR_DYNAMIC;
 362
 363        if (ec->use_adaptive_tx_coalesce)
 364                vsi->tx_itr_setting |= I40E_ITR_DYNAMIC;
 365        else
 366                vsi->tx_itr_setting &= ~I40E_ITR_DYNAMIC;
 367
 368        for (i = 0; i < adapter->num_msix_vectors - NONQ_VECS; i++) {
 369                q_vector = &adapter->q_vectors[i];
 370                q_vector->rx.itr = ITR_TO_REG(vsi->rx_itr_setting);
 371                wr32(hw, I40E_VFINT_ITRN1(0, i), q_vector->rx.itr);
 372                q_vector->tx.itr = ITR_TO_REG(vsi->tx_itr_setting);
 373                wr32(hw, I40E_VFINT_ITRN1(1, i), q_vector->tx.itr);
 374                i40e_flush(hw);
 375        }
 376
 377        return 0;
 378}
 379
 380/**
 381 * i40e_get_rss_hash_opts - Get RSS hash Input Set for each flow type
 382 * @adapter: board private structure
 383 * @cmd: ethtool rxnfc command
 384 *
 385 * Returns Success if the flow is supported, else Invalid Input.
 386 **/
 387static int i40evf_get_rss_hash_opts(struct i40evf_adapter *adapter,
 388                                    struct ethtool_rxnfc *cmd)
 389{
 390        struct i40e_hw *hw = &adapter->hw;
 391        u64 hena = (u64)rd32(hw, I40E_VFQF_HENA(0)) |
 392                   ((u64)rd32(hw, I40E_VFQF_HENA(1)) << 32);
 393
 394        /* We always hash on IP src and dest addresses */
 395        cmd->data = RXH_IP_SRC | RXH_IP_DST;
 396
 397        switch (cmd->flow_type) {
 398        case TCP_V4_FLOW:
 399                if (hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP))
 400                        cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
 401                break;
 402        case UDP_V4_FLOW:
 403                if (hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP))
 404                        cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
 405                break;
 406
 407        case SCTP_V4_FLOW:
 408        case AH_ESP_V4_FLOW:
 409        case AH_V4_FLOW:
 410        case ESP_V4_FLOW:
 411        case IPV4_FLOW:
 412                break;
 413
 414        case TCP_V6_FLOW:
 415                if (hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP))
 416                        cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
 417                break;
 418        case UDP_V6_FLOW:
 419                if (hena & BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP))
 420                        cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
 421                break;
 422
 423        case SCTP_V6_FLOW:
 424        case AH_ESP_V6_FLOW:
 425        case AH_V6_FLOW:
 426        case ESP_V6_FLOW:
 427        case IPV6_FLOW:
 428                break;
 429        default:
 430                cmd->data = 0;
 431                return -EINVAL;
 432        }
 433
 434        return 0;
 435}
 436
 437/**
 438 * i40evf_get_rxnfc - command to get RX flow classification rules
 439 * @netdev: network interface device structure
 440 * @cmd: ethtool rxnfc command
 441 *
 442 * Returns Success if the command is supported.
 443 **/
 444static int i40evf_get_rxnfc(struct net_device *netdev,
 445                            struct ethtool_rxnfc *cmd,
 446                            u32 *rule_locs)
 447{
 448        struct i40evf_adapter *adapter = netdev_priv(netdev);
 449        int ret = -EOPNOTSUPP;
 450
 451        switch (cmd->cmd) {
 452        case ETHTOOL_GRXRINGS:
 453                cmd->data = adapter->num_active_queues;
 454                ret = 0;
 455                break;
 456        case ETHTOOL_GRXFH:
 457                ret = i40evf_get_rss_hash_opts(adapter, cmd);
 458                break;
 459        default:
 460                break;
 461        }
 462
 463        return ret;
 464}
 465
 466/**
 467 * i40evf_set_rss_hash_opt - Enable/Disable flow types for RSS hash
 468 * @adapter: board private structure
 469 * @cmd: ethtool rxnfc command
 470 *
 471 * Returns Success if the flow input set is supported.
 472 **/
 473static int i40evf_set_rss_hash_opt(struct i40evf_adapter *adapter,
 474                                   struct ethtool_rxnfc *nfc)
 475{
 476        struct i40e_hw *hw = &adapter->hw;
 477        u32 flags = adapter->vf_res->vf_offload_flags;
 478
 479        u64 hena = (u64)rd32(hw, I40E_VFQF_HENA(0)) |
 480                   ((u64)rd32(hw, I40E_VFQF_HENA(1)) << 32);
 481
 482        /* RSS does not support anything other than hashing
 483         * to queues on src and dst IPs and ports
 484         */
 485        if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
 486                          RXH_L4_B_0_1 | RXH_L4_B_2_3))
 487                return -EINVAL;
 488
 489        /* We need at least the IP SRC and DEST fields for hashing */
 490        if (!(nfc->data & RXH_IP_SRC) ||
 491            !(nfc->data & RXH_IP_DST))
 492                return -EINVAL;
 493
 494        switch (nfc->flow_type) {
 495        case TCP_V4_FLOW:
 496                if (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
 497                        if (flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)
 498                                hena |=
 499                           BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
 500
 501                        hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
 502                } else {
 503                        return -EINVAL;
 504                }
 505                break;
 506        case TCP_V6_FLOW:
 507                if (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
 508                        if (flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)
 509                                hena |=
 510                           BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
 511
 512                        hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
 513                } else {
 514                        return -EINVAL;
 515                }
 516                break;
 517        case UDP_V4_FLOW:
 518                if (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
 519                        if (flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)
 520                                hena |=
 521                            BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
 522                            BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
 523
 524                        hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
 525                                 BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4));
 526                } else {
 527                        return -EINVAL;
 528                }
 529                break;
 530        case UDP_V6_FLOW:
 531                if (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
 532                        if (flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)
 533                                hena |=
 534                            BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
 535                            BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
 536
 537                        hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
 538                                 BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6));
 539                } else {
 540                        return -EINVAL;
 541                }
 542                break;
 543        case AH_ESP_V4_FLOW:
 544        case AH_V4_FLOW:
 545        case ESP_V4_FLOW:
 546        case SCTP_V4_FLOW:
 547                if ((nfc->data & RXH_L4_B_0_1) ||
 548                    (nfc->data & RXH_L4_B_2_3))
 549                        return -EINVAL;
 550                hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER);
 551                break;
 552        case AH_ESP_V6_FLOW:
 553        case AH_V6_FLOW:
 554        case ESP_V6_FLOW:
 555        case SCTP_V6_FLOW:
 556                if ((nfc->data & RXH_L4_B_0_1) ||
 557                    (nfc->data & RXH_L4_B_2_3))
 558                        return -EINVAL;
 559                hena |= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER);
 560                break;
 561        case IPV4_FLOW:
 562                hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER) |
 563                         BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4));
 564                break;
 565        case IPV6_FLOW:
 566                hena |= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER) |
 567                         BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6));
 568                break;
 569        default:
 570                return -EINVAL;
 571        }
 572
 573        wr32(hw, I40E_VFQF_HENA(0), (u32)hena);
 574        wr32(hw, I40E_VFQF_HENA(1), (u32)(hena >> 32));
 575        i40e_flush(hw);
 576
 577        return 0;
 578}
 579
 580/**
 581 * i40evf_set_rxnfc - command to set RX flow classification rules
 582 * @netdev: network interface device structure
 583 * @cmd: ethtool rxnfc command
 584 *
 585 * Returns Success if the command is supported.
 586 **/
 587static int i40evf_set_rxnfc(struct net_device *netdev,
 588                            struct ethtool_rxnfc *cmd)
 589{
 590        struct i40evf_adapter *adapter = netdev_priv(netdev);
 591        int ret = -EOPNOTSUPP;
 592
 593        switch (cmd->cmd) {
 594        case ETHTOOL_SRXFH:
 595                ret = i40evf_set_rss_hash_opt(adapter, cmd);
 596                break;
 597        default:
 598                break;
 599        }
 600
 601        return ret;
 602}
 603
 604/**
 605 * i40evf_get_channels: get the number of channels supported by the device
 606 * @netdev: network interface device structure
 607 * @ch: channel information structure
 608 *
 609 * For the purposes of our device, we only use combined channels, i.e. a tx/rx
 610 * queue pair. Report one extra channel to match our "other" MSI-X vector.
 611 **/
 612static void i40evf_get_channels(struct net_device *netdev,
 613                                struct ethtool_channels *ch)
 614{
 615        struct i40evf_adapter *adapter = netdev_priv(netdev);
 616
 617        /* Report maximum channels */
 618        ch->max_combined = adapter->num_active_queues;
 619
 620        ch->max_other = NONQ_VECS;
 621        ch->other_count = NONQ_VECS;
 622
 623        ch->combined_count = adapter->num_active_queues;
 624}
 625
 626/**
 627 * i40evf_get_rxfh_indir_size - get the rx flow hash indirection table size
 628 * @netdev: network interface device structure
 629 *
 630 * Returns the table size.
 631 **/
 632static u32 i40evf_get_rxfh_indir_size(struct net_device *netdev)
 633{
 634        return (I40E_VFQF_HLUT_MAX_INDEX + 1) * 4;
 635}
 636
 637/**
 638 * i40evf_get_rxfh - get the rx flow hash indirection table
 639 * @netdev: network interface device structure
 640 * @indir: indirection table
 641 * @key: hash key
 642 *
 643 * Reads the indirection table directly from the hardware. Always returns 0.
 644 **/
 645static int i40evf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
 646                           u8 *hfunc)
 647{
 648        struct i40evf_adapter *adapter = netdev_priv(netdev);
 649        struct i40e_vsi *vsi = &adapter->vsi;
 650        u8 *seed = NULL, *lut;
 651        int ret;
 652        u16 i;
 653
 654        if (hfunc)
 655                *hfunc = ETH_RSS_HASH_TOP;
 656        if (!indir)
 657                return 0;
 658
 659        seed = key;
 660
 661        lut = kzalloc(I40EVF_HLUT_ARRAY_SIZE, GFP_KERNEL);
 662        if (!lut)
 663                return -ENOMEM;
 664
 665        ret = i40evf_get_rss(vsi, seed, lut, I40EVF_HLUT_ARRAY_SIZE);
 666        if (ret)
 667                goto out;
 668
 669        /* Each 32 bits pointed by 'indir' is stored with a lut entry */
 670        for (i = 0; i < I40EVF_HLUT_ARRAY_SIZE; i++)
 671                indir[i] = (u32)lut[i];
 672
 673out:
 674        kfree(lut);
 675
 676        return ret;
 677}
 678
 679/**
 680 * i40evf_set_rxfh - set the rx flow hash indirection table
 681 * @netdev: network interface device structure
 682 * @indir: indirection table
 683 * @key: hash key
 684 *
 685 * Returns -EINVAL if the table specifies an inavlid queue id, otherwise
 686 * returns 0 after programming the table.
 687 **/
 688static int i40evf_set_rxfh(struct net_device *netdev, const u32 *indir,
 689                           const u8 *key, const u8 hfunc)
 690{
 691        struct i40evf_adapter *adapter = netdev_priv(netdev);
 692        struct i40e_vsi *vsi = &adapter->vsi;
 693        u8 *seed = NULL;
 694        u16 i;
 695
 696        /* We do not allow change in unsupported parameters */
 697        if (key ||
 698            (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP))
 699                return -EOPNOTSUPP;
 700        if (!indir)
 701                return 0;
 702
 703        if (key) {
 704                if (!vsi->rss_hkey_user) {
 705                        vsi->rss_hkey_user = kzalloc(I40EVF_HKEY_ARRAY_SIZE,
 706                                                     GFP_KERNEL);
 707                        if (!vsi->rss_hkey_user)
 708                                return -ENOMEM;
 709                }
 710                memcpy(vsi->rss_hkey_user, key, I40EVF_HKEY_ARRAY_SIZE);
 711                seed = vsi->rss_hkey_user;
 712        }
 713        if (!vsi->rss_lut_user) {
 714                vsi->rss_lut_user = kzalloc(I40EVF_HLUT_ARRAY_SIZE,
 715                                            GFP_KERNEL);
 716                if (!vsi->rss_lut_user)
 717                        return -ENOMEM;
 718        }
 719
 720        /* Each 32 bits pointed by 'indir' is stored with a lut entry */
 721        for (i = 0; i < I40EVF_HLUT_ARRAY_SIZE; i++)
 722                vsi->rss_lut_user[i] = (u8)(indir[i]);
 723
 724        return i40evf_config_rss(vsi, seed, vsi->rss_lut_user,
 725                                 I40EVF_HLUT_ARRAY_SIZE);
 726}
 727
 728/**
 729 * i40evf_get_priv_flags - report device private flags
 730 * @dev: network interface device structure
 731 *
 732 * The get string set count and the string set should be matched for each
 733 * flag returned.  Add new strings for each flag to the i40e_priv_flags_strings
 734 * array.
 735 *
 736 * Returns a u32 bitmap of flags.
 737 **/
 738static u32 i40evf_get_priv_flags(struct net_device *dev)
 739{
 740        struct i40evf_adapter *adapter = netdev_priv(dev);
 741        u32 ret_flags = 0;
 742
 743        ret_flags |= adapter->flags & I40EVF_FLAG_RX_PS_ENABLED ?
 744                I40EVF_PRIV_FLAGS_PS : 0;
 745
 746        return ret_flags;
 747}
 748
 749/**
 750 * i40evf_set_priv_flags - set private flags
 751 * @dev: network interface device structure
 752 * @flags: bit flags to be set
 753 **/
 754static int i40evf_set_priv_flags(struct net_device *dev, u32 flags)
 755{
 756        struct i40evf_adapter *adapter = netdev_priv(dev);
 757        bool reset_required = false;
 758
 759        if ((flags & I40EVF_PRIV_FLAGS_PS) &&
 760            !(adapter->flags & I40EVF_FLAG_RX_PS_ENABLED)) {
 761                adapter->flags |= I40EVF_FLAG_RX_PS_ENABLED;
 762                reset_required = true;
 763        } else if (!(flags & I40EVF_PRIV_FLAGS_PS) &&
 764                   (adapter->flags & I40EVF_FLAG_RX_PS_ENABLED)) {
 765                adapter->flags &= ~I40EVF_FLAG_RX_PS_ENABLED;
 766                reset_required = true;
 767        }
 768
 769        /* if needed, issue reset to cause things to take effect */
 770        if (reset_required)
 771                i40evf_schedule_reset(adapter);
 772
 773        return 0;
 774}
 775
 776static const struct ethtool_ops i40evf_ethtool_ops = {
 777        .get_settings           = i40evf_get_settings,
 778        .get_drvinfo            = i40evf_get_drvinfo,
 779        .get_link               = ethtool_op_get_link,
 780        .get_ringparam          = i40evf_get_ringparam,
 781        .set_ringparam          = i40evf_set_ringparam,
 782        .get_strings            = i40evf_get_strings,
 783        .get_ethtool_stats      = i40evf_get_ethtool_stats,
 784        .get_sset_count         = i40evf_get_sset_count,
 785        .get_priv_flags         = i40evf_get_priv_flags,
 786        .set_priv_flags         = i40evf_set_priv_flags,
 787        .get_msglevel           = i40evf_get_msglevel,
 788        .set_msglevel           = i40evf_set_msglevel,
 789        .get_coalesce           = i40evf_get_coalesce,
 790        .set_coalesce           = i40evf_set_coalesce,
 791        .get_rxnfc              = i40evf_get_rxnfc,
 792        .set_rxnfc              = i40evf_set_rxnfc,
 793        .get_rxfh_indir_size    = i40evf_get_rxfh_indir_size,
 794        .get_rxfh               = i40evf_get_rxfh,
 795        .set_rxfh               = i40evf_set_rxfh,
 796        .get_channels           = i40evf_get_channels,
 797};
 798
 799/**
 800 * i40evf_set_ethtool_ops - Initialize ethtool ops struct
 801 * @netdev: network interface device structure
 802 *
 803 * Sets ethtool ops struct in our netdev so that ethtool can call
 804 * our functions.
 805 **/
 806void i40evf_set_ethtool_ops(struct net_device *netdev)
 807{
 808        netdev->ethtool_ops = &i40evf_ethtool_ops;
 809}
 810