Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/net/ethernet/intel/i40e/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 24.10.2025 mit Größe 179 kB image not shown  

Quelle  i40e_ethtool.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2013 - 2018 Intel Corporation. */

/* ethtool support for i40e */

#include <linux/net/intel/libie/pctype.h>
#include "i40e_devids.h"
#include "i40e_diag.h"
#include "i40e_txrx_common.h"
#include "i40e_virtchnl_pf.h"

/* ethtool statistics helpers */

/**
 * struct i40e_stats - definition for an ethtool statistic
 * @stat_string: statistic name to display in ethtool -S output
 * @sizeof_stat: the sizeof() the stat, must be no greater than sizeof(u64)
 * @stat_offset: offsetof() the stat from a base pointer
 *
 * This structure defines a statistic to be added to the ethtool stats buffer.
 * It defines a statistic as offset from a common base pointer. Stats should
 * be defined in constant arrays using the I40E_STAT macro, with every element
 * of the array using the same _type for calculating the sizeof_stat and
 * stat_offset.
 *
 * The @sizeof_stat is expected to be sizeof(u8), sizeof(u16), sizeof(u32) or
 * sizeof(u64). Other sizes are not expected and will produce a WARN_ONCE from
 * the i40e_add_ethtool_stat() helper function.
 *
 * The @stat_string is interpreted as a format string, allowing formatted
 * values to be inserted while looping over multiple structures for a given
 * statistics array. Thus, every statistic string in an array should have the
 * same type and number of format specifiers, to be formatted by variadic
 * arguments to the i40e_add_stat_string() helper function.
 **/

struct i40e_stats {
 char stat_string[ETH_GSTRING_LEN];
 int sizeof_stat;
 int stat_offset;
};

/* Helper macro to define an i40e_stat structure with proper size and type.
 * Use this when defining constant statistics arrays. Note that @_type expects
 * only a type name and is used multiple times.
 */

#define I40E_STAT(_type, _name, _stat) { \
 .stat_string = _name, \
 .sizeof_stat = sizeof_field(_type, _stat), \
 .stat_offset = offsetof(_type, _stat) \
}

/* Helper macro for defining some statistics directly copied from the netdev
 * stats structure.
 */

#define I40E_NETDEV_STAT(_net_stat) \
 I40E_STAT(struct rtnl_link_stats64, #_net_stat, _net_stat)

/* Helper macro for defining some statistics related to queues */
#define I40E_QUEUE_STAT(_name, _stat) \
 I40E_STAT(struct i40e_ring, _name, _stat)

/* Stats associated with a Tx or Rx ring */
static const struct i40e_stats i40e_gstrings_queue_stats[] = {
 I40E_QUEUE_STAT("%s-%u.packets", stats.packets),
 I40E_QUEUE_STAT("%s-%u.bytes", stats.bytes),
};

/**
 * i40e_add_one_ethtool_stat - copy the stat into the supplied buffer
 * @data: location to store the stat value
 * @pointer: basis for where to copy from
 * @stat: the stat definition
 *
 * Copies the stat data defined by the pointer and stat structure pair into
 * the memory supplied as data. Used to implement i40e_add_ethtool_stats and
 * i40e_add_queue_stats. If the pointer is null, data will be zero'd.
 */

static void
i40e_add_one_ethtool_stat(u64 *data, void *pointer,
     const struct i40e_stats *stat)
{
 char *p;

 if (!pointer) {
  /* ensure that the ethtool data buffer is zero'd for any stats
 * which don't have a valid pointer.
 */

  *data = 0;
  return;
 }

 p = (char *)pointer + stat->stat_offset;
 switch (stat->sizeof_stat) {
 case sizeof(u64):
  *data = *((u64 *)p);
  break;
 case sizeof(u32):
  *data = *((u32 *)p);
  break;
 case sizeof(u16):
  *data = *((u16 *)p);
  break;
 case sizeof(u8):
  *data = *((u8 *)p);
  break;
 default:
  WARN_ONCE(1, "unexpected stat size for %s",
     stat->stat_string);
  *data = 0;
 }
}

/**
 * __i40e_add_ethtool_stats - copy stats into the ethtool supplied buffer
 * @data: ethtool stats buffer
 * @pointer: location to copy stats from
 * @stats: array of stats to copy
 * @size: the size of the stats definition
 *
 * Copy the stats defined by the stats array using the pointer as a base into
 * the data buffer supplied by ethtool. Updates the data pointer to point to
 * the next empty location for successive calls to __i40e_add_ethtool_stats.
 * If pointer is null, set the data values to zero and update the pointer to
 * skip these stats.
 **/

static void
__i40e_add_ethtool_stats(u64 **data, void *pointer,
    const struct i40e_stats stats[],
    const unsigned int size)
{
 unsigned int i;

 for (i = 0; i < size; i++)
  i40e_add_one_ethtool_stat((*data)++, pointer, &stats[i]);
}

/**
 * i40e_add_ethtool_stats - copy stats into ethtool supplied buffer
 * @data: ethtool stats buffer
 * @pointer: location where stats are stored
 * @stats: static const array of stat definitions
 *
 * Macro to ease the use of __i40e_add_ethtool_stats by taking a static
 * constant stats array and passing the ARRAY_SIZE(). This avoids typos by
 * ensuring that we pass the size associated with the given stats array.
 *
 * The parameter @stats is evaluated twice, so parameters with side effects
 * should be avoided.
 **/

#define i40e_add_ethtool_stats(data, pointer, stats) \
 __i40e_add_ethtool_stats(data, pointer, stats, ARRAY_SIZE(stats))

/**
 * i40e_add_queue_stats - copy queue statistics into supplied buffer
 * @data: ethtool stats buffer
 * @ring: the ring to copy
 *
 * Queue statistics must be copied while protected by
 * u64_stats_fetch_begin, so we can't directly use i40e_add_ethtool_stats.
 * Assumes that queue stats are defined in i40e_gstrings_queue_stats. If the
 * ring pointer is null, zero out the queue stat values and update the data
 * pointer. Otherwise safely copy the stats from the ring into the supplied
 * buffer and update the data pointer when finished.
 *
 * This function expects to be called while under rcu_read_lock().
 **/

static void
i40e_add_queue_stats(u64 **data, struct i40e_ring *ring)
{
 const unsigned int size = ARRAY_SIZE(i40e_gstrings_queue_stats);
 const struct i40e_stats *stats = i40e_gstrings_queue_stats;
 unsigned int start;
 unsigned int i;

 /* To avoid invalid statistics values, ensure that we keep retrying
 * the copy until we get a consistent value according to
 * u64_stats_fetch_retry. But first, make sure our ring is
 * non-null before attempting to access its syncp.
 */

 do {
  start = !ring ? 0 : u64_stats_fetch_begin(&ring->syncp);
  for (i = 0; i < size; i++) {
   i40e_add_one_ethtool_stat(&(*data)[i], ring,
        &stats[i]);
  }
 } while (ring && u64_stats_fetch_retry(&ring->syncp, start));

 /* Once we successfully copy the stats in, update the data pointer */
 *data += size;
}

/**
 * __i40e_add_stat_strings - copy stat strings into ethtool buffer
 * @p: ethtool supplied buffer
 * @stats: stat definitions array
 * @size: size of the stats array
 *
 * Format and copy the strings described by stats into the buffer pointed at
 * by p.
 **/

static void __i40e_add_stat_strings(u8 **p, const struct i40e_stats stats[],
        const unsigned int size, ...)
{
 unsigned int i;

 for (i = 0; i < size; i++) {
  va_list args;

  va_start(args, size);
  vsnprintf(*p, ETH_GSTRING_LEN, stats[i].stat_string, args);
  *p += ETH_GSTRING_LEN;
  va_end(args);
 }
}

/**
 * i40e_add_stat_strings - copy stat strings into ethtool buffer
 * @p: ethtool supplied buffer
 * @stats: stat definitions array
 *
 * Format and copy the strings described by the const static stats value into
 * the buffer pointed at by p.
 *
 * The parameter @stats is evaluated twice, so parameters with side effects
 * should be avoided. Additionally, stats must be an array such that
 * ARRAY_SIZE can be called on it.
 **/

#define i40e_add_stat_strings(p, stats, ...) \
 __i40e_add_stat_strings(p, stats, ARRAY_SIZE(stats), ## __VA_ARGS__)

#define I40E_PF_STAT(_name, _stat) \
 I40E_STAT(struct i40e_pf, _name, _stat)
#define I40E_VSI_STAT(_name, _stat) \
 I40E_STAT(struct i40e_vsi, _name, _stat)
#define I40E_VEB_STAT(_name, _stat) \
 I40E_STAT(struct i40e_veb, _name, _stat)
#define I40E_VEB_TC_STAT(_name, _stat) \
 I40E_STAT(struct i40e_cp_veb_tc_stats, _name, _stat)
#define I40E_PFC_STAT(_name, _stat) \
 I40E_STAT(struct i40e_pfc_stats, _name, _stat)

static const struct i40e_stats i40e_gstrings_net_stats[] = {
 I40E_NETDEV_STAT(rx_packets),
 I40E_NETDEV_STAT(tx_packets),
 I40E_NETDEV_STAT(rx_bytes),
 I40E_NETDEV_STAT(tx_bytes),
 I40E_NETDEV_STAT(rx_errors),
 I40E_NETDEV_STAT(tx_errors),
 I40E_NETDEV_STAT(rx_dropped),
 I40E_NETDEV_STAT(rx_missed_errors),
 I40E_NETDEV_STAT(tx_dropped),
 I40E_NETDEV_STAT(collisions),
 I40E_NETDEV_STAT(rx_length_errors),
 I40E_NETDEV_STAT(rx_crc_errors),
};

static const struct i40e_stats i40e_gstrings_veb_stats[] = {
 I40E_VEB_STAT("veb.rx_bytes", stats.rx_bytes),
 I40E_VEB_STAT("veb.tx_bytes", stats.tx_bytes),
 I40E_VEB_STAT("veb.rx_unicast", stats.rx_unicast),
 I40E_VEB_STAT("veb.tx_unicast", stats.tx_unicast),
 I40E_VEB_STAT("veb.rx_multicast", stats.rx_multicast),
 I40E_VEB_STAT("veb.tx_multicast", stats.tx_multicast),
 I40E_VEB_STAT("veb.rx_broadcast", stats.rx_broadcast),
 I40E_VEB_STAT("veb.tx_broadcast", stats.tx_broadcast),
 I40E_VEB_STAT("veb.rx_discards", stats.rx_discards),
 I40E_VEB_STAT("veb.tx_discards", stats.tx_discards),
 I40E_VEB_STAT("veb.tx_errors", stats.tx_errors),
 I40E_VEB_STAT("veb.rx_unknown_protocol", stats.rx_unknown_protocol),
};

struct i40e_cp_veb_tc_stats {
 u64 tc_rx_packets;
 u64 tc_rx_bytes;
 u64 tc_tx_packets;
 u64 tc_tx_bytes;
};

static const struct i40e_stats i40e_gstrings_veb_tc_stats[] = {
 I40E_VEB_TC_STAT("veb.tc_%u_tx_packets", tc_tx_packets),
 I40E_VEB_TC_STAT("veb.tc_%u_tx_bytes", tc_tx_bytes),
 I40E_VEB_TC_STAT("veb.tc_%u_rx_packets", tc_rx_packets),
 I40E_VEB_TC_STAT("veb.tc_%u_rx_bytes", tc_rx_bytes),
};

static const struct i40e_stats i40e_gstrings_misc_stats[] = {
 I40E_VSI_STAT("rx_unicast", eth_stats.rx_unicast),
 I40E_VSI_STAT("tx_unicast", eth_stats.tx_unicast),
 I40E_VSI_STAT("rx_multicast", eth_stats.rx_multicast),
 I40E_VSI_STAT("tx_multicast", eth_stats.tx_multicast),
 I40E_VSI_STAT("rx_broadcast", eth_stats.rx_broadcast),
 I40E_VSI_STAT("tx_broadcast", eth_stats.tx_broadcast),
 I40E_VSI_STAT("rx_unknown_protocol", eth_stats.rx_unknown_protocol),
 I40E_VSI_STAT("tx_linearize", tx_linearize),
 I40E_VSI_STAT("tx_force_wb", tx_force_wb),
 I40E_VSI_STAT("tx_busy", tx_busy),
 I40E_VSI_STAT("tx_stopped", tx_stopped),
 I40E_VSI_STAT("rx_alloc_fail", rx_buf_failed),
 I40E_VSI_STAT("rx_pg_alloc_fail", rx_page_failed),
 I40E_VSI_STAT("rx_cache_reuse", rx_page_reuse),
 I40E_VSI_STAT("rx_cache_alloc", rx_page_alloc),
 I40E_VSI_STAT("rx_cache_waive", rx_page_waive),
 I40E_VSI_STAT("rx_cache_busy", rx_page_busy),
 I40E_VSI_STAT("tx_restart", tx_restart),
};

/* These PF_STATs might look like duplicates of some NETDEV_STATs,
 * but they are separate.  This device supports Virtualization, and
 * as such might have several netdevs supporting VMDq and FCoE going
 * through a single port.  The NETDEV_STATs are for individual netdevs
 * seen at the top of the stack, and the PF_STATs are for the physical
 * function at the bottom of the stack hosting those netdevs.
 *
 * The PF_STATs are appended to the netdev stats only when ethtool -S
 * is queried on the base PF netdev, not on the VMDq or FCoE netdev.
 */

static const struct i40e_stats i40e_gstrings_stats[] = {
 I40E_PF_STAT("port.rx_bytes", stats.eth.rx_bytes),
 I40E_PF_STAT("port.tx_bytes", stats.eth.tx_bytes),
 I40E_PF_STAT("port.rx_unicast", stats.eth.rx_unicast),
 I40E_PF_STAT("port.tx_unicast", stats.eth.tx_unicast),
 I40E_PF_STAT("port.rx_multicast", stats.eth.rx_multicast),
 I40E_PF_STAT("port.tx_multicast", stats.eth.tx_multicast),
 I40E_PF_STAT("port.rx_broadcast", stats.eth.rx_broadcast),
 I40E_PF_STAT("port.tx_broadcast", stats.eth.tx_broadcast),
 I40E_PF_STAT("port.tx_errors", stats.eth.tx_errors),
 I40E_PF_STAT("port.rx_discards", stats.eth.rx_discards),
 I40E_PF_STAT("port.tx_dropped_link_down", stats.tx_dropped_link_down),
 I40E_PF_STAT("port.rx_crc_errors", stats.crc_errors),
 I40E_PF_STAT("port.illegal_bytes", stats.illegal_bytes),
 I40E_PF_STAT("port.mac_local_faults", stats.mac_local_faults),
 I40E_PF_STAT("port.mac_remote_faults", stats.mac_remote_faults),
 I40E_PF_STAT("port.tx_timeout", tx_timeout_count),
 I40E_PF_STAT("port.rx_csum_bad", hw_csum_rx_error),
 I40E_PF_STAT("port.rx_length_errors", stats.rx_length_errors),
 I40E_PF_STAT("port.link_xon_rx", stats.link_xon_rx),
 I40E_PF_STAT("port.link_xoff_rx", stats.link_xoff_rx),
 I40E_PF_STAT("port.link_xon_tx", stats.link_xon_tx),
 I40E_PF_STAT("port.link_xoff_tx", stats.link_xoff_tx),
 I40E_PF_STAT("port.rx_size_64", stats.rx_size_64),
 I40E_PF_STAT("port.rx_size_127", stats.rx_size_127),
 I40E_PF_STAT("port.rx_size_255", stats.rx_size_255),
 I40E_PF_STAT("port.rx_size_511", stats.rx_size_511),
 I40E_PF_STAT("port.rx_size_1023", stats.rx_size_1023),
 I40E_PF_STAT("port.rx_size_1522", stats.rx_size_1522),
 I40E_PF_STAT("port.rx_size_big", stats.rx_size_big),
 I40E_PF_STAT("port.tx_size_64", stats.tx_size_64),
 I40E_PF_STAT("port.tx_size_127", stats.tx_size_127),
 I40E_PF_STAT("port.tx_size_255", stats.tx_size_255),
 I40E_PF_STAT("port.tx_size_511", stats.tx_size_511),
 I40E_PF_STAT("port.tx_size_1023", stats.tx_size_1023),
 I40E_PF_STAT("port.tx_size_1522", stats.tx_size_1522),
 I40E_PF_STAT("port.tx_size_big", stats.tx_size_big),
 I40E_PF_STAT("port.rx_undersize", stats.rx_undersize),
 I40E_PF_STAT("port.rx_fragments", stats.rx_fragments),
 I40E_PF_STAT("port.rx_oversize", stats.rx_oversize),
 I40E_PF_STAT("port.rx_jabber", stats.rx_jabber),
 I40E_PF_STAT("port.VF_admin_queue_requests", vf_aq_requests),
 I40E_PF_STAT("port.arq_overflows", arq_overflows),
 I40E_PF_STAT("port.tx_hwtstamp_timeouts", tx_hwtstamp_timeouts),
 I40E_PF_STAT("port.rx_hwtstamp_cleared", rx_hwtstamp_cleared),
 I40E_PF_STAT("port.tx_hwtstamp_skipped", tx_hwtstamp_skipped),
 I40E_PF_STAT("port.fdir_flush_cnt", fd_flush_cnt),
 I40E_PF_STAT("port.fdir_atr_match", stats.fd_atr_match),
 I40E_PF_STAT("port.fdir_atr_tunnel_match", stats.fd_atr_tunnel_match),
 I40E_PF_STAT("port.fdir_atr_status", stats.fd_atr_status),
 I40E_PF_STAT("port.fdir_sb_match", stats.fd_sb_match),
 I40E_PF_STAT("port.fdir_sb_status", stats.fd_sb_status),

 /* LPI stats */
 I40E_PF_STAT("port.tx_lpi_status", stats.tx_lpi_status),
 I40E_PF_STAT("port.rx_lpi_status", stats.rx_lpi_status),
 I40E_PF_STAT("port.tx_lpi_count", stats.tx_lpi_count),
 I40E_PF_STAT("port.rx_lpi_count", stats.rx_lpi_count),
};

struct i40e_pfc_stats {
 u64 priority_xon_rx;
 u64 priority_xoff_rx;
 u64 priority_xon_tx;
 u64 priority_xoff_tx;
 u64 priority_xon_2_xoff;
};

static const struct i40e_stats i40e_gstrings_pfc_stats[] = {
 I40E_PFC_STAT("port.tx_priority_%u_xon_tx", priority_xon_tx),
 I40E_PFC_STAT("port.tx_priority_%u_xoff_tx", priority_xoff_tx),
 I40E_PFC_STAT("port.rx_priority_%u_xon_rx", priority_xon_rx),
 I40E_PFC_STAT("port.rx_priority_%u_xoff_rx", priority_xoff_rx),
 I40E_PFC_STAT("port.rx_priority_%u_xon_2_xoff", priority_xon_2_xoff),
};

#define I40E_NETDEV_STATS_LEN ARRAY_SIZE(i40e_gstrings_net_stats)

#define I40E_MISC_STATS_LEN ARRAY_SIZE(i40e_gstrings_misc_stats)

#define I40E_VSI_STATS_LEN (I40E_NETDEV_STATS_LEN + I40E_MISC_STATS_LEN)

#define I40E_PFC_STATS_LEN (ARRAY_SIZE(i40e_gstrings_pfc_stats) * \
     I40E_MAX_USER_PRIORITY)

#define I40E_VEB_STATS_LEN (ARRAY_SIZE(i40e_gstrings_veb_stats) + \
     (ARRAY_SIZE(i40e_gstrings_veb_tc_stats) * \
      I40E_MAX_TRAFFIC_CLASS))

#define I40E_GLOBAL_STATS_LEN ARRAY_SIZE(i40e_gstrings_stats)

#define I40E_PF_STATS_LEN (I40E_GLOBAL_STATS_LEN + \
     I40E_PFC_STATS_LEN + \
     I40E_VEB_STATS_LEN + \
     I40E_VSI_STATS_LEN)

/* Length of stats for a single queue */
#define I40E_QUEUE_STATS_LEN ARRAY_SIZE(i40e_gstrings_queue_stats)

enum i40e_ethtool_test_id {
 I40E_ETH_TEST_REG = 0,
 I40E_ETH_TEST_EEPROM,
 I40E_ETH_TEST_INTR,
 I40E_ETH_TEST_LINK,
};

static const char i40e_gstrings_test[][ETH_GSTRING_LEN] = {
 "Register test (offline)",
 "Eeprom test (offline)",
 "Interrupt test (offline)",
 "Link test (on/offline)"
};

#define I40E_TEST_LEN (sizeof(i40e_gstrings_test) / ETH_GSTRING_LEN)

struct i40e_priv_flags {
 char flag_string[ETH_GSTRING_LEN];
 u8 bitno;
 bool read_only;
};

#define I40E_PRIV_FLAG(_name, _bitno, _read_only) { \
 .flag_string = _name, \
 .bitno = _bitno, \
 .read_only = _read_only, \
}

static const struct i40e_priv_flags i40e_gstrings_priv_flags[] = {
 /* NOTE: MFP setting cannot be changed */
 I40E_PRIV_FLAG("MFP", I40E_FLAG_MFP_ENA, 1),
 I40E_PRIV_FLAG("total-port-shutdown",
         I40E_FLAG_TOTAL_PORT_SHUTDOWN_ENA, 1),
 I40E_PRIV_FLAG("LinkPolling", I40E_FLAG_LINK_POLLING_ENA, 0),
 I40E_PRIV_FLAG("flow-director-atr", I40E_FLAG_FD_ATR_ENA, 0),
 I40E_PRIV_FLAG("veb-stats", I40E_FLAG_VEB_STATS_ENA, 0),
 I40E_PRIV_FLAG("hw-atr-eviction", I40E_FLAG_HW_ATR_EVICT_ENA, 0),
 I40E_PRIV_FLAG("link-down-on-close",
         I40E_FLAG_LINK_DOWN_ON_CLOSE_ENA, 0),
 I40E_PRIV_FLAG("legacy-rx", I40E_FLAG_LEGACY_RX_ENA, 0),
 I40E_PRIV_FLAG("disable-source-pruning",
         I40E_FLAG_SOURCE_PRUNING_DIS, 0),
 I40E_PRIV_FLAG("disable-fw-lldp", I40E_FLAG_FW_LLDP_DIS, 0),
 I40E_PRIV_FLAG("rs-fec", I40E_FLAG_RS_FEC, 0),
 I40E_PRIV_FLAG("base-r-fec", I40E_FLAG_BASE_R_FEC, 0),
 I40E_PRIV_FLAG("vf-vlan-pruning",
         I40E_FLAG_VF_VLAN_PRUNING_ENA, 0),
 I40E_PRIV_FLAG("mdd-auto-reset-vf",
         I40E_FLAG_MDD_AUTO_RESET_VF, 0),
};

#define I40E_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40e_gstrings_priv_flags)

/* Private flags with a global effect, restricted to PF 0 */
static const struct i40e_priv_flags i40e_gl_gstrings_priv_flags[] = {
 I40E_PRIV_FLAG("vf-true-promisc-support",
         I40E_FLAG_TRUE_PROMISC_ENA, 0),
};

#define I40E_GL_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40e_gl_gstrings_priv_flags)

/**
 * i40e_partition_setting_complaint - generic complaint for MFP restriction
 * @pf: the PF struct
 **/

static void i40e_partition_setting_complaint(struct i40e_pf *pf)
{
 dev_info(&pf->pdev->dev,
   "The link settings are allowed to be changed only from the first partition of a given port. Please switch to the first partition in order to change the setting.\n");
}

/**
 * i40e_phy_type_to_ethtool - convert the phy_types to ethtool link modes
 * @pf: PF struct with phy_types
 * @ks: ethtool link ksettings struct to fill out
 *
 **/

static void i40e_phy_type_to_ethtool(struct i40e_pf *pf,
         struct ethtool_link_ksettings *ks)
{
 struct i40e_link_status *hw_link_info = &pf->hw.phy.link_info;
 u64 phy_types = pf->hw.phy.phy_types;

 ethtool_link_ksettings_zero_link_mode(ks, supported);
 ethtool_link_ksettings_zero_link_mode(ks, advertising);

 if (phy_types & I40E_CAP_PHY_TYPE_SGMII) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           1000baseT_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            1000baseT_Full);
  if (test_bit(I40E_HW_CAP_100M_SGMII, pf->hw.caps)) {
   ethtool_link_ksettings_add_link_mode(ks, supported,
            100baseT_Full);
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            100baseT_Full);
  }
 }
 if (phy_types & I40E_CAP_PHY_TYPE_XAUI ||
     phy_types & I40E_CAP_PHY_TYPE_XFI ||
     phy_types & I40E_CAP_PHY_TYPE_SFI ||
     phy_types & I40E_CAP_PHY_TYPE_10GBASE_SFPP_CU ||
     phy_types & I40E_CAP_PHY_TYPE_10GBASE_AOC) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           10000baseT_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            10000baseT_Full);
 }
 if (phy_types & I40E_CAP_PHY_TYPE_10GBASE_T) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           10000baseT_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            10000baseT_Full);
 }
 if (phy_types & I40E_CAP_PHY_TYPE_2_5GBASE_T) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           2500baseT_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_2_5GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            2500baseT_Full);
 }
 if (phy_types & I40E_CAP_PHY_TYPE_5GBASE_T) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           5000baseT_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_5GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            5000baseT_Full);
 }
 if (phy_types & I40E_CAP_PHY_TYPE_XLAUI ||
     phy_types & I40E_CAP_PHY_TYPE_XLPPI ||
     phy_types & I40E_CAP_PHY_TYPE_40GBASE_AOC)
  ethtool_link_ksettings_add_link_mode(ks, supported,
           40000baseCR4_Full);
 if (phy_types & I40E_CAP_PHY_TYPE_40GBASE_CR4_CU ||
     phy_types & I40E_CAP_PHY_TYPE_40GBASE_CR4) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           40000baseCR4_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_40GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            40000baseCR4_Full);
 }
 if (phy_types & I40E_CAP_PHY_TYPE_100BASE_TX) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           100baseT_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_100MB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            100baseT_Full);
 }
 if (phy_types & I40E_CAP_PHY_TYPE_1000BASE_T) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           1000baseT_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            1000baseT_Full);
 }
 if (phy_types & I40E_CAP_PHY_TYPE_40GBASE_SR4) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           40000baseSR4_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           40000baseSR4_Full);
 }
 if (phy_types & I40E_CAP_PHY_TYPE_40GBASE_LR4) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           40000baseLR4_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           40000baseLR4_Full);
 }
 if (phy_types & I40E_CAP_PHY_TYPE_40GBASE_KR4) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           40000baseKR4_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           40000baseKR4_Full);
 }
 if (phy_types & I40E_CAP_PHY_TYPE_20GBASE_KR2) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           20000baseKR2_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_20GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            20000baseKR2_Full);
 }
 if (phy_types & I40E_CAP_PHY_TYPE_10GBASE_KX4) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           10000baseKX4_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            10000baseKX4_Full);
 }
 if (phy_types & I40E_CAP_PHY_TYPE_10GBASE_KR &&
     !test_bit(I40E_HW_CAP_CRT_RETIMER, pf->hw.caps)) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           10000baseKR_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            10000baseKR_Full);
 }
 if (phy_types & I40E_CAP_PHY_TYPE_1000BASE_KX &&
     !test_bit(I40E_HW_CAP_CRT_RETIMER, pf->hw.caps)) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           1000baseKX_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            1000baseKX_Full);
 }
 /* need to add 25G PHY types */
 if (phy_types & I40E_CAP_PHY_TYPE_25GBASE_KR) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           25000baseKR_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_25GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            25000baseKR_Full);
 }
 if (phy_types & I40E_CAP_PHY_TYPE_25GBASE_CR) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           25000baseCR_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_25GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            25000baseCR_Full);
 }
 if (phy_types & I40E_CAP_PHY_TYPE_25GBASE_SR ||
     phy_types & I40E_CAP_PHY_TYPE_25GBASE_LR) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           25000baseSR_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_25GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            25000baseSR_Full);
 }
 if (phy_types & I40E_CAP_PHY_TYPE_25GBASE_AOC ||
     phy_types & I40E_CAP_PHY_TYPE_25GBASE_ACC) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           25000baseCR_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_25GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            25000baseCR_Full);
 }
 if (phy_types & I40E_CAP_PHY_TYPE_25GBASE_KR ||
     phy_types & I40E_CAP_PHY_TYPE_25GBASE_CR ||
     phy_types & I40E_CAP_PHY_TYPE_25GBASE_SR ||
     phy_types & I40E_CAP_PHY_TYPE_25GBASE_LR ||
     phy_types & I40E_CAP_PHY_TYPE_25GBASE_AOC ||
     phy_types & I40E_CAP_PHY_TYPE_25GBASE_ACC) {
  ethtool_link_ksettings_add_link_mode(ks, supported, FEC_NONE);
  ethtool_link_ksettings_add_link_mode(ks, supported, FEC_RS);
  ethtool_link_ksettings_add_link_mode(ks, supported, FEC_BASER);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_25GB) {
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            FEC_NONE);
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            FEC_RS);
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            FEC_BASER);
  }
 }
 /* need to add new 10G PHY types */
 if (phy_types & I40E_CAP_PHY_TYPE_10GBASE_CR1 ||
     phy_types & I40E_CAP_PHY_TYPE_10GBASE_CR1_CU) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           10000baseCR_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            10000baseCR_Full);
 }
 if (phy_types & I40E_CAP_PHY_TYPE_10GBASE_SR) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           10000baseSR_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            10000baseSR_Full);
 }
 if (phy_types & I40E_CAP_PHY_TYPE_10GBASE_LR) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           10000baseLR_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            10000baseLR_Full);
 }
 if (phy_types & I40E_CAP_PHY_TYPE_1000BASE_SX ||
     phy_types & I40E_CAP_PHY_TYPE_1000BASE_LX ||
     phy_types & I40E_CAP_PHY_TYPE_1000BASE_T_OPTICAL) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           1000baseX_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            1000baseX_Full);
 }
 /* Autoneg PHY types */
 if (phy_types & I40E_CAP_PHY_TYPE_SGMII ||
     phy_types & I40E_CAP_PHY_TYPE_40GBASE_KR4 ||
     phy_types & I40E_CAP_PHY_TYPE_40GBASE_CR4_CU ||
     phy_types & I40E_CAP_PHY_TYPE_40GBASE_CR4 ||
     phy_types & I40E_CAP_PHY_TYPE_25GBASE_SR ||
     phy_types & I40E_CAP_PHY_TYPE_25GBASE_LR ||
     phy_types & I40E_CAP_PHY_TYPE_25GBASE_KR ||
     phy_types & I40E_CAP_PHY_TYPE_25GBASE_CR ||
     phy_types & I40E_CAP_PHY_TYPE_20GBASE_KR2 ||
     phy_types & I40E_CAP_PHY_TYPE_10GBASE_SR ||
     phy_types & I40E_CAP_PHY_TYPE_10GBASE_LR ||
     phy_types & I40E_CAP_PHY_TYPE_10GBASE_KX4 ||
     phy_types & I40E_CAP_PHY_TYPE_10GBASE_KR ||
     phy_types & I40E_CAP_PHY_TYPE_10GBASE_CR1_CU ||
     phy_types & I40E_CAP_PHY_TYPE_10GBASE_CR1 ||
     phy_types & I40E_CAP_PHY_TYPE_10GBASE_T ||
     phy_types & I40E_CAP_PHY_TYPE_5GBASE_T ||
     phy_types & I40E_CAP_PHY_TYPE_2_5GBASE_T ||
     phy_types & I40E_CAP_PHY_TYPE_1000BASE_T_OPTICAL ||
     phy_types & I40E_CAP_PHY_TYPE_1000BASE_T ||
     phy_types & I40E_CAP_PHY_TYPE_1000BASE_SX ||
     phy_types & I40E_CAP_PHY_TYPE_1000BASE_LX ||
     phy_types & I40E_CAP_PHY_TYPE_1000BASE_KX ||
     phy_types & I40E_CAP_PHY_TYPE_100BASE_TX) {
  ethtool_link_ksettings_add_link_mode(ks, supported,
           Autoneg);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           Autoneg);
 }
}

/**
 * i40e_get_settings_link_up_fec - Get the FEC mode encoding from mask
 * @req_fec_info: mask request FEC info
 * @ks: ethtool ksettings to fill in
 **/

static void i40e_get_settings_link_up_fec(u8 req_fec_info,
       struct ethtool_link_ksettings *ks)
{
 ethtool_link_ksettings_add_link_mode(ks, supported, FEC_NONE);
 ethtool_link_ksettings_add_link_mode(ks, supported, FEC_RS);
 ethtool_link_ksettings_add_link_mode(ks, supported, FEC_BASER);

 if ((I40E_AQ_SET_FEC_REQUEST_RS & req_fec_info) &&
     (I40E_AQ_SET_FEC_REQUEST_KR & req_fec_info)) {
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           FEC_NONE);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           FEC_BASER);
  ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_RS);
 } else if (I40E_AQ_SET_FEC_REQUEST_RS & req_fec_info) {
  ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_RS);
 } else if (I40E_AQ_SET_FEC_REQUEST_KR & req_fec_info) {
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           FEC_BASER);
 } else {
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           FEC_NONE);
 }
}

/**
 * i40e_get_settings_link_up - Get the Link settings for when link is up
 * @hw: hw structure
 * @ks: ethtool ksettings to fill in
 * @netdev: network interface device structure
 * @pf: pointer to physical function struct
 **/

static void i40e_get_settings_link_up(struct i40e_hw *hw,
          struct ethtool_link_ksettings *ks,
          struct net_device *netdev,
          struct i40e_pf *pf)
{
 struct i40e_link_status *hw_link_info = &hw->phy.link_info;
 struct ethtool_link_ksettings cap_ksettings;
 u32 link_speed = hw_link_info->link_speed;

 /* Initialize supported and advertised settings based on phy settings */
 switch (hw_link_info->phy_type) {
 case I40E_PHY_TYPE_40GBASE_CR4:
 case I40E_PHY_TYPE_40GBASE_CR4_CU:
  ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg);
  ethtool_link_ksettings_add_link_mode(ks, supported,
           40000baseCR4_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising, Autoneg);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           40000baseCR4_Full);
  break;
 case I40E_PHY_TYPE_XLAUI:
 case I40E_PHY_TYPE_XLPPI:
 case I40E_PHY_TYPE_40GBASE_AOC:
  ethtool_link_ksettings_add_link_mode(ks, supported,
           40000baseCR4_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           40000baseCR4_Full);
  break;
 case I40E_PHY_TYPE_40GBASE_SR4:
  ethtool_link_ksettings_add_link_mode(ks, supported,
           40000baseSR4_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           40000baseSR4_Full);
  break;
 case I40E_PHY_TYPE_40GBASE_LR4:
  ethtool_link_ksettings_add_link_mode(ks, supported,
           40000baseLR4_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           40000baseLR4_Full);
  break;
 case I40E_PHY_TYPE_25GBASE_SR:
 case I40E_PHY_TYPE_25GBASE_LR:
 case I40E_PHY_TYPE_10GBASE_SR:
 case I40E_PHY_TYPE_10GBASE_LR:
 case I40E_PHY_TYPE_1000BASE_SX:
 case I40E_PHY_TYPE_1000BASE_LX:
  ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg);
  ethtool_link_ksettings_add_link_mode(ks, advertising, Autoneg);
  ethtool_link_ksettings_add_link_mode(ks, supported,
           25000baseSR_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           25000baseSR_Full);
  i40e_get_settings_link_up_fec(hw_link_info->req_fec_info, ks);
  ethtool_link_ksettings_add_link_mode(ks, supported,
           10000baseSR_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           10000baseSR_Full);
  ethtool_link_ksettings_add_link_mode(ks, supported,
           10000baseLR_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           10000baseLR_Full);
  ethtool_link_ksettings_add_link_mode(ks, supported,
           1000baseX_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           1000baseX_Full);
  ethtool_link_ksettings_add_link_mode(ks, supported,
           10000baseT_Full);
  if (hw_link_info->module_type[2] &
      I40E_MODULE_TYPE_1000BASE_SX ||
      hw_link_info->module_type[2] &
      I40E_MODULE_TYPE_1000BASE_LX) {
   ethtool_link_ksettings_add_link_mode(ks, supported,
            1000baseT_Full);
   if (hw_link_info->requested_speeds &
       I40E_LINK_SPEED_1GB)
    ethtool_link_ksettings_add_link_mode(
         ks, advertising, 1000baseT_Full);
  }
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            10000baseT_Full);
  break;
 case I40E_PHY_TYPE_10GBASE_T:
 case I40E_PHY_TYPE_5GBASE_T_LINK_STATUS:
 case I40E_PHY_TYPE_2_5GBASE_T_LINK_STATUS:
 case I40E_PHY_TYPE_1000BASE_T:
 case I40E_PHY_TYPE_100BASE_TX:
  ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg);
  ethtool_link_ksettings_add_link_mode(ks, supported,
           10000baseT_Full);
  ethtool_link_ksettings_add_link_mode(ks, supported,
           5000baseT_Full);
  ethtool_link_ksettings_add_link_mode(ks, supported,
           2500baseT_Full);
  ethtool_link_ksettings_add_link_mode(ks, supported,
           1000baseT_Full);
  ethtool_link_ksettings_add_link_mode(ks, supported,
           100baseT_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising, Autoneg);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            10000baseT_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_5GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            5000baseT_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_2_5GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            2500baseT_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            1000baseT_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_100MB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            100baseT_Full);
  break;
 case I40E_PHY_TYPE_1000BASE_T_OPTICAL:
  ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg);
  ethtool_link_ksettings_add_link_mode(ks, supported,
           1000baseT_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising, Autoneg);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           1000baseT_Full);
  break;
 case I40E_PHY_TYPE_10GBASE_CR1_CU:
 case I40E_PHY_TYPE_10GBASE_CR1:
  ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg);
  ethtool_link_ksettings_add_link_mode(ks, supported,
           10000baseT_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising, Autoneg);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           10000baseT_Full);
  break;
 case I40E_PHY_TYPE_XAUI:
 case I40E_PHY_TYPE_XFI:
 case I40E_PHY_TYPE_SFI:
 case I40E_PHY_TYPE_10GBASE_SFPP_CU:
 case I40E_PHY_TYPE_10GBASE_AOC:
  ethtool_link_ksettings_add_link_mode(ks, supported,
           10000baseT_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            10000baseT_Full);
  i40e_get_settings_link_up_fec(hw_link_info->req_fec_info, ks);
  break;
 case I40E_PHY_TYPE_SGMII:
  ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg);
  ethtool_link_ksettings_add_link_mode(ks, supported,
           1000baseT_Full);
  if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB)
   ethtool_link_ksettings_add_link_mode(ks, advertising,
            1000baseT_Full);
  if (test_bit(I40E_HW_CAP_100M_SGMII, pf->hw.caps)) {
   ethtool_link_ksettings_add_link_mode(ks, supported,
            100baseT_Full);
   if (hw_link_info->requested_speeds &
       I40E_LINK_SPEED_100MB)
    ethtool_link_ksettings_add_link_mode(
          ks, advertising, 100baseT_Full);
  }
  break;
 case I40E_PHY_TYPE_40GBASE_KR4:
 case I40E_PHY_TYPE_25GBASE_KR:
 case I40E_PHY_TYPE_20GBASE_KR2:
 case I40E_PHY_TYPE_10GBASE_KR:
 case I40E_PHY_TYPE_10GBASE_KX4:
 case I40E_PHY_TYPE_1000BASE_KX:
  ethtool_link_ksettings_add_link_mode(ks, supported,
           40000baseKR4_Full);
  ethtool_link_ksettings_add_link_mode(ks, supported,
           25000baseKR_Full);
  ethtool_link_ksettings_add_link_mode(ks, supported,
           20000baseKR2_Full);
  ethtool_link_ksettings_add_link_mode(ks, supported,
           10000baseKR_Full);
  ethtool_link_ksettings_add_link_mode(ks, supported,
           10000baseKX4_Full);
  ethtool_link_ksettings_add_link_mode(ks, supported,
           1000baseKX_Full);
  ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           40000baseKR4_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           25000baseKR_Full);
  i40e_get_settings_link_up_fec(hw_link_info->req_fec_info, ks);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           20000baseKR2_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           10000baseKR_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           10000baseKX4_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           1000baseKX_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising, Autoneg);
  break;
 case I40E_PHY_TYPE_25GBASE_CR:
  ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg);
  ethtool_link_ksettings_add_link_mode(ks, advertising, Autoneg);
  ethtool_link_ksettings_add_link_mode(ks, supported,
           25000baseCR_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           25000baseCR_Full);
  i40e_get_settings_link_up_fec(hw_link_info->req_fec_info, ks);

  break;
 case I40E_PHY_TYPE_25GBASE_AOC:
 case I40E_PHY_TYPE_25GBASE_ACC:
  ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg);
  ethtool_link_ksettings_add_link_mode(ks, advertising, Autoneg);
  ethtool_link_ksettings_add_link_mode(ks, supported,
           25000baseCR_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           25000baseCR_Full);
  i40e_get_settings_link_up_fec(hw_link_info->req_fec_info, ks);

  ethtool_link_ksettings_add_link_mode(ks, supported,
           10000baseCR_Full);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           10000baseCR_Full);
  break;
 default:
  /* if we got here and link is up something bad is afoot */
  netdev_info(netdev,
       "WARNING: Link is up but PHY type 0x%x is not recognized, or incorrect cable is in use\n",
       hw_link_info->phy_type);
 }

 /* Now that we've worked out everything that could be supported by the
 * current PHY type, get what is supported by the NVM and intersect
 * them to get what is truly supported
 */

 memset(&cap_ksettings, 0, sizeof(struct ethtool_link_ksettings));
 i40e_phy_type_to_ethtool(pf, &cap_ksettings);
 ethtool_intersect_link_masks(ks, &cap_ksettings);

 /* Set speed and duplex */
 switch (link_speed) {
 case I40E_LINK_SPEED_40GB:
  ks->base.speed = SPEED_40000;
  break;
 case I40E_LINK_SPEED_25GB:
  ks->base.speed = SPEED_25000;
  break;
 case I40E_LINK_SPEED_20GB:
  ks->base.speed = SPEED_20000;
  break;
 case I40E_LINK_SPEED_10GB:
  ks->base.speed = SPEED_10000;
  break;
 case I40E_LINK_SPEED_5GB:
  ks->base.speed = SPEED_5000;
  break;
 case I40E_LINK_SPEED_2_5GB:
  ks->base.speed = SPEED_2500;
  break;
 case I40E_LINK_SPEED_1GB:
  ks->base.speed = SPEED_1000;
  break;
 case I40E_LINK_SPEED_100MB:
  ks->base.speed = SPEED_100;
  break;
 default:
  ks->base.speed = SPEED_UNKNOWN;
  break;
 }
 ks->base.duplex = DUPLEX_FULL;
}

/**
 * i40e_get_settings_link_down - Get the Link settings for when link is down
 * @hw: hw structure
 * @ks: ethtool ksettings to fill in
 * @pf: pointer to physical function struct
 *
 * Reports link settings that can be determined when link is down
 **/

static void i40e_get_settings_link_down(struct i40e_hw *hw,
     struct ethtool_link_ksettings *ks,
     struct i40e_pf *pf)
{
 /* link is down and the driver needs to fall back on
 * supported phy types to figure out what info to display
 */

 i40e_phy_type_to_ethtool(pf, ks);

 /* With no link speed and duplex are unknown */
 ks->base.speed = SPEED_UNKNOWN;
 ks->base.duplex = DUPLEX_UNKNOWN;
}

/**
 * i40e_get_link_ksettings - Get Link Speed and Duplex settings
 * @netdev: network interface device structure
 * @ks: ethtool ksettings
 *
 * Reports speed/duplex settings based on media_type
 **/

static int i40e_get_link_ksettings(struct net_device *netdev,
       struct ethtool_link_ksettings *ks)
{
 struct i40e_netdev_priv *np = netdev_priv(netdev);
 struct i40e_pf *pf = np->vsi->back;
 struct i40e_hw *hw = &pf->hw;
 struct i40e_link_status *hw_link_info = &hw->phy.link_info;
 bool link_up = hw_link_info->link_info & I40E_AQ_LINK_UP;

 ethtool_link_ksettings_zero_link_mode(ks, supported);
 ethtool_link_ksettings_zero_link_mode(ks, advertising);

 if (link_up)
  i40e_get_settings_link_up(hw, ks, netdev, pf);
 else
  i40e_get_settings_link_down(hw, ks, pf);

 /* Now set the settings that don't rely on link being up/down */
 /* Set autoneg settings */
 ks->base.autoneg = ((hw_link_info->an_info & I40E_AQ_AN_COMPLETED) ?
       AUTONEG_ENABLE : AUTONEG_DISABLE);

 /* Set media type settings */
 switch (hw->phy.media_type) {
 case I40E_MEDIA_TYPE_BACKPLANE:
  ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg);
  ethtool_link_ksettings_add_link_mode(ks, supported, Backplane);
  ethtool_link_ksettings_add_link_mode(ks, advertising, Autoneg);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           Backplane);
  ks->base.port = PORT_NONE;
  break;
 case I40E_MEDIA_TYPE_BASET:
  ethtool_link_ksettings_add_link_mode(ks, supported, TP);
  ethtool_link_ksettings_add_link_mode(ks, advertising, TP);
  ks->base.port = PORT_TP;
  break;
 case I40E_MEDIA_TYPE_DA:
 case I40E_MEDIA_TYPE_CX4:
  ethtool_link_ksettings_add_link_mode(ks, supported, FIBRE);
  ethtool_link_ksettings_add_link_mode(ks, advertising, FIBRE);
  ks->base.port = PORT_DA;
  break;
 case I40E_MEDIA_TYPE_FIBER:
  ethtool_link_ksettings_add_link_mode(ks, supported, FIBRE);
  ethtool_link_ksettings_add_link_mode(ks, advertising, FIBRE);
  ks->base.port = PORT_FIBRE;
  break;
 case I40E_MEDIA_TYPE_UNKNOWN:
 default:
  ks->base.port = PORT_OTHER;
  break;
 }

 /* Set flow control settings */
 ethtool_link_ksettings_add_link_mode(ks, supported, Pause);
 ethtool_link_ksettings_add_link_mode(ks, supported, Asym_Pause);

 switch (hw->fc.requested_mode) {
 case I40E_FC_FULL:
  ethtool_link_ksettings_add_link_mode(ks, advertising, Pause);
  break;
 case I40E_FC_TX_PAUSE:
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           Asym_Pause);
  break;
 case I40E_FC_RX_PAUSE:
  ethtool_link_ksettings_add_link_mode(ks, advertising, Pause);
  ethtool_link_ksettings_add_link_mode(ks, advertising,
           Asym_Pause);
  break;
 default:
  ethtool_link_ksettings_del_link_mode(ks, advertising, Pause);
  ethtool_link_ksettings_del_link_mode(ks, advertising,
           Asym_Pause);
  break;
 }

 return 0;
}

#define I40E_LBIT_SIZE 8
/**
 * i40e_speed_to_link_speed - Translate decimal speed to i40e_aq_link_speed
 * @speed: speed in decimal
 * @ks: ethtool ksettings
 *
 * Return i40e_aq_link_speed based on speed
 **/

static enum i40e_aq_link_speed
i40e_speed_to_link_speed(__u32 speed, const struct ethtool_link_ksettings *ks)
{
 enum i40e_aq_link_speed link_speed = I40E_LINK_SPEED_UNKNOWN;
 bool speed_changed = false;
 int i, j;

 static const struct {
  __u32 speed;
  enum i40e_aq_link_speed link_speed;
  __u8 bit[I40E_LBIT_SIZE];
 } i40e_speed_lut[] = {
#define I40E_LBIT(mode) ETHTOOL_LINK_MODE_ ## mode ##_Full_BIT
  {SPEED_100, I40E_LINK_SPEED_100MB, {I40E_LBIT(100baseT)} },
  {SPEED_1000, I40E_LINK_SPEED_1GB,
   {I40E_LBIT(1000baseT), I40E_LBIT(1000baseX),
    I40E_LBIT(1000baseKX)} },
  {SPEED_10000, I40E_LINK_SPEED_10GB,
   {I40E_LBIT(10000baseT), I40E_LBIT(10000baseKR),
    I40E_LBIT(10000baseLR), I40E_LBIT(10000baseCR),
    I40E_LBIT(10000baseSR), I40E_LBIT(10000baseKX4)} },

  {SPEED_25000, I40E_LINK_SPEED_25GB,
   {I40E_LBIT(25000baseCR), I40E_LBIT(25000baseKR),
    I40E_LBIT(25000baseSR)} },
  {SPEED_40000, I40E_LINK_SPEED_40GB,
   {I40E_LBIT(40000baseKR4), I40E_LBIT(40000baseCR4),
    I40E_LBIT(40000baseSR4), I40E_LBIT(40000baseLR4)} },
  {SPEED_20000, I40E_LINK_SPEED_20GB,
   {I40E_LBIT(20000baseKR2)} },
  {SPEED_2500, I40E_LINK_SPEED_2_5GB, {I40E_LBIT(2500baseT)} },
  {SPEED_5000, I40E_LINK_SPEED_5GB, {I40E_LBIT(2500baseT)} }
#undef I40E_LBIT
};

 for (i = 0; i < ARRAY_SIZE(i40e_speed_lut); i++) {
  if (i40e_speed_lut[i].speed == speed) {
   for (j = 0; j < I40E_LBIT_SIZE; j++) {
    if (test_bit(i40e_speed_lut[i].bit[j],
          ks->link_modes.supported)) {
     speed_changed = true;
     break;
    }
    if (!i40e_speed_lut[i].bit[j])
     break;
   }
   if (speed_changed) {
    link_speed = i40e_speed_lut[i].link_speed;
    break;
   }
  }
 }
 return link_speed;
}

#undef I40E_LBIT_SIZE

/**
 * i40e_set_link_ksettings - Set Speed and Duplex
 * @netdev: network interface device structure
 * @ks: ethtool ksettings
 *
 * Set speed/duplex per media_types advertised/forced
 **/

static int i40e_set_link_ksettings(struct net_device *netdev,
       const struct ethtool_link_ksettings *ks)
{
 struct i40e_netdev_priv *np = netdev_priv(netdev);
 struct i40e_aq_get_phy_abilities_resp abilities;
 struct ethtool_link_ksettings safe_ks;
 struct ethtool_link_ksettings copy_ks;
 struct i40e_aq_set_phy_config config;
 struct i40e_pf *pf = np->vsi->back;
 enum i40e_aq_link_speed link_speed;
 struct i40e_vsi *vsi = np->vsi;
 struct i40e_hw *hw = &pf->hw;
 bool autoneg_changed = false;
 int timeout = 50;
 int status = 0;
 int err = 0;
 __u32 speed;
 u8 autoneg;

 /* Changing port settings is not supported if this isn't the
 * port's controlling PF
 */

 if (hw->partition_id != 1) {
  i40e_partition_setting_complaint(pf);
  return -EOPNOTSUPP;
 }
 if (vsi->type != I40E_VSI_MAIN)
  return -EOPNOTSUPP;
 if (hw->phy.media_type != I40E_MEDIA_TYPE_BASET &&
     hw->phy.media_type != I40E_MEDIA_TYPE_FIBER &&
     hw->phy.media_type != I40E_MEDIA_TYPE_BACKPLANE &&
     hw->phy.media_type != I40E_MEDIA_TYPE_DA &&
     hw->phy.link_info.link_info & I40E_AQ_LINK_UP)
  return -EOPNOTSUPP;
 if (hw->device_id == I40E_DEV_ID_KX_B ||
     hw->device_id == I40E_DEV_ID_KX_C ||
     hw->device_id == I40E_DEV_ID_20G_KR2 ||
     hw->device_id == I40E_DEV_ID_20G_KR2_A ||
     hw->device_id == I40E_DEV_ID_25G_B ||
     hw->device_id == I40E_DEV_ID_KX_X722) {
  netdev_info(netdev, "Changing settings is not supported on backplane.\n");
  return -EOPNOTSUPP;
 }

 /* copy the ksettings to copy_ks to avoid modifying the origin */
 memcpy(©_ks, ks, sizeof(struct ethtool_link_ksettings));

 /* save autoneg out of ksettings */
 autoneg = copy_ks.base.autoneg;
 speed = copy_ks.base.speed;

 /* get our own copy of the bits to check against */
 memset(&safe_ks, 0, sizeof(struct ethtool_link_ksettings));
 safe_ks.base.cmd = copy_ks.base.cmd;
 safe_ks.base.link_mode_masks_nwords =
  copy_ks.base.link_mode_masks_nwords;
 i40e_get_link_ksettings(netdev, &safe_ks);

 /* Get link modes supported by hardware and check against modes
 * requested by the user.  Return an error if unsupported mode was set.
 */

 if (!bitmap_subset(copy_ks.link_modes.advertising,
      safe_ks.link_modes.supported,
      __ETHTOOL_LINK_MODE_MASK_NBITS))
  return -EINVAL;

 /* set autoneg back to what it currently is */
 copy_ks.base.autoneg = safe_ks.base.autoneg;
 copy_ks.base.speed  = safe_ks.base.speed;

 /* If copy_ks.base and safe_ks.base are not the same now, then they are
 * trying to set something that we do not support.
 */

 if (memcmp(©_ks.base, &safe_ks.base,
     sizeof(struct ethtool_link_settings))) {
  netdev_err(netdev, "Only speed and autoneg are supported.\n");
  return -EOPNOTSUPP;
 }

 while (test_and_set_bit(__I40E_CONFIG_BUSY, pf->state)) {
  timeout--;
  if (!timeout)
   return -EBUSY;
  usleep_range(1000, 2000);
 }

 /* Get the current phy config */
 status = i40e_aq_get_phy_capabilities(hw, falsefalse, &abilities,
           NULL);
 if (status) {
  err = -EAGAIN;
  goto done;
 }

 /* Copy abilities to config in case autoneg is not
 * set below
 */

 memset(&config, 0, sizeof(struct i40e_aq_set_phy_config));
 config.abilities = abilities.abilities;

 /* Check autoneg */
 if (autoneg == AUTONEG_ENABLE) {
  /* If autoneg was not already enabled */
  if (!(hw->phy.link_info.an_info & I40E_AQ_AN_COMPLETED)) {
   /* If autoneg is not supported, return error */
   if (!ethtool_link_ksettings_test_link_mode(&safe_ks,
           supported,
           Autoneg)) {
    netdev_info(netdev, "Autoneg not supported on this phy\n");
    err = -EINVAL;
    goto done;
   }
   /* Autoneg is allowed to change */
   config.abilities = abilities.abilities |
        I40E_AQ_PHY_ENABLE_AN;
   autoneg_changed = true;
  }
 } else {
  /* If autoneg is currently enabled */
  if (hw->phy.link_info.an_info & I40E_AQ_AN_COMPLETED) {
   /* If autoneg is supported 10GBASE_T is the only PHY
 * that can disable it, so otherwise return error
 */

   if (ethtool_link_ksettings_test_link_mode(&safe_ks,
          supported,
          Autoneg) &&
       hw->phy.media_type != I40E_MEDIA_TYPE_BASET) {
    netdev_info(netdev, "Autoneg cannot be disabled on this phy\n");
    err = -EINVAL;
    goto done;
   }
   /* Autoneg is allowed to change */
   config.abilities = abilities.abilities &
        ~I40E_AQ_PHY_ENABLE_AN;
   autoneg_changed = true;
  }
 }

 if (ethtool_link_ksettings_test_link_mode(ks, advertising,
        100baseT_Full))
  config.link_speed |= I40E_LINK_SPEED_100MB;
 if (ethtool_link_ksettings_test_link_mode(ks, advertising,
        1000baseT_Full) ||
     ethtool_link_ksettings_test_link_mode(ks, advertising,
        1000baseX_Full) ||
     ethtool_link_ksettings_test_link_mode(ks, advertising,
        1000baseKX_Full))
  config.link_speed |= I40E_LINK_SPEED_1GB;
 if (ethtool_link_ksettings_test_link_mode(ks, advertising,
        10000baseT_Full) ||
     ethtool_link_ksettings_test_link_mode(ks, advertising,
        10000baseKX4_Full) ||
     ethtool_link_ksettings_test_link_mode(ks, advertising,
        10000baseKR_Full) ||
     ethtool_link_ksettings_test_link_mode(ks, advertising,
        10000baseCR_Full) ||
     ethtool_link_ksettings_test_link_mode(ks, advertising,
        10000baseSR_Full) ||
     ethtool_link_ksettings_test_link_mode(ks, advertising,
        10000baseLR_Full))
  config.link_speed |= I40E_LINK_SPEED_10GB;
 if (ethtool_link_ksettings_test_link_mode(ks, advertising,
        2500baseT_Full))
  config.link_speed |= I40E_LINK_SPEED_2_5GB;
 if (ethtool_link_ksettings_test_link_mode(ks, advertising,
        5000baseT_Full))
  config.link_speed |= I40E_LINK_SPEED_5GB;
 if (ethtool_link_ksettings_test_link_mode(ks, advertising,
        20000baseKR2_Full))
  config.link_speed |= I40E_LINK_SPEED_20GB;
 if (ethtool_link_ksettings_test_link_mode(ks, advertising,
        25000baseCR_Full) ||
     ethtool_link_ksettings_test_link_mode(ks, advertising,
        25000baseKR_Full) ||
     ethtool_link_ksettings_test_link_mode(ks, advertising,
        25000baseSR_Full))
  config.link_speed |= I40E_LINK_SPEED_25GB;
 if (ethtool_link_ksettings_test_link_mode(ks, advertising,
        40000baseKR4_Full) ||
     ethtool_link_ksettings_test_link_mode(ks, advertising,
        40000baseCR4_Full) ||
     ethtool_link_ksettings_test_link_mode(ks, advertising,
        40000baseSR4_Full) ||
     ethtool_link_ksettings_test_link_mode(ks, advertising,
        40000baseLR4_Full))
  config.link_speed |= I40E_LINK_SPEED_40GB;

 /* Autonegotiation must be disabled to change speed */
 if ((speed != SPEED_UNKNOWN && safe_ks.base.speed != speed) &&
     (autoneg == AUTONEG_DISABLE ||
     (safe_ks.base.autoneg == AUTONEG_DISABLE && !autoneg_changed))) {
  link_speed = i40e_speed_to_link_speed(speed, ks);
  if (link_speed == I40E_LINK_SPEED_UNKNOWN) {
   netdev_info(netdev, "Given speed is not supported\n");
   err = -EOPNOTSUPP;
   goto done;
  } else {
   config.link_speed = link_speed;
  }
 } else {
  if (safe_ks.base.speed != speed) {
   netdev_info(netdev,
        "Unable to set speed, disable autoneg\n");
   err = -EOPNOTSUPP;
   goto done;
  }
 }

 /* If speed didn't get set, set it to what it currently is.
 * This is needed because if advertise is 0 (as it is when autoneg
 * is disabled) then speed won't get set.
 */

 if (!config.link_speed)
  config.link_speed = abilities.link_speed;
 if (autoneg_changed || abilities.link_speed != config.link_speed) {
  /* copy over the rest of the abilities */
  config.phy_type = abilities.phy_type;
  config.phy_type_ext = abilities.phy_type_ext;
  config.eee_capability = abilities.eee_capability;
  config.eeer = abilities.eeer_val;
  config.low_power_ctrl = abilities.d3_lpan;
  config.fec_config = abilities.fec_cfg_curr_mod_ext_info &
        I40E_AQ_PHY_FEC_CONFIG_MASK;

  /* save the requested speeds */
  hw->phy.link_info.requested_speeds = config.link_speed;
  /* set link and auto negotiation so changes take effect */
  config.abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
  /* If link is up put link down */
  if (hw->phy.link_info.link_info & I40E_AQ_LINK_UP) {
   /* Tell the OS link is going down, the link will go
 * back up when fw says it is ready asynchronously
 */

   i40e_print_link_message(vsi, false);
   netif_carrier_off(netdev);
   netif_tx_stop_all_queues(netdev);
  }

  /* make the aq call */
  status = i40e_aq_set_phy_config(hw, &config, NULL);
  if (status) {
   netdev_info(netdev,
        "Set phy config failed, err %pe aq_err %s\n",
        ERR_PTR(status),
        libie_aq_str(hw->aq.asq_last_status));
   err = -EAGAIN;
   goto done;
  }

  status = i40e_update_link_info(hw);
  if (status)
   netdev_dbg(netdev,
       "Updating link info failed with err %pe aq_err %s\n",
       ERR_PTR(status),
       libie_aq_str(hw->aq.asq_last_status));

 } else {
  netdev_info(netdev, "Nothing changed, exiting without setting anything.\n");
 }

done:
 clear_bit(__I40E_CONFIG_BUSY, pf->state);

 return err;
}

static int i40e_set_fec_cfg(struct net_device *netdev, u8 fec_cfg)
{
 struct i40e_netdev_priv *np = netdev_priv(netdev);
 struct i40e_aq_get_phy_abilities_resp abilities;
 struct i40e_pf *pf = np->vsi->back;
 struct i40e_hw *hw = &pf->hw;
 int status = 0;
 int err = 0;

 /* Get the current phy config */
 memset(&abilities, 0, sizeof(abilities));
 status = i40e_aq_get_phy_capabilities(hw, falsefalse, &abilities,
           NULL);
 if (status) {
  err = -EAGAIN;
  goto done;
 }

 if (abilities.fec_cfg_curr_mod_ext_info != fec_cfg) {
  struct i40e_aq_set_phy_config config;

  memset(&config, 0, sizeof(config));
  config.phy_type = abilities.phy_type;
  config.abilities = abilities.abilities |
       I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
  config.phy_type_ext = abilities.phy_type_ext;
  config.link_speed = abilities.link_speed;
  config.eee_capability = abilities.eee_capability;
  config.eeer = abilities.eeer_val;
  config.low_power_ctrl = abilities.d3_lpan;
  config.fec_config = fec_cfg & I40E_AQ_PHY_FEC_CONFIG_MASK;
  status = i40e_aq_set_phy_config(hw, &config, NULL);
  if (status) {
   netdev_info(netdev,
        "Set phy config failed, err %pe aq_err %s\n",
        ERR_PTR(status),
        libie_aq_str(hw->aq.asq_last_status));
   err = -EAGAIN;
   goto done;
  }
  i40e_set_fec_in_flags(fec_cfg, pf->flags);
  status = i40e_update_link_info(hw);
  if (status)
   /* debug level message only due to relation to the link
 * itself rather than to the FEC settings
 * (e.g. no physical connection etc.)
 */

   netdev_dbg(netdev,
       "Updating link info failed with err %pe aq_err %s\n",
       ERR_PTR(status),
       libie_aq_str(hw->aq.asq_last_status));
 }

done:
 return err;
}

static int i40e_get_fec_param(struct net_device *netdev,
         struct ethtool_fecparam *fecparam)
{
 struct i40e_netdev_priv *np = netdev_priv(netdev);
 struct i40e_aq_get_phy_abilities_resp abilities;
 struct i40e_pf *pf = np->vsi->back;
 struct i40e_hw *hw = &pf->hw;
 int status = 0;
 int err = 0;
 u8 fec_cfg;

 /* Get the current phy config */
 memset(&abilities, 0, sizeof(abilities));
 status = i40e_aq_get_phy_capabilities(hw, falsefalse, &abilities,
           NULL);
 if (status) {
  err = -EAGAIN;
  goto done;
 }

 fecparam->fec = 0;
 fec_cfg = abilities.fec_cfg_curr_mod_ext_info;
 if (fec_cfg & I40E_AQ_SET_FEC_AUTO)
  fecparam->fec |= ETHTOOL_FEC_AUTO;
 else if (fec_cfg & (I40E_AQ_SET_FEC_REQUEST_RS |
   I40E_AQ_SET_FEC_ABILITY_RS))
  fecparam->fec |= ETHTOOL_FEC_RS;
 else if (fec_cfg & (I40E_AQ_SET_FEC_REQUEST_KR |
   I40E_AQ_SET_FEC_ABILITY_KR))
  fecparam->fec |= ETHTOOL_FEC_BASER;
 if (fec_cfg == 0)
  fecparam->fec | ETHTOOL_FEC_OFF;

 if (hw->phylink_info.fec_infoI40E_AQ_CONFIG_FEC_KR_ENA
include"i40e_txrx_common."
 else"
  fecparam->active_fec = ETHTOOL_FEC_RS;
 else
  fecparam->active_fec =  * @stat_offset: offsetof() the stat  * This structure defines a statistic to be added to the ethtool * It defines a statistic as offset from * be defined in constant arrays using the  * of the array using the same _type for calculating  * The @sizeof_stat is expected to * sizeof(u64). Other sizes  * the i40e_add_ethtool_stat() helper function.
done
 return err;
}

static  i40e_set_fec_param( net_device*etdev
          ethtool_fecparam *fecparam)
{
 struct i40e_netdev_priv *np  sizeof_stat = sizeof_field(_type stat,\
 struct i40e_pf *pf = np->vsi->back;
 structi40e_hw * = &pf->hw;
 u8 fec_cfg = 0;

 if(>device_id !  &&
     hw->device_id! I40E_DEV_ID_25G_B &java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
     hw->device_id != I40E_DEV_ID_KX_X722 * i40e_add_queue_stats. If the pointer is nulljava.lang.StringIndexOutOfBoundsException: Range [0, 1) out of bounds for length 0
  return-;

 if (hw->   * which don't have a valid pointer.
     !test_bit(I40E_HW_CAP_X722_FEC_REQUEST, hw->caps) 
  netdev_err(netdev, "Setting FEC encodingnot supported byfirmware. Please update the NVM image.\n")
  return EOPNOTSUPP;
 java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2

 switchfecparam-fec java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
 caseETHTOOL_FEC_AUTO:
   =I40E_AQ_SET_FEC_AUTO
  break
 case ETHTOOL_FEC_RS:
  fec_cfg = (I40E_AQ_SET_FEC_REQUEST_RS |
        I40E_AQ_SET_FEC_ABILITY_RS);
  break;
 case ETHTOOL_FEC_BASER:
 * Copy the stats defined by the stats array using the pointer as * the data buffer supplied by ethtool. Updates the data pointer to point to
        I40E_AQ_SET_FEC_ABILITY_KR);
  break;
 case ETHTOOL_FEC_OFF:
 case ETHTOOL_FEC_NONE:
  fec_cfg = 0;
  break;
 default:
  dev_warn(&pf->pdev->dev, "Unsupported FEC
     fecparam-fec);
  return -EINVAL;
 }

 return i40e_set_fec_cfg{
}

static int i40e_nway_reset(struct net_device i40e_add_one_ethtool_stat((*)++ , &[i)java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
{
 /* restart autonegotiation */
 java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
 struct i40e_pf *pf = np- * @data: ethtool  * @ring: the ring to copy *
 struct i40e_hw * u64_stats_fetch_begin, so we can't directly use i40e_add_ethtool_stats.
 bool link_up = hw->phy * pointer. Otherwise safely copy the stats  * buffer and update the data pointer *
 nt retret =0;

 ret=i40e_aq_set_link_restart_anhw, ijava.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16

  (, linkfailed%  s\n"
      (ret,
              &statsi])java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
  return -java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 }java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3

 return 0;
}

/**
 * i40e_get_pauseparam -  Get Flow Control status
 * @netdev: netdevice structure
 * @pause: buffer to return pause parameters
 *
 * Return tx/rx-pause status
 **/

static vsnprintf(,ETH_GSTRING_LEN, [i., args)java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
    struct ethtool_pauseparam * * @p: ethtool supplied  * @stats: stat *
{
 struct i40e_netdev_priv *np = netdev_priv(netdev * should be avoided. Additionally, stats must be an * ARRAY_SIZE can be called on  
 struct i40e_pf *pf = np->vsi->back;
 struct i40e_hw *hw = &pf->hw;
 struct i40e_link_status *hw_link_info
 struct i40e_dcbx_config *dcbx_cfg = &hw->local_dcbx_config;

 pause->autoneg =
  (hw_link_info-an_info &I40E_AQ_AN_COMPLETED)?
    AUTONEG_ENABLE : AUTONEG_DISABLE);

 /* PFC enabled so report LFC as off */
 if(pfc) {
  pause->rx_pause = 0;
  pause->tx_pause (name_) 
  return;
 }

 if ()
  pause->rx_pause = 1;
 } else if (hw->fc.current_mode == I40E_FC_TX_PAUSE) {
  pause->tx_pause(rx_dropped,
 >fccurrent_mode== ) {
  pause-rx_pause=1;
  pause-
}
}

/**
 * i40e_set_pauseparam - Set Flow Control parameter
 * @netdev: network interface device structure
 * @pause: return tx/rx flow control status
 **/

static int i40e_set_pauseparam(struct net_device *netdev,
          struct ethtool_pauseparam *pause)
{
 structi40e_netdev_priv* = (netdev
  =>vsi-;
 struct i40e_vsi *vsi = np->vsi("veb.,stats.tx_discards,
 struct* &>;
struct  hw_link_info =&w-phylink_info
 struct i40e_dcbx_config tc_rx_packets
 bool  = > &I40E_AQ_LINK_UP
 u8 aq_failures;
 int err = 0;
 int status;
 u32 is_an(vebtc_u_rx_bytes" tc_rx_bytes)java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53

 /* Changing the port's flow control is not supported if this isn't the
 * port's controlling PF
 */

 if (("" .)java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
  i40e_partition_setting_complainttx_stopped )
 4E_VSI_STAT"" rx_page_failed),
 }

 if (vsi-STAT(rx_cache_waive,r),
  return -EOPNOTSUPP;

 is_an = hw_link_info-> * but they are separate.  This device supports Virtualization * as such might have several netdevs supporting VMDq * through a single port.  The NETDEV_STATs are * seen at the top of the stack, and the  * function at the bottom of the stack *
  (>autoneg=is_an{
  netdev_info(netdev, "To change autoneg please use
 returnEOPNOTSUPP
 }

 /* If we have link and don't have autoneg */
  (test_bit__, >tate)& !) 
  * Send message that it might not necessarily work*/I40E_PF_STAT"porttx_errors,statsethtx_errors,
  (, Autonegdidsochanging ay otresultanactual\n)java.lang.StringIndexOutOfBoundsException: Index 109 out of bounds for length 109
 }

if(>pfcenable{
  netdev_infonetdev
  " flow enabled. set flow control.\";
  return -EOPNOTSUPP;
 }

 if (pause-> I40E_PF_STAT("port.", statslink_xon_tx)java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
  hw-fcrequested_mode=I40E_FC_FULL;
 else if (pause->rx_pause && !pause->tx_pause)
 (portrx_size_255, stats),
 else if I40E_PF_STAT".rx_size_1023,statsrx_size_1023)java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
  hw-.  I40E_FC_TX_PAUSE
  if (!>rx_pause& pause-)
  hw->(".java.lang.StringIndexOutOfBoundsException: Range [32, 31) out of bounds for length 53
 else
  return (.rx_oversize statsrx_oversize)java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53

 (port" )java.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
  *says it is ready asynchronously
  */
 i40e_print_link_message(vsi, false);
 netif_carrier_off(netdev);
 netif_tx_stop_all_queues(netdev);

 /* Set the fc mode and only restart an if link is up*/
 status =i40e_set_fchw &aq_failures, link_up;

 &) java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
 netdev_infonetdev "et fc failed on the get_phy_capabilities with err %peaq_err s\",
       ERR_PTR(status),
       libie_aq_str(I40E_PF_STAT(".tx_lpi_count, .tx_lpi_count),
  err =;
 }
if( & I40E_SET_FC_AQ_FAIL_SET){
  netdev_info(netdev, u64priority_xon_tx
       ERR_PTR(status,
       libie_aq_str(}
  err =-EAGAIN;
 }
 ifI40E_PFC_STAT"port.tx_priority_u_xoff_tx", priority_xoff_tx),
 I40E_PFC_STAT(".%u_xon_rx",priority_xon_rx)
       ERR_PTR(status),
       libie_aq_str(hw->aq};
  err = -EAGAINI40E_NETDEV_STATS_LEN ()
 }

 if (!test_bit(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 )
  msleep(75 (ARRAY_SIZE(i40e_gstrings_veb_tc_stats)* \
  if (!test_bit(__   I40E_MAX_TRAFFIC_CLASS
  returni40e_nway_reset(netdev)java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34


 return err;
}

java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
{
 structtest),
 struct i40e_pf *pf = np->vsi->back;
 u32 debug_mask = pf->hw.debug_mask;

 if (debug_mask)
  netdev_info(netdev, "i40e debug_mask: 0x%08X\n", debug_mask);

 return pf->msg_enablejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}

static i40e_set_msglevelstruct net_device *etdev,  data)
{
 struct i40e_netdev_priv = read_only \
 struct i40e_pf *pf = np->vsi->back;

 if ( &data)
  pf->hw.debug_mask cannotbe changedchanged/
 else
  pf->msg_enable = data;
}

static int i40e_get_regs_len(struct net_device *netdev)
{
 int reg_count = 0;
 int i;

 for (  0 i40e_reg_list[].offset != 00;i+)
  reg_count+ i40e_reg_list[i.;

 return reg_count * sizeof(u32);
}

static void i40e_get_regs(struct net_deviceI40E_PRIV_FLAG"", I40E_FLAG_HW_ATR_EVICT_ENA, 0),
   void *p)
{
 struct i40e_netdev_priv *np = netdev_priv(netdevI40E_PRIV_FLAG("legacy-rx, , 0)java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57
 struct i40e_pf*  np-vsi-back
 structi40e_hw *hw=pf-hw;
 u32 *I40E_PRIV_FLAGvf-vlan-pruning
 intj,;
 ;

 /* Tell ethtool which driver-version-specific regs output we have.
 *
 * At some point, if we have ethtool doing special formatting of
 * this data, it will rely on this version number to know how to
 * interpret things.  Hence, this needs to be updated if/when the
 * diags register table is changed.
 */

 regs->version = 1;

 /* loop through the diags reg table for what to print */
 ri 0;
 for (i = 0; i40e_reg_list
  for e* i40e_phy_type_to_ethtool - convert the phy_types to ethtool link modes
   reg = java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    + java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
   reg_buf[ri++ u64 phy_types = pf->hw.phy.phy_types;
  }
 }

}

static int i40e_get_eeprom(struct net_device *netdev,
      struct ethtool_eeprom *eeprom, u8 *bytes)
{
 structi4e_netdev_priv* =netdev_priv(netdev;
  &np-vsi-back->hw
  i40e_pf*pf ==np->vsi->back;
 java.lang.StringIndexOutOfBoundsException: Range [12, 4) out of bounds for length 30
 u8eeprom_buffjava.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
 u16
 boolifphy_types&I40E_CAP_PHY_TYPE_XAUI|java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
  java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11

#define I40E_NVM_SECTOR_SIZE  4        1000baseT_Full
 if (eeprom->len =(kssupported,
  return-;

 /* check for NVMUpdate access method */
 magic = hw->vendor_id | ethtool_link_ksettings_add_link_modeks supported
 if (eeprom->magic &e(ks,
  structi40e_nvm_access *md= structi40e_nvm_access)eeprom;
  int errno    50baseT_Full)java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
      00baseCR4_Full
  /* make sure it is the right magic for NVMUpdate */
  if (( if (hw_link_info-requested_speeds &I40E_LINK_SPEED_40GBjava.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
   errno = -EINVAL;
 else (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state ||
    test_bit(__I40E_RESET_INTR_RECEIVED, pf->state))
    ethtool_link_ksttings_add_link_mode(ks advertising,
  else
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=95 H=91 G=92

¤ Dauer der Verarbeitung: 0.20 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.