diff options
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_ethtool.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_ethtool.c | 140 |
1 files changed, 103 insertions, 37 deletions
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 856c18c207f3..06a9d18bbdbc 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -40,19 +40,27 @@ #define IXGBE_ALL_RAR_ENTRIES 16 +enum {NETDEV_STATS, IXGBE_STATS}; + struct ixgbe_stats { char stat_string[ETH_GSTRING_LEN]; + int type; int sizeof_stat; int stat_offset; }; -#define IXGBE_STAT(m) sizeof(((struct ixgbe_adapter *)0)->m), \ - offsetof(struct ixgbe_adapter, m) +#define IXGBE_STAT(m) IXGBE_STATS, \ + sizeof(((struct ixgbe_adapter *)0)->m), \ + offsetof(struct ixgbe_adapter, m) +#define IXGBE_NETDEV_STAT(m) NETDEV_STATS, \ + sizeof(((struct net_device *)0)->m), \ + offsetof(struct net_device, m) + static struct ixgbe_stats ixgbe_gstrings_stats[] = { - {"rx_packets", IXGBE_STAT(net_stats.rx_packets)}, - {"tx_packets", IXGBE_STAT(net_stats.tx_packets)}, - {"rx_bytes", IXGBE_STAT(net_stats.rx_bytes)}, - {"tx_bytes", IXGBE_STAT(net_stats.tx_bytes)}, + {"rx_packets", IXGBE_NETDEV_STAT(stats.rx_packets)}, + {"tx_packets", IXGBE_NETDEV_STAT(stats.tx_packets)}, + {"rx_bytes", IXGBE_NETDEV_STAT(stats.rx_bytes)}, + {"tx_bytes", IXGBE_NETDEV_STAT(stats.tx_bytes)}, {"rx_pkts_nic", IXGBE_STAT(stats.gprc)}, {"tx_pkts_nic", IXGBE_STAT(stats.gptc)}, {"rx_bytes_nic", IXGBE_STAT(stats.gorc)}, @@ -60,40 +68,36 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = { {"lsc_int", IXGBE_STAT(lsc_int)}, {"tx_busy", IXGBE_STAT(tx_busy)}, {"non_eop_descs", IXGBE_STAT(non_eop_descs)}, - {"rx_errors", IXGBE_STAT(net_stats.rx_errors)}, - {"tx_errors", IXGBE_STAT(net_stats.tx_errors)}, - {"rx_dropped", IXGBE_STAT(net_stats.rx_dropped)}, - {"tx_dropped", IXGBE_STAT(net_stats.tx_dropped)}, - {"multicast", IXGBE_STAT(net_stats.multicast)}, + {"rx_errors", IXGBE_NETDEV_STAT(stats.rx_errors)}, + {"tx_errors", IXGBE_NETDEV_STAT(stats.tx_errors)}, + {"rx_dropped", IXGBE_NETDEV_STAT(stats.rx_dropped)}, + {"tx_dropped", IXGBE_NETDEV_STAT(stats.tx_dropped)}, + {"multicast", IXGBE_NETDEV_STAT(stats.multicast)}, {"broadcast", IXGBE_STAT(stats.bprc)}, {"rx_no_buffer_count", IXGBE_STAT(stats.rnbc[0]) }, - {"collisions", IXGBE_STAT(net_stats.collisions)}, - {"rx_over_errors", IXGBE_STAT(net_stats.rx_over_errors)}, - {"rx_crc_errors", IXGBE_STAT(net_stats.rx_crc_errors)}, - {"rx_frame_errors", IXGBE_STAT(net_stats.rx_frame_errors)}, - {"hw_rsc_count", IXGBE_STAT(rsc_count)}, + {"collisions", IXGBE_NETDEV_STAT(stats.collisions)}, + {"rx_over_errors", IXGBE_NETDEV_STAT(stats.rx_over_errors)}, + {"rx_crc_errors", IXGBE_NETDEV_STAT(stats.rx_crc_errors)}, + {"rx_frame_errors", IXGBE_NETDEV_STAT(stats.rx_frame_errors)}, + {"hw_rsc_aggregated", IXGBE_STAT(rsc_total_count)}, + {"hw_rsc_flushed", IXGBE_STAT(rsc_total_flush)}, {"fdir_match", IXGBE_STAT(stats.fdirmatch)}, {"fdir_miss", IXGBE_STAT(stats.fdirmiss)}, - {"rx_fifo_errors", IXGBE_STAT(net_stats.rx_fifo_errors)}, - {"rx_missed_errors", IXGBE_STAT(net_stats.rx_missed_errors)}, - {"tx_aborted_errors", IXGBE_STAT(net_stats.tx_aborted_errors)}, - {"tx_carrier_errors", IXGBE_STAT(net_stats.tx_carrier_errors)}, - {"tx_fifo_errors", IXGBE_STAT(net_stats.tx_fifo_errors)}, - {"tx_heartbeat_errors", IXGBE_STAT(net_stats.tx_heartbeat_errors)}, + {"rx_fifo_errors", IXGBE_NETDEV_STAT(stats.rx_fifo_errors)}, + {"rx_missed_errors", IXGBE_NETDEV_STAT(stats.rx_missed_errors)}, + {"tx_aborted_errors", IXGBE_NETDEV_STAT(stats.tx_aborted_errors)}, + {"tx_carrier_errors", IXGBE_NETDEV_STAT(stats.tx_carrier_errors)}, + {"tx_fifo_errors", IXGBE_NETDEV_STAT(stats.tx_fifo_errors)}, + {"tx_heartbeat_errors", IXGBE_NETDEV_STAT(stats.tx_heartbeat_errors)}, {"tx_timeout_count", IXGBE_STAT(tx_timeout_count)}, {"tx_restart_queue", IXGBE_STAT(restart_queue)}, {"rx_long_length_errors", IXGBE_STAT(stats.roc)}, {"rx_short_length_errors", IXGBE_STAT(stats.ruc)}, - {"tx_tcp4_seg_ctxt", IXGBE_STAT(hw_tso_ctxt)}, - {"tx_tcp6_seg_ctxt", IXGBE_STAT(hw_tso6_ctxt)}, {"tx_flow_control_xon", IXGBE_STAT(stats.lxontxc)}, {"rx_flow_control_xon", IXGBE_STAT(stats.lxonrxc)}, {"tx_flow_control_xoff", IXGBE_STAT(stats.lxofftxc)}, {"rx_flow_control_xoff", IXGBE_STAT(stats.lxoffrxc)}, - {"rx_csum_offload_good", IXGBE_STAT(hw_csum_rx_good)}, {"rx_csum_offload_errors", IXGBE_STAT(hw_csum_rx_error)}, - {"tx_csum_offload_ctxt", IXGBE_STAT(hw_csum_tx_good)}, - {"rx_header_split", IXGBE_STAT(rx_hdr_split)}, {"alloc_rx_page_failed", IXGBE_STAT(alloc_rx_page_failed)}, {"alloc_rx_buff_failed", IXGBE_STAT(alloc_rx_buff_failed)}, {"rx_no_dma_resources", IXGBE_STAT(hw_rx_no_dma_resources)}, @@ -196,6 +200,56 @@ static int ixgbe_get_settings(struct net_device *netdev, ecmd->autoneg = AUTONEG_DISABLE; } + /* Get PHY type */ + switch (adapter->hw.phy.type) { + case ixgbe_phy_tn: + case ixgbe_phy_cu_unknown: + /* Copper 10G-BASET */ + ecmd->port = PORT_TP; + break; + case ixgbe_phy_qt: + ecmd->port = PORT_FIBRE; + break; + case ixgbe_phy_nl: + case ixgbe_phy_tw_tyco: + case ixgbe_phy_tw_unknown: + case ixgbe_phy_sfp_ftl: + case ixgbe_phy_sfp_avago: + case ixgbe_phy_sfp_intel: + case ixgbe_phy_sfp_unknown: + switch (adapter->hw.phy.sfp_type) { + /* SFP+ devices, further checking needed */ + case ixgbe_sfp_type_da_cu: + case ixgbe_sfp_type_da_cu_core0: + case ixgbe_sfp_type_da_cu_core1: + ecmd->port = PORT_DA; + break; + case ixgbe_sfp_type_sr: + case ixgbe_sfp_type_lr: + case ixgbe_sfp_type_srlr_core0: + case ixgbe_sfp_type_srlr_core1: + ecmd->port = PORT_FIBRE; + break; + case ixgbe_sfp_type_not_present: + ecmd->port = PORT_NONE; + break; + case ixgbe_sfp_type_unknown: + default: + ecmd->port = PORT_OTHER; + break; + } + break; + case ixgbe_phy_xaui: + ecmd->port = PORT_NONE; + break; + case ixgbe_phy_unknown: + case ixgbe_phy_generic: + case ixgbe_phy_sfp_unsupported: + default: + ecmd->port = PORT_OTHER; + break; + } + hw->mac.ops.check_link(hw, &link_speed, &link_up, false); if (link_up) { ecmd->speed = (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ? @@ -933,10 +987,21 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev, int stat_count = sizeof(struct ixgbe_queue_stats) / sizeof(u64); int j, k; int i; + char *p = NULL; ixgbe_update_stats(adapter); for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) { - char *p = (char *)adapter + ixgbe_gstrings_stats[i].stat_offset; + switch (ixgbe_gstrings_stats[i].type) { + case NETDEV_STATS: + p = (char *) netdev + + ixgbe_gstrings_stats[i].stat_offset; + break; + case IXGBE_STATS: + p = (char *) adapter + + ixgbe_gstrings_stats[i].stat_offset; + break; + } + data[i] = (ixgbe_gstrings_stats[i].sizeof_stat == sizeof(u64)) ? *(u64 *)p : *(u32 *)p; } @@ -1255,15 +1320,15 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data) return 0; } else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) { shared_int = false; - if (request_irq(irq, &ixgbe_test_intr, 0, netdev->name, + if (request_irq(irq, ixgbe_test_intr, 0, netdev->name, netdev)) { *data = 1; return -1; } - } else if (!request_irq(irq, &ixgbe_test_intr, IRQF_PROBE_SHARED, + } else if (!request_irq(irq, ixgbe_test_intr, IRQF_PROBE_SHARED, netdev->name, netdev)) { shared_int = false; - } else if (request_irq(irq, &ixgbe_test_intr, IRQF_SHARED, + } else if (request_irq(irq, ixgbe_test_intr, IRQF_SHARED, netdev->name, netdev)) { *data = 1; return -1; @@ -1952,6 +2017,10 @@ static int ixgbe_get_coalesce(struct net_device *netdev, break; } + /* if in mixed tx/rx queues per vector mode, report only rx settings */ + if (adapter->q_vector[0]->txr_count && adapter->q_vector[0]->rxr_count) + return 0; + /* only valid if in constant ITR mode */ switch (adapter->tx_itr_setting) { case 0: @@ -1977,12 +2046,9 @@ static int ixgbe_set_coalesce(struct net_device *netdev, struct ixgbe_q_vector *q_vector; int i; - /* - * don't accept tx specific changes if we've got mixed RxTx vectors - * test and jump out here if needed before changing the rx numbers - */ - if ((1000000/ec->tx_coalesce_usecs) != adapter->tx_eitr_param && - adapter->q_vector[0]->txr_count && adapter->q_vector[0]->rxr_count) + /* don't accept tx specific changes if we've got mixed RxTx vectors */ + if (adapter->q_vector[0]->txr_count && adapter->q_vector[0]->rxr_count + && ec->tx_coalesce_usecs) return -EINVAL; if (ec->tx_max_coalesced_frames_irq) |