diff options
Diffstat (limited to 'drivers/net/igb/igb_ethtool.c')
-rw-r--r-- | drivers/net/igb/igb_ethtool.c | 130 |
1 files changed, 86 insertions, 44 deletions
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index 26bf6a13d1c1..fdc895e5a3f8 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c | |||
@@ -86,12 +86,16 @@ static const struct igb_stats igb_gstrings_stats[] = { | |||
86 | IGB_STAT("tx_smbus", stats.mgptc), | 86 | IGB_STAT("tx_smbus", stats.mgptc), |
87 | IGB_STAT("rx_smbus", stats.mgprc), | 87 | IGB_STAT("rx_smbus", stats.mgprc), |
88 | IGB_STAT("dropped_smbus", stats.mgpdc), | 88 | IGB_STAT("dropped_smbus", stats.mgpdc), |
89 | IGB_STAT("os2bmc_rx_by_bmc", stats.o2bgptc), | ||
90 | IGB_STAT("os2bmc_tx_by_bmc", stats.b2ospc), | ||
91 | IGB_STAT("os2bmc_tx_by_host", stats.o2bspc), | ||
92 | IGB_STAT("os2bmc_rx_by_host", stats.b2ogprc), | ||
89 | }; | 93 | }; |
90 | 94 | ||
91 | #define IGB_NETDEV_STAT(_net_stat) { \ | 95 | #define IGB_NETDEV_STAT(_net_stat) { \ |
92 | .stat_string = __stringify(_net_stat), \ | 96 | .stat_string = __stringify(_net_stat), \ |
93 | .sizeof_stat = FIELD_SIZEOF(struct net_device_stats, _net_stat), \ | 97 | .sizeof_stat = FIELD_SIZEOF(struct rtnl_link_stats64, _net_stat), \ |
94 | .stat_offset = offsetof(struct net_device_stats, _net_stat) \ | 98 | .stat_offset = offsetof(struct rtnl_link_stats64, _net_stat) \ |
95 | } | 99 | } |
96 | static const struct igb_stats igb_gstrings_net_stats[] = { | 100 | static const struct igb_stats igb_gstrings_net_stats[] = { |
97 | IGB_NETDEV_STAT(rx_errors), | 101 | IGB_NETDEV_STAT(rx_errors), |
@@ -111,8 +115,9 @@ static const struct igb_stats igb_gstrings_net_stats[] = { | |||
111 | (sizeof(igb_gstrings_net_stats) / sizeof(struct igb_stats)) | 115 | (sizeof(igb_gstrings_net_stats) / sizeof(struct igb_stats)) |
112 | #define IGB_RX_QUEUE_STATS_LEN \ | 116 | #define IGB_RX_QUEUE_STATS_LEN \ |
113 | (sizeof(struct igb_rx_queue_stats) / sizeof(u64)) | 117 | (sizeof(struct igb_rx_queue_stats) / sizeof(u64)) |
114 | #define IGB_TX_QUEUE_STATS_LEN \ | 118 | |
115 | (sizeof(struct igb_tx_queue_stats) / sizeof(u64)) | 119 | #define IGB_TX_QUEUE_STATS_LEN 3 /* packets, bytes, restart_queue */ |
120 | |||
116 | #define IGB_QUEUE_STATS_LEN \ | 121 | #define IGB_QUEUE_STATS_LEN \ |
117 | ((((struct igb_adapter *)netdev_priv(netdev))->num_rx_queues * \ | 122 | ((((struct igb_adapter *)netdev_priv(netdev))->num_rx_queues * \ |
118 | IGB_RX_QUEUE_STATS_LEN) + \ | 123 | IGB_RX_QUEUE_STATS_LEN) + \ |
@@ -173,11 +178,11 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
173 | 178 | ||
174 | if ((status & E1000_STATUS_SPEED_1000) || | 179 | if ((status & E1000_STATUS_SPEED_1000) || |
175 | hw->phy.media_type != e1000_media_type_copper) | 180 | hw->phy.media_type != e1000_media_type_copper) |
176 | ecmd->speed = SPEED_1000; | 181 | ethtool_cmd_speed_set(ecmd, SPEED_1000); |
177 | else if (status & E1000_STATUS_SPEED_100) | 182 | else if (status & E1000_STATUS_SPEED_100) |
178 | ecmd->speed = SPEED_100; | 183 | ethtool_cmd_speed_set(ecmd, SPEED_100); |
179 | else | 184 | else |
180 | ecmd->speed = SPEED_10; | 185 | ethtool_cmd_speed_set(ecmd, SPEED_10); |
181 | 186 | ||
182 | if ((status & E1000_STATUS_FD) || | 187 | if ((status & E1000_STATUS_FD) || |
183 | hw->phy.media_type != e1000_media_type_copper) | 188 | hw->phy.media_type != e1000_media_type_copper) |
@@ -185,7 +190,7 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
185 | else | 190 | else |
186 | ecmd->duplex = DUPLEX_HALF; | 191 | ecmd->duplex = DUPLEX_HALF; |
187 | } else { | 192 | } else { |
188 | ecmd->speed = -1; | 193 | ethtool_cmd_speed_set(ecmd, -1); |
189 | ecmd->duplex = -1; | 194 | ecmd->duplex = -1; |
190 | } | 195 | } |
191 | 196 | ||
@@ -218,7 +223,8 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
218 | if (adapter->fc_autoneg) | 223 | if (adapter->fc_autoneg) |
219 | hw->fc.requested_mode = e1000_fc_default; | 224 | hw->fc.requested_mode = e1000_fc_default; |
220 | } else { | 225 | } else { |
221 | if (igb_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) { | 226 | u32 speed = ethtool_cmd_speed(ecmd); |
227 | if (igb_set_spd_dplx(adapter, speed, ecmd->duplex)) { | ||
222 | clear_bit(__IGB_RESETTING, &adapter->state); | 228 | clear_bit(__IGB_RESETTING, &adapter->state); |
223 | return -EINVAL; | 229 | return -EINVAL; |
224 | } | 230 | } |
@@ -602,7 +608,10 @@ static void igb_get_regs(struct net_device *netdev, | |||
602 | regs_buff[548] = rd32(E1000_TDFT); | 608 | regs_buff[548] = rd32(E1000_TDFT); |
603 | regs_buff[549] = rd32(E1000_TDFHS); | 609 | regs_buff[549] = rd32(E1000_TDFHS); |
604 | regs_buff[550] = rd32(E1000_TDFPC); | 610 | regs_buff[550] = rd32(E1000_TDFPC); |
605 | 611 | regs_buff[551] = adapter->stats.o2bgptc; | |
612 | regs_buff[552] = adapter->stats.b2ospc; | ||
613 | regs_buff[553] = adapter->stats.o2bspc; | ||
614 | regs_buff[554] = adapter->stats.b2ogprc; | ||
606 | } | 615 | } |
607 | 616 | ||
608 | static int igb_get_eeprom_len(struct net_device *netdev) | 617 | static int igb_get_eeprom_len(struct net_device *netdev) |
@@ -713,7 +722,7 @@ static int igb_set_eeprom(struct net_device *netdev, | |||
713 | /* Update the checksum over the first part of the EEPROM if needed | 722 | /* Update the checksum over the first part of the EEPROM if needed |
714 | * and flush shadow RAM for 82573 controllers */ | 723 | * and flush shadow RAM for 82573 controllers */ |
715 | if ((ret_val == 0) && ((first_word <= NVM_CHECKSUM_REG))) | 724 | if ((ret_val == 0) && ((first_word <= NVM_CHECKSUM_REG))) |
716 | igb_update_nvm_checksum(hw); | 725 | hw->nvm.ops.update(hw); |
717 | 726 | ||
718 | kfree(eeprom_buff); | 727 | kfree(eeprom_buff); |
719 | return ret_val; | 728 | return ret_val; |
@@ -726,8 +735,9 @@ static void igb_get_drvinfo(struct net_device *netdev, | |||
726 | char firmware_version[32]; | 735 | char firmware_version[32]; |
727 | u16 eeprom_data; | 736 | u16 eeprom_data; |
728 | 737 | ||
729 | strncpy(drvinfo->driver, igb_driver_name, 32); | 738 | strncpy(drvinfo->driver, igb_driver_name, sizeof(drvinfo->driver) - 1); |
730 | strncpy(drvinfo->version, igb_driver_version, 32); | 739 | strncpy(drvinfo->version, igb_driver_version, |
740 | sizeof(drvinfo->version) - 1); | ||
731 | 741 | ||
732 | /* EEPROM image version # is reported as firmware version # for | 742 | /* EEPROM image version # is reported as firmware version # for |
733 | * 82575 controllers */ | 743 | * 82575 controllers */ |
@@ -737,8 +747,10 @@ static void igb_get_drvinfo(struct net_device *netdev, | |||
737 | (eeprom_data & 0x0FF0) >> 4, | 747 | (eeprom_data & 0x0FF0) >> 4, |
738 | eeprom_data & 0x000F); | 748 | eeprom_data & 0x000F); |
739 | 749 | ||
740 | strncpy(drvinfo->fw_version, firmware_version, 32); | 750 | strncpy(drvinfo->fw_version, firmware_version, |
741 | strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); | 751 | sizeof(drvinfo->fw_version) - 1); |
752 | strncpy(drvinfo->bus_info, pci_name(adapter->pdev), | ||
753 | sizeof(drvinfo->bus_info) - 1); | ||
742 | drvinfo->n_stats = IGB_STATS_LEN; | 754 | drvinfo->n_stats = IGB_STATS_LEN; |
743 | drvinfo->testinfo_len = IGB_TEST_LEN; | 755 | drvinfo->testinfo_len = IGB_TEST_LEN; |
744 | drvinfo->regdump_len = igb_get_regs_len(netdev); | 756 | drvinfo->regdump_len = igb_get_regs_len(netdev); |
@@ -1069,7 +1081,7 @@ static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data, | |||
1069 | {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; | 1081 | {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; |
1070 | for (pat = 0; pat < ARRAY_SIZE(_test); pat++) { | 1082 | for (pat = 0; pat < ARRAY_SIZE(_test); pat++) { |
1071 | wr32(reg, (_test[pat] & write)); | 1083 | wr32(reg, (_test[pat] & write)); |
1072 | val = rd32(reg); | 1084 | val = rd32(reg) & mask; |
1073 | if (val != (_test[pat] & write & mask)) { | 1085 | if (val != (_test[pat] & write & mask)) { |
1074 | dev_err(&adapter->pdev->dev, "pattern test reg %04X " | 1086 | dev_err(&adapter->pdev->dev, "pattern test reg %04X " |
1075 | "failed: got 0x%08X expected 0x%08X\n", | 1087 | "failed: got 0x%08X expected 0x%08X\n", |
@@ -1952,27 +1964,28 @@ static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | |||
1952 | /* bit defines for adapter->led_status */ | 1964 | /* bit defines for adapter->led_status */ |
1953 | #define IGB_LED_ON 0 | 1965 | #define IGB_LED_ON 0 |
1954 | 1966 | ||
1955 | static int igb_phys_id(struct net_device *netdev, u32 data) | 1967 | static int igb_set_phys_id(struct net_device *netdev, |
1968 | enum ethtool_phys_id_state state) | ||
1956 | { | 1969 | { |
1957 | struct igb_adapter *adapter = netdev_priv(netdev); | 1970 | struct igb_adapter *adapter = netdev_priv(netdev); |
1958 | struct e1000_hw *hw = &adapter->hw; | 1971 | struct e1000_hw *hw = &adapter->hw; |
1959 | unsigned long timeout; | ||
1960 | |||
1961 | timeout = data * 1000; | ||
1962 | |||
1963 | /* | ||
1964 | * msleep_interruptable only accepts unsigned int so we are limited | ||
1965 | * in how long a duration we can wait | ||
1966 | */ | ||
1967 | if (!timeout || timeout > UINT_MAX) | ||
1968 | timeout = UINT_MAX; | ||
1969 | |||
1970 | igb_blink_led(hw); | ||
1971 | msleep_interruptible(timeout); | ||
1972 | 1972 | ||
1973 | igb_led_off(hw); | 1973 | switch (state) { |
1974 | clear_bit(IGB_LED_ON, &adapter->led_status); | 1974 | case ETHTOOL_ID_ACTIVE: |
1975 | igb_cleanup_led(hw); | 1975 | igb_blink_led(hw); |
1976 | return 2; | ||
1977 | case ETHTOOL_ID_ON: | ||
1978 | igb_blink_led(hw); | ||
1979 | break; | ||
1980 | case ETHTOOL_ID_OFF: | ||
1981 | igb_led_off(hw); | ||
1982 | break; | ||
1983 | case ETHTOOL_ID_INACTIVE: | ||
1984 | igb_led_off(hw); | ||
1985 | clear_bit(IGB_LED_ON, &adapter->led_status); | ||
1986 | igb_cleanup_led(hw); | ||
1987 | break; | ||
1988 | } | ||
1976 | 1989 | ||
1977 | return 0; | 1990 | return 0; |
1978 | } | 1991 | } |
@@ -1998,6 +2011,12 @@ static int igb_set_coalesce(struct net_device *netdev, | |||
1998 | if ((adapter->flags & IGB_FLAG_QUEUE_PAIRS) && ec->tx_coalesce_usecs) | 2011 | if ((adapter->flags & IGB_FLAG_QUEUE_PAIRS) && ec->tx_coalesce_usecs) |
1999 | return -EINVAL; | 2012 | return -EINVAL; |
2000 | 2013 | ||
2014 | /* If ITR is disabled, disable DMAC */ | ||
2015 | if (ec->rx_coalesce_usecs == 0) { | ||
2016 | if (adapter->flags & IGB_FLAG_DMAC) | ||
2017 | adapter->flags &= ~IGB_FLAG_DMAC; | ||
2018 | } | ||
2019 | |||
2001 | /* convert to rate of irq's per second */ | 2020 | /* convert to rate of irq's per second */ |
2002 | if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3) | 2021 | if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3) |
2003 | adapter->rx_itr_setting = ec->rx_coalesce_usecs; | 2022 | adapter->rx_itr_setting = ec->rx_coalesce_usecs; |
@@ -2070,12 +2089,14 @@ static void igb_get_ethtool_stats(struct net_device *netdev, | |||
2070 | struct ethtool_stats *stats, u64 *data) | 2089 | struct ethtool_stats *stats, u64 *data) |
2071 | { | 2090 | { |
2072 | struct igb_adapter *adapter = netdev_priv(netdev); | 2091 | struct igb_adapter *adapter = netdev_priv(netdev); |
2073 | struct net_device_stats *net_stats = &netdev->stats; | 2092 | struct rtnl_link_stats64 *net_stats = &adapter->stats64; |
2074 | u64 *queue_stat; | 2093 | unsigned int start; |
2075 | int i, j, k; | 2094 | struct igb_ring *ring; |
2095 | int i, j; | ||
2076 | char *p; | 2096 | char *p; |
2077 | 2097 | ||
2078 | igb_update_stats(adapter); | 2098 | spin_lock(&adapter->stats64_lock); |
2099 | igb_update_stats(adapter, net_stats); | ||
2079 | 2100 | ||
2080 | for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) { | 2101 | for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) { |
2081 | p = (char *)adapter + igb_gstrings_stats[i].stat_offset; | 2102 | p = (char *)adapter + igb_gstrings_stats[i].stat_offset; |
@@ -2088,15 +2109,36 @@ static void igb_get_ethtool_stats(struct net_device *netdev, | |||
2088 | sizeof(u64)) ? *(u64 *)p : *(u32 *)p; | 2109 | sizeof(u64)) ? *(u64 *)p : *(u32 *)p; |
2089 | } | 2110 | } |
2090 | for (j = 0; j < adapter->num_tx_queues; j++) { | 2111 | for (j = 0; j < adapter->num_tx_queues; j++) { |
2091 | queue_stat = (u64 *)&adapter->tx_ring[j]->tx_stats; | 2112 | u64 restart2; |
2092 | for (k = 0; k < IGB_TX_QUEUE_STATS_LEN; k++, i++) | 2113 | |
2093 | data[i] = queue_stat[k]; | 2114 | ring = adapter->tx_ring[j]; |
2115 | do { | ||
2116 | start = u64_stats_fetch_begin_bh(&ring->tx_syncp); | ||
2117 | data[i] = ring->tx_stats.packets; | ||
2118 | data[i+1] = ring->tx_stats.bytes; | ||
2119 | data[i+2] = ring->tx_stats.restart_queue; | ||
2120 | } while (u64_stats_fetch_retry_bh(&ring->tx_syncp, start)); | ||
2121 | do { | ||
2122 | start = u64_stats_fetch_begin_bh(&ring->tx_syncp2); | ||
2123 | restart2 = ring->tx_stats.restart_queue2; | ||
2124 | } while (u64_stats_fetch_retry_bh(&ring->tx_syncp2, start)); | ||
2125 | data[i+2] += restart2; | ||
2126 | |||
2127 | i += IGB_TX_QUEUE_STATS_LEN; | ||
2094 | } | 2128 | } |
2095 | for (j = 0; j < adapter->num_rx_queues; j++) { | 2129 | for (j = 0; j < adapter->num_rx_queues; j++) { |
2096 | queue_stat = (u64 *)&adapter->rx_ring[j]->rx_stats; | 2130 | ring = adapter->rx_ring[j]; |
2097 | for (k = 0; k < IGB_RX_QUEUE_STATS_LEN; k++, i++) | 2131 | do { |
2098 | data[i] = queue_stat[k]; | 2132 | start = u64_stats_fetch_begin_bh(&ring->rx_syncp); |
2133 | data[i] = ring->rx_stats.packets; | ||
2134 | data[i+1] = ring->rx_stats.bytes; | ||
2135 | data[i+2] = ring->rx_stats.drops; | ||
2136 | data[i+3] = ring->rx_stats.csum_err; | ||
2137 | data[i+4] = ring->rx_stats.alloc_failed; | ||
2138 | } while (u64_stats_fetch_retry_bh(&ring->rx_syncp, start)); | ||
2139 | i += IGB_RX_QUEUE_STATS_LEN; | ||
2099 | } | 2140 | } |
2141 | spin_unlock(&adapter->stats64_lock); | ||
2100 | } | 2142 | } |
2101 | 2143 | ||
2102 | static void igb_get_strings(struct net_device *netdev, u32 stringset, u8 *data) | 2144 | static void igb_get_strings(struct net_device *netdev, u32 stringset, u8 *data) |
@@ -2175,7 +2217,7 @@ static const struct ethtool_ops igb_ethtool_ops = { | |||
2175 | .set_tso = igb_set_tso, | 2217 | .set_tso = igb_set_tso, |
2176 | .self_test = igb_diag_test, | 2218 | .self_test = igb_diag_test, |
2177 | .get_strings = igb_get_strings, | 2219 | .get_strings = igb_get_strings, |
2178 | .phys_id = igb_phys_id, | 2220 | .set_phys_id = igb_set_phys_id, |
2179 | .get_sset_count = igb_get_sset_count, | 2221 | .get_sset_count = igb_get_sset_count, |
2180 | .get_ethtool_stats = igb_get_ethtool_stats, | 2222 | .get_ethtool_stats = igb_get_ethtool_stats, |
2181 | .get_coalesce = igb_get_coalesce, | 2223 | .get_coalesce = igb_get_coalesce, |