1dee1ad47SJeff Kirsher /******************************************************************************* 2dee1ad47SJeff Kirsher 3dee1ad47SJeff Kirsher Intel 82599 Virtual Function driver 4dec0d8e4SJeff Kirsher Copyright(c) 1999 - 2015 Intel Corporation. 5dee1ad47SJeff Kirsher 6dee1ad47SJeff Kirsher This program is free software; you can redistribute it and/or modify it 7dee1ad47SJeff Kirsher under the terms and conditions of the GNU General Public License, 8dee1ad47SJeff Kirsher version 2, as published by the Free Software Foundation. 9dee1ad47SJeff Kirsher 10dee1ad47SJeff Kirsher This program is distributed in the hope it will be useful, but WITHOUT 11dee1ad47SJeff Kirsher ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12dee1ad47SJeff Kirsher FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13dee1ad47SJeff Kirsher more details. 14dee1ad47SJeff Kirsher 15dee1ad47SJeff Kirsher You should have received a copy of the GNU General Public License along with 16dec0d8e4SJeff Kirsher this program; if not, see <http://www.gnu.org/licenses/>. 17dee1ad47SJeff Kirsher 18dee1ad47SJeff Kirsher The full GNU General Public License is included in this distribution in 19dee1ad47SJeff Kirsher the file called "COPYING". 20dee1ad47SJeff Kirsher 21dee1ad47SJeff Kirsher Contact Information: 22dee1ad47SJeff Kirsher e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> 23dee1ad47SJeff Kirsher Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 24dee1ad47SJeff Kirsher 25dee1ad47SJeff Kirsher *******************************************************************************/ 26dee1ad47SJeff Kirsher 27dee1ad47SJeff Kirsher /* ethtool support for ixgbevf */ 28dee1ad47SJeff Kirsher 29dbd9636eSJeff Kirsher #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 30dbd9636eSJeff Kirsher 31dee1ad47SJeff Kirsher #include <linux/types.h> 32dee1ad47SJeff Kirsher #include <linux/module.h> 33dee1ad47SJeff Kirsher #include <linux/slab.h> 34dee1ad47SJeff Kirsher #include <linux/pci.h> 35dee1ad47SJeff Kirsher #include <linux/netdevice.h> 36dee1ad47SJeff Kirsher #include <linux/ethtool.h> 37dee1ad47SJeff Kirsher #include <linux/vmalloc.h> 38dee1ad47SJeff Kirsher #include <linux/if_vlan.h> 39dee1ad47SJeff Kirsher #include <linux/uaccess.h> 40dee1ad47SJeff Kirsher 41dee1ad47SJeff Kirsher #include "ixgbevf.h" 42dee1ad47SJeff Kirsher 43dee1ad47SJeff Kirsher #define IXGBE_ALL_RAR_ENTRIES 16 44dee1ad47SJeff Kirsher 45d72d6c19SEmil Tantilov enum {NETDEV_STATS, IXGBEVF_STATS}; 46d72d6c19SEmil Tantilov 47dee1ad47SJeff Kirsher struct ixgbe_stats { 48dee1ad47SJeff Kirsher char stat_string[ETH_GSTRING_LEN]; 49d72d6c19SEmil Tantilov int type; 50dee1ad47SJeff Kirsher int sizeof_stat; 51dee1ad47SJeff Kirsher int stat_offset; 5244bd741eSDon Skidmore }; 53dee1ad47SJeff Kirsher 54d72d6c19SEmil Tantilov #define IXGBEVF_STAT(_name, _stat) { \ 55d72d6c19SEmil Tantilov .stat_string = _name, \ 56d72d6c19SEmil Tantilov .type = IXGBEVF_STATS, \ 57d72d6c19SEmil Tantilov .sizeof_stat = FIELD_SIZEOF(struct ixgbevf_adapter, _stat), \ 58d72d6c19SEmil Tantilov .stat_offset = offsetof(struct ixgbevf_adapter, _stat) \ 5944bd741eSDon Skidmore } 6044bd741eSDon Skidmore 61d72d6c19SEmil Tantilov #define IXGBEVF_NETDEV_STAT(_net_stat) { \ 62d72d6c19SEmil Tantilov .stat_string = #_net_stat, \ 63d72d6c19SEmil Tantilov .type = NETDEV_STATS, \ 64d72d6c19SEmil Tantilov .sizeof_stat = FIELD_SIZEOF(struct net_device_stats, _net_stat), \ 65d72d6c19SEmil Tantilov .stat_offset = offsetof(struct net_device_stats, _net_stat) \ 6644bd741eSDon Skidmore } 67b47aca13SStephen Hemminger 68d72d6c19SEmil Tantilov static struct ixgbe_stats ixgbevf_gstrings_stats[] = { 69d72d6c19SEmil Tantilov IXGBEVF_NETDEV_STAT(rx_packets), 70d72d6c19SEmil Tantilov IXGBEVF_NETDEV_STAT(tx_packets), 71d72d6c19SEmil Tantilov IXGBEVF_NETDEV_STAT(rx_bytes), 72d72d6c19SEmil Tantilov IXGBEVF_NETDEV_STAT(tx_bytes), 73d72d6c19SEmil Tantilov IXGBEVF_STAT("tx_busy", tx_busy), 74d72d6c19SEmil Tantilov IXGBEVF_STAT("tx_restart_queue", restart_queue), 75d72d6c19SEmil Tantilov IXGBEVF_STAT("tx_timeout_count", tx_timeout_count), 76d72d6c19SEmil Tantilov IXGBEVF_NETDEV_STAT(multicast), 77d72d6c19SEmil Tantilov IXGBEVF_STAT("rx_csum_offload_errors", hw_csum_rx_error), 78dee1ad47SJeff Kirsher }; 79dee1ad47SJeff Kirsher 80d72d6c19SEmil Tantilov #define IXGBEVF_QUEUE_STATS_LEN ( \ 81d72d6c19SEmil Tantilov (((struct ixgbevf_adapter *)netdev_priv(netdev))->num_tx_queues + \ 82d72d6c19SEmil Tantilov ((struct ixgbevf_adapter *)netdev_priv(netdev))->num_rx_queues) * \ 83d72d6c19SEmil Tantilov (sizeof(struct ixgbe_stats) / sizeof(u64))) 84d72d6c19SEmil Tantilov #define IXGBEVF_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbevf_gstrings_stats) 85dee1ad47SJeff Kirsher 86d72d6c19SEmil Tantilov #define IXGBEVF_STATS_LEN (IXGBEVF_GLOBAL_STATS_LEN + IXGBEVF_QUEUE_STATS_LEN) 87dee1ad47SJeff Kirsher static const char ixgbe_gstrings_test[][ETH_GSTRING_LEN] = { 88dee1ad47SJeff Kirsher "Register test (offline)", 89dee1ad47SJeff Kirsher "Link test (on/offline)" 90dee1ad47SJeff Kirsher }; 91dec0d8e4SJeff Kirsher 92d72d6c19SEmil Tantilov #define IXGBEVF_TEST_LEN (sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN) 93dee1ad47SJeff Kirsher 94dee1ad47SJeff Kirsher static int ixgbevf_get_settings(struct net_device *netdev, 95dee1ad47SJeff Kirsher struct ethtool_cmd *ecmd) 96dee1ad47SJeff Kirsher { 97dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 98dee1ad47SJeff Kirsher struct ixgbe_hw *hw = &adapter->hw; 99dee1ad47SJeff Kirsher u32 link_speed = 0; 100dee1ad47SJeff Kirsher bool link_up; 101dee1ad47SJeff Kirsher 102dee1ad47SJeff Kirsher ecmd->supported = SUPPORTED_10000baseT_Full; 103dee1ad47SJeff Kirsher ecmd->autoneg = AUTONEG_DISABLE; 104dee1ad47SJeff Kirsher ecmd->transceiver = XCVR_DUMMY1; 105dee1ad47SJeff Kirsher ecmd->port = -1; 106dee1ad47SJeff Kirsher 107aa19c295SGreg Rose hw->mac.get_link_status = 1; 108dee1ad47SJeff Kirsher hw->mac.ops.check_link(hw, &link_speed, &link_up, false); 109dee1ad47SJeff Kirsher 110dee1ad47SJeff Kirsher if (link_up) { 11131a1b375SGreg Rose __u32 speed = SPEED_10000; 112dec0d8e4SJeff Kirsher 11331a1b375SGreg Rose switch (link_speed) { 11431a1b375SGreg Rose case IXGBE_LINK_SPEED_10GB_FULL: 11531a1b375SGreg Rose speed = SPEED_10000; 11631a1b375SGreg Rose break; 11731a1b375SGreg Rose case IXGBE_LINK_SPEED_1GB_FULL: 11831a1b375SGreg Rose speed = SPEED_1000; 11931a1b375SGreg Rose break; 12031a1b375SGreg Rose case IXGBE_LINK_SPEED_100_FULL: 12131a1b375SGreg Rose speed = SPEED_100; 12231a1b375SGreg Rose break; 12331a1b375SGreg Rose } 12431a1b375SGreg Rose 12531a1b375SGreg Rose ethtool_cmd_speed_set(ecmd, speed); 126dee1ad47SJeff Kirsher ecmd->duplex = DUPLEX_FULL; 127dee1ad47SJeff Kirsher } else { 128537fae01SJiri Pirko ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN); 129537fae01SJiri Pirko ecmd->duplex = DUPLEX_UNKNOWN; 130dee1ad47SJeff Kirsher } 131dee1ad47SJeff Kirsher 132dee1ad47SJeff Kirsher return 0; 133dee1ad47SJeff Kirsher } 134dee1ad47SJeff Kirsher 135dee1ad47SJeff Kirsher static u32 ixgbevf_get_msglevel(struct net_device *netdev) 136dee1ad47SJeff Kirsher { 137dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 138dec0d8e4SJeff Kirsher 139dee1ad47SJeff Kirsher return adapter->msg_enable; 140dee1ad47SJeff Kirsher } 141dee1ad47SJeff Kirsher 142dee1ad47SJeff Kirsher static void ixgbevf_set_msglevel(struct net_device *netdev, u32 data) 143dee1ad47SJeff Kirsher { 144dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 145dec0d8e4SJeff Kirsher 146dee1ad47SJeff Kirsher adapter->msg_enable = data; 147dee1ad47SJeff Kirsher } 148dee1ad47SJeff Kirsher 149dee1ad47SJeff Kirsher #define IXGBE_GET_STAT(_A_, _R_) (_A_->stats._R_) 150dee1ad47SJeff Kirsher 151dee1ad47SJeff Kirsher static int ixgbevf_get_regs_len(struct net_device *netdev) 152dee1ad47SJeff Kirsher { 153fa07f10dSJacob Keller #define IXGBE_REGS_LEN 45 154fa07f10dSJacob Keller return IXGBE_REGS_LEN * sizeof(u32); 155dee1ad47SJeff Kirsher } 156dee1ad47SJeff Kirsher 157dee1ad47SJeff Kirsher static void ixgbevf_get_regs(struct net_device *netdev, 158dee1ad47SJeff Kirsher struct ethtool_regs *regs, 159dee1ad47SJeff Kirsher void *p) 160dee1ad47SJeff Kirsher { 161dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 162dee1ad47SJeff Kirsher struct ixgbe_hw *hw = &adapter->hw; 163dee1ad47SJeff Kirsher u32 *regs_buff = p; 164dee1ad47SJeff Kirsher u32 regs_len = ixgbevf_get_regs_len(netdev); 165dee1ad47SJeff Kirsher u8 i; 166dee1ad47SJeff Kirsher 167dee1ad47SJeff Kirsher memset(p, 0, regs_len); 168dee1ad47SJeff Kirsher 169dee1ad47SJeff Kirsher regs->version = (1 << 24) | hw->revision_id << 16 | hw->device_id; 170dee1ad47SJeff Kirsher 171dee1ad47SJeff Kirsher /* General Registers */ 172dee1ad47SJeff Kirsher regs_buff[0] = IXGBE_READ_REG(hw, IXGBE_VFCTRL); 173dee1ad47SJeff Kirsher regs_buff[1] = IXGBE_READ_REG(hw, IXGBE_VFSTATUS); 174dee1ad47SJeff Kirsher regs_buff[2] = IXGBE_READ_REG(hw, IXGBE_VFLINKS); 175dee1ad47SJeff Kirsher regs_buff[3] = IXGBE_READ_REG(hw, IXGBE_VFRXMEMWRAP); 176dee1ad47SJeff Kirsher regs_buff[4] = IXGBE_READ_REG(hw, IXGBE_VFFRTIMER); 177dee1ad47SJeff Kirsher 178dee1ad47SJeff Kirsher /* Interrupt */ 179dee1ad47SJeff Kirsher /* don't read EICR because it can clear interrupt causes, instead 180dec0d8e4SJeff Kirsher * read EICS which is a shadow but doesn't clear EICR 181dec0d8e4SJeff Kirsher */ 182dee1ad47SJeff Kirsher regs_buff[5] = IXGBE_READ_REG(hw, IXGBE_VTEICS); 183dee1ad47SJeff Kirsher regs_buff[6] = IXGBE_READ_REG(hw, IXGBE_VTEICS); 184dee1ad47SJeff Kirsher regs_buff[7] = IXGBE_READ_REG(hw, IXGBE_VTEIMS); 185dee1ad47SJeff Kirsher regs_buff[8] = IXGBE_READ_REG(hw, IXGBE_VTEIMC); 186dee1ad47SJeff Kirsher regs_buff[9] = IXGBE_READ_REG(hw, IXGBE_VTEIAC); 187dee1ad47SJeff Kirsher regs_buff[10] = IXGBE_READ_REG(hw, IXGBE_VTEIAM); 188dee1ad47SJeff Kirsher regs_buff[11] = IXGBE_READ_REG(hw, IXGBE_VTEITR(0)); 189dee1ad47SJeff Kirsher regs_buff[12] = IXGBE_READ_REG(hw, IXGBE_VTIVAR(0)); 190dee1ad47SJeff Kirsher regs_buff[13] = IXGBE_READ_REG(hw, IXGBE_VTIVAR_MISC); 191dee1ad47SJeff Kirsher 192dee1ad47SJeff Kirsher /* Receive DMA */ 193dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 194dee1ad47SJeff Kirsher regs_buff[14 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDBAL(i)); 195dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 196dee1ad47SJeff Kirsher regs_buff[16 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDBAH(i)); 197dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 198dee1ad47SJeff Kirsher regs_buff[18 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDLEN(i)); 199dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 200dee1ad47SJeff Kirsher regs_buff[20 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDH(i)); 201dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 202dee1ad47SJeff Kirsher regs_buff[22 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDT(i)); 203dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 204dee1ad47SJeff Kirsher regs_buff[24 + i] = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)); 205dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 206dee1ad47SJeff Kirsher regs_buff[26 + i] = IXGBE_READ_REG(hw, IXGBE_VFSRRCTL(i)); 207dee1ad47SJeff Kirsher 208dee1ad47SJeff Kirsher /* Receive */ 209dee1ad47SJeff Kirsher regs_buff[28] = IXGBE_READ_REG(hw, IXGBE_VFPSRTYPE); 210dee1ad47SJeff Kirsher 211dee1ad47SJeff Kirsher /* Transmit */ 212dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 213dee1ad47SJeff Kirsher regs_buff[29 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDBAL(i)); 214dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 215dee1ad47SJeff Kirsher regs_buff[31 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDBAH(i)); 216dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 217dee1ad47SJeff Kirsher regs_buff[33 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDLEN(i)); 218dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 219dee1ad47SJeff Kirsher regs_buff[35 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDH(i)); 220dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 221dee1ad47SJeff Kirsher regs_buff[37 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDT(i)); 222dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 223dee1ad47SJeff Kirsher regs_buff[39 + i] = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(i)); 224dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 225dee1ad47SJeff Kirsher regs_buff[41 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDWBAL(i)); 226dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 227dee1ad47SJeff Kirsher regs_buff[43 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDWBAH(i)); 228dee1ad47SJeff Kirsher } 229dee1ad47SJeff Kirsher 230dee1ad47SJeff Kirsher static void ixgbevf_get_drvinfo(struct net_device *netdev, 231dee1ad47SJeff Kirsher struct ethtool_drvinfo *drvinfo) 232dee1ad47SJeff Kirsher { 233dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 234dee1ad47SJeff Kirsher 23584b40501SRick Jones strlcpy(drvinfo->driver, ixgbevf_driver_name, sizeof(drvinfo->driver)); 23684b40501SRick Jones strlcpy(drvinfo->version, ixgbevf_driver_version, 23784b40501SRick Jones sizeof(drvinfo->version)); 23884b40501SRick Jones strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 23984b40501SRick Jones sizeof(drvinfo->bus_info)); 240dee1ad47SJeff Kirsher } 241dee1ad47SJeff Kirsher 242dee1ad47SJeff Kirsher static void ixgbevf_get_ringparam(struct net_device *netdev, 243dee1ad47SJeff Kirsher struct ethtool_ringparam *ring) 244dee1ad47SJeff Kirsher { 245dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 246dee1ad47SJeff Kirsher 247dee1ad47SJeff Kirsher ring->rx_max_pending = IXGBEVF_MAX_RXD; 248dee1ad47SJeff Kirsher ring->tx_max_pending = IXGBEVF_MAX_TXD; 249eb022d05SAlexander Duyck ring->rx_pending = adapter->rx_ring_count; 250eb022d05SAlexander Duyck ring->tx_pending = adapter->tx_ring_count; 251dee1ad47SJeff Kirsher } 252dee1ad47SJeff Kirsher 253dee1ad47SJeff Kirsher static int ixgbevf_set_ringparam(struct net_device *netdev, 254dee1ad47SJeff Kirsher struct ethtool_ringparam *ring) 255dee1ad47SJeff Kirsher { 256dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 257dee1ad47SJeff Kirsher struct ixgbevf_ring *tx_ring = NULL, *rx_ring = NULL; 258dee1ad47SJeff Kirsher u32 new_rx_count, new_tx_count; 259eb022d05SAlexander Duyck int i, err = 0; 260dee1ad47SJeff Kirsher 261dee1ad47SJeff Kirsher if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) 262dee1ad47SJeff Kirsher return -EINVAL; 263dee1ad47SJeff Kirsher 264eb022d05SAlexander Duyck new_tx_count = max_t(u32, ring->tx_pending, IXGBEVF_MIN_TXD); 265eb022d05SAlexander Duyck new_tx_count = min_t(u32, new_tx_count, IXGBEVF_MAX_TXD); 266dee1ad47SJeff Kirsher new_tx_count = ALIGN(new_tx_count, IXGBE_REQ_TX_DESCRIPTOR_MULTIPLE); 267dee1ad47SJeff Kirsher 268eb022d05SAlexander Duyck new_rx_count = max_t(u32, ring->rx_pending, IXGBEVF_MIN_RXD); 269eb022d05SAlexander Duyck new_rx_count = min_t(u32, new_rx_count, IXGBEVF_MAX_RXD); 270eb022d05SAlexander Duyck new_rx_count = ALIGN(new_rx_count, IXGBE_REQ_RX_DESCRIPTOR_MULTIPLE); 271eb022d05SAlexander Duyck 272eb022d05SAlexander Duyck /* if nothing to do return success */ 273eb022d05SAlexander Duyck if ((new_tx_count == adapter->tx_ring_count) && 274eb022d05SAlexander Duyck (new_rx_count == adapter->rx_ring_count)) 275dee1ad47SJeff Kirsher return 0; 276dee1ad47SJeff Kirsher 277dee1ad47SJeff Kirsher while (test_and_set_bit(__IXGBEVF_RESETTING, &adapter->state)) 278eb022d05SAlexander Duyck usleep_range(1000, 2000); 279dee1ad47SJeff Kirsher 280dee1ad47SJeff Kirsher if (!netif_running(adapter->netdev)) { 281dee1ad47SJeff Kirsher for (i = 0; i < adapter->num_tx_queues; i++) 28287e70ab9SDon Skidmore adapter->tx_ring[i]->count = new_tx_count; 283dee1ad47SJeff Kirsher for (i = 0; i < adapter->num_rx_queues; i++) 28487e70ab9SDon Skidmore adapter->rx_ring[i]->count = new_rx_count; 285dee1ad47SJeff Kirsher adapter->tx_ring_count = new_tx_count; 286dee1ad47SJeff Kirsher adapter->rx_ring_count = new_rx_count; 287dee1ad47SJeff Kirsher goto clear_reset; 288dee1ad47SJeff Kirsher } 289dee1ad47SJeff Kirsher 290eb022d05SAlexander Duyck if (new_tx_count != adapter->tx_ring_count) { 291eb022d05SAlexander Duyck tx_ring = vmalloc(adapter->num_tx_queues * sizeof(*tx_ring)); 292dee1ad47SJeff Kirsher if (!tx_ring) { 293dee1ad47SJeff Kirsher err = -ENOMEM; 294dee1ad47SJeff Kirsher goto clear_reset; 295dee1ad47SJeff Kirsher } 296dee1ad47SJeff Kirsher 297dee1ad47SJeff Kirsher for (i = 0; i < adapter->num_tx_queues; i++) { 298eb022d05SAlexander Duyck /* clone ring and setup updated count */ 29987e70ab9SDon Skidmore tx_ring[i] = *adapter->tx_ring[i]; 300dee1ad47SJeff Kirsher tx_ring[i].count = new_tx_count; 30105d063aaSEmil Tantilov err = ixgbevf_setup_tx_resources(&tx_ring[i]); 30205d063aaSEmil Tantilov if (err) { 303dee1ad47SJeff Kirsher while (i) { 304dee1ad47SJeff Kirsher i--; 30505d063aaSEmil Tantilov ixgbevf_free_tx_resources(&tx_ring[i]); 306dee1ad47SJeff Kirsher } 307eb022d05SAlexander Duyck 308eb022d05SAlexander Duyck vfree(tx_ring); 309eb022d05SAlexander Duyck tx_ring = NULL; 310eb022d05SAlexander Duyck 311eb022d05SAlexander Duyck goto clear_reset; 312dee1ad47SJeff Kirsher } 313dee1ad47SJeff Kirsher } 31405d063aaSEmil Tantilov } 315dee1ad47SJeff Kirsher 316eb022d05SAlexander Duyck if (new_rx_count != adapter->rx_ring_count) { 317eb022d05SAlexander Duyck rx_ring = vmalloc(adapter->num_rx_queues * sizeof(*rx_ring)); 318eb022d05SAlexander Duyck if (!rx_ring) { 319eb022d05SAlexander Duyck err = -ENOMEM; 320eb022d05SAlexander Duyck goto clear_reset; 321eb022d05SAlexander Duyck } 322eb022d05SAlexander Duyck 323dee1ad47SJeff Kirsher for (i = 0; i < adapter->num_rx_queues; i++) { 324eb022d05SAlexander Duyck /* clone ring and setup updated count */ 32587e70ab9SDon Skidmore rx_ring[i] = *adapter->rx_ring[i]; 326dee1ad47SJeff Kirsher rx_ring[i].count = new_rx_count; 32705d063aaSEmil Tantilov err = ixgbevf_setup_rx_resources(&rx_ring[i]); 32805d063aaSEmil Tantilov if (err) { 329dee1ad47SJeff Kirsher while (i) { 330dee1ad47SJeff Kirsher i--; 33105d063aaSEmil Tantilov ixgbevf_free_rx_resources(&rx_ring[i]); 332dee1ad47SJeff Kirsher } 333dee1ad47SJeff Kirsher 334eb022d05SAlexander Duyck vfree(rx_ring); 335eb022d05SAlexander Duyck rx_ring = NULL; 336dee1ad47SJeff Kirsher 337dee1ad47SJeff Kirsher goto clear_reset; 338eb022d05SAlexander Duyck } 339eb022d05SAlexander Duyck } 34005d063aaSEmil Tantilov } 341dee1ad47SJeff Kirsher 342eb022d05SAlexander Duyck /* bring interface down to prepare for update */ 343eb022d05SAlexander Duyck ixgbevf_down(adapter); 344dee1ad47SJeff Kirsher 345eb022d05SAlexander Duyck /* Tx */ 346eb022d05SAlexander Duyck if (tx_ring) { 347eb022d05SAlexander Duyck for (i = 0; i < adapter->num_tx_queues; i++) { 34805d063aaSEmil Tantilov ixgbevf_free_tx_resources(adapter->tx_ring[i]); 34987e70ab9SDon Skidmore *adapter->tx_ring[i] = tx_ring[i]; 350eb022d05SAlexander Duyck } 351eb022d05SAlexander Duyck adapter->tx_ring_count = new_tx_count; 352dee1ad47SJeff Kirsher 353eb022d05SAlexander Duyck vfree(tx_ring); 354eb022d05SAlexander Duyck tx_ring = NULL; 355eb022d05SAlexander Duyck } 356eb022d05SAlexander Duyck 357eb022d05SAlexander Duyck /* Rx */ 358eb022d05SAlexander Duyck if (rx_ring) { 359eb022d05SAlexander Duyck for (i = 0; i < adapter->num_rx_queues; i++) { 36005d063aaSEmil Tantilov ixgbevf_free_rx_resources(adapter->rx_ring[i]); 36187e70ab9SDon Skidmore *adapter->rx_ring[i] = rx_ring[i]; 362eb022d05SAlexander Duyck } 363eb022d05SAlexander Duyck adapter->rx_ring_count = new_rx_count; 364eb022d05SAlexander Duyck 365eb022d05SAlexander Duyck vfree(rx_ring); 366eb022d05SAlexander Duyck rx_ring = NULL; 367eb022d05SAlexander Duyck } 368eb022d05SAlexander Duyck 369eb022d05SAlexander Duyck /* restore interface using new values */ 370eb022d05SAlexander Duyck ixgbevf_up(adapter); 371dee1ad47SJeff Kirsher 372dee1ad47SJeff Kirsher clear_reset: 373eb022d05SAlexander Duyck /* free Tx resources if Rx error is encountered */ 374eb022d05SAlexander Duyck if (tx_ring) { 375eb022d05SAlexander Duyck for (i = 0; i < adapter->num_tx_queues; i++) 37605d063aaSEmil Tantilov ixgbevf_free_tx_resources(&tx_ring[i]); 377eb022d05SAlexander Duyck vfree(tx_ring); 378eb022d05SAlexander Duyck } 379eb022d05SAlexander Duyck 380dee1ad47SJeff Kirsher clear_bit(__IXGBEVF_RESETTING, &adapter->state); 381dee1ad47SJeff Kirsher return err; 382dee1ad47SJeff Kirsher } 383dee1ad47SJeff Kirsher 384a02a5a53SEmil Tantilov static int ixgbevf_get_sset_count(struct net_device *netdev, int stringset) 385dee1ad47SJeff Kirsher { 386dee1ad47SJeff Kirsher switch (stringset) { 387dee1ad47SJeff Kirsher case ETH_SS_TEST: 388d72d6c19SEmil Tantilov return IXGBEVF_TEST_LEN; 389dee1ad47SJeff Kirsher case ETH_SS_STATS: 390a02a5a53SEmil Tantilov return IXGBEVF_STATS_LEN; 391dee1ad47SJeff Kirsher default: 392dee1ad47SJeff Kirsher return -EINVAL; 393dee1ad47SJeff Kirsher } 394dee1ad47SJeff Kirsher } 395dee1ad47SJeff Kirsher 396dee1ad47SJeff Kirsher static void ixgbevf_get_ethtool_stats(struct net_device *netdev, 397dee1ad47SJeff Kirsher struct ethtool_stats *stats, u64 *data) 398dee1ad47SJeff Kirsher { 399dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 400d72d6c19SEmil Tantilov struct rtnl_link_stats64 temp; 401d72d6c19SEmil Tantilov const struct rtnl_link_stats64 *net_stats; 402a02a5a53SEmil Tantilov unsigned int start; 403a02a5a53SEmil Tantilov struct ixgbevf_ring *ring; 404a02a5a53SEmil Tantilov int i, j; 405d72d6c19SEmil Tantilov char *p; 406d72d6c19SEmil Tantilov 407dee1ad47SJeff Kirsher ixgbevf_update_stats(adapter); 408d72d6c19SEmil Tantilov net_stats = dev_get_stats(netdev, &temp); 409d72d6c19SEmil Tantilov for (i = 0; i < IXGBEVF_GLOBAL_STATS_LEN; i++) { 410d72d6c19SEmil Tantilov switch (ixgbevf_gstrings_stats[i].type) { 411d72d6c19SEmil Tantilov case NETDEV_STATS: 412d72d6c19SEmil Tantilov p = (char *)net_stats + 413d72d6c19SEmil Tantilov ixgbevf_gstrings_stats[i].stat_offset; 414d72d6c19SEmil Tantilov break; 415d72d6c19SEmil Tantilov case IXGBEVF_STATS: 416d72d6c19SEmil Tantilov p = (char *)adapter + 417d72d6c19SEmil Tantilov ixgbevf_gstrings_stats[i].stat_offset; 418d72d6c19SEmil Tantilov break; 419d72d6c19SEmil Tantilov default: 420d72d6c19SEmil Tantilov data[i] = 0; 421d72d6c19SEmil Tantilov continue; 42244bd741eSDon Skidmore } 423d72d6c19SEmil Tantilov 424d72d6c19SEmil Tantilov data[i] = (ixgbevf_gstrings_stats[i].sizeof_stat == 425d72d6c19SEmil Tantilov sizeof(u64)) ? *(u64 *)p : *(u32 *)p; 426dee1ad47SJeff Kirsher } 427a02a5a53SEmil Tantilov 428a02a5a53SEmil Tantilov /* populate Tx queue data */ 429a02a5a53SEmil Tantilov for (j = 0; j < adapter->num_tx_queues; j++) { 430a02a5a53SEmil Tantilov ring = adapter->tx_ring[j]; 431a02a5a53SEmil Tantilov if (!ring) { 432a02a5a53SEmil Tantilov data[i++] = 0; 433a02a5a53SEmil Tantilov data[i++] = 0; 434a02a5a53SEmil Tantilov #ifdef BP_EXTENDED_STATS 435a02a5a53SEmil Tantilov data[i++] = 0; 436a02a5a53SEmil Tantilov data[i++] = 0; 437a02a5a53SEmil Tantilov data[i++] = 0; 438a02a5a53SEmil Tantilov #endif 439a02a5a53SEmil Tantilov continue; 440a02a5a53SEmil Tantilov } 441a02a5a53SEmil Tantilov 442a02a5a53SEmil Tantilov do { 443a02a5a53SEmil Tantilov start = u64_stats_fetch_begin_irq(&ring->syncp); 444a02a5a53SEmil Tantilov data[i] = ring->stats.packets; 445a02a5a53SEmil Tantilov data[i + 1] = ring->stats.bytes; 446a02a5a53SEmil Tantilov } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); 447a02a5a53SEmil Tantilov i += 2; 448a02a5a53SEmil Tantilov #ifdef BP_EXTENDED_STATS 449a02a5a53SEmil Tantilov data[i] = ring->stats.yields; 450a02a5a53SEmil Tantilov data[i + 1] = ring->stats.misses; 451a02a5a53SEmil Tantilov data[i + 2] = ring->stats.cleaned; 452a02a5a53SEmil Tantilov i += 3; 453a02a5a53SEmil Tantilov #endif 454a02a5a53SEmil Tantilov } 455a02a5a53SEmil Tantilov 456a02a5a53SEmil Tantilov /* populate Rx queue data */ 457a02a5a53SEmil Tantilov for (j = 0; j < adapter->num_rx_queues; j++) { 458a02a5a53SEmil Tantilov ring = adapter->rx_ring[j]; 459a02a5a53SEmil Tantilov if (!ring) { 460a02a5a53SEmil Tantilov data[i++] = 0; 461a02a5a53SEmil Tantilov data[i++] = 0; 462a02a5a53SEmil Tantilov #ifdef BP_EXTENDED_STATS 463a02a5a53SEmil Tantilov data[i++] = 0; 464a02a5a53SEmil Tantilov data[i++] = 0; 465a02a5a53SEmil Tantilov data[i++] = 0; 466a02a5a53SEmil Tantilov #endif 467a02a5a53SEmil Tantilov continue; 468a02a5a53SEmil Tantilov } 469a02a5a53SEmil Tantilov 470a02a5a53SEmil Tantilov do { 471a02a5a53SEmil Tantilov start = u64_stats_fetch_begin_irq(&ring->syncp); 472a02a5a53SEmil Tantilov data[i] = ring->stats.packets; 473a02a5a53SEmil Tantilov data[i + 1] = ring->stats.bytes; 474a02a5a53SEmil Tantilov } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); 475a02a5a53SEmil Tantilov i += 2; 476a02a5a53SEmil Tantilov #ifdef BP_EXTENDED_STATS 477a02a5a53SEmil Tantilov data[i] = ring->stats.yields; 478a02a5a53SEmil Tantilov data[i + 1] = ring->stats.misses; 479a02a5a53SEmil Tantilov data[i + 2] = ring->stats.cleaned; 480a02a5a53SEmil Tantilov i += 3; 481a02a5a53SEmil Tantilov #endif 482a02a5a53SEmil Tantilov } 483dee1ad47SJeff Kirsher } 484dee1ad47SJeff Kirsher 485dee1ad47SJeff Kirsher static void ixgbevf_get_strings(struct net_device *netdev, u32 stringset, 486dee1ad47SJeff Kirsher u8 *data) 487dee1ad47SJeff Kirsher { 488a02a5a53SEmil Tantilov struct ixgbevf_adapter *adapter = netdev_priv(netdev); 489dee1ad47SJeff Kirsher char *p = (char *)data; 490dee1ad47SJeff Kirsher int i; 491dee1ad47SJeff Kirsher 492dee1ad47SJeff Kirsher switch (stringset) { 493dee1ad47SJeff Kirsher case ETH_SS_TEST: 494dee1ad47SJeff Kirsher memcpy(data, *ixgbe_gstrings_test, 495d72d6c19SEmil Tantilov IXGBEVF_TEST_LEN * ETH_GSTRING_LEN); 496dee1ad47SJeff Kirsher break; 497dee1ad47SJeff Kirsher case ETH_SS_STATS: 498d72d6c19SEmil Tantilov for (i = 0; i < IXGBEVF_GLOBAL_STATS_LEN; i++) { 499d72d6c19SEmil Tantilov memcpy(p, ixgbevf_gstrings_stats[i].stat_string, 500dee1ad47SJeff Kirsher ETH_GSTRING_LEN); 501dee1ad47SJeff Kirsher p += ETH_GSTRING_LEN; 502dee1ad47SJeff Kirsher } 503a02a5a53SEmil Tantilov 504a02a5a53SEmil Tantilov for (i = 0; i < adapter->num_tx_queues; i++) { 505a02a5a53SEmil Tantilov sprintf(p, "tx_queue_%u_packets", i); 506a02a5a53SEmil Tantilov p += ETH_GSTRING_LEN; 507a02a5a53SEmil Tantilov sprintf(p, "tx_queue_%u_bytes", i); 508a02a5a53SEmil Tantilov p += ETH_GSTRING_LEN; 509a02a5a53SEmil Tantilov #ifdef BP_EXTENDED_STATS 510a02a5a53SEmil Tantilov sprintf(p, "tx_queue_%u_bp_napi_yield", i); 511a02a5a53SEmil Tantilov p += ETH_GSTRING_LEN; 512a02a5a53SEmil Tantilov sprintf(p, "tx_queue_%u_bp_misses", i); 513a02a5a53SEmil Tantilov p += ETH_GSTRING_LEN; 514a02a5a53SEmil Tantilov sprintf(p, "tx_queue_%u_bp_cleaned", i); 515a02a5a53SEmil Tantilov p += ETH_GSTRING_LEN; 516a02a5a53SEmil Tantilov #endif /* BP_EXTENDED_STATS */ 517a02a5a53SEmil Tantilov } 518a02a5a53SEmil Tantilov for (i = 0; i < adapter->num_rx_queues; i++) { 519a02a5a53SEmil Tantilov sprintf(p, "rx_queue_%u_packets", i); 520a02a5a53SEmil Tantilov p += ETH_GSTRING_LEN; 521a02a5a53SEmil Tantilov sprintf(p, "rx_queue_%u_bytes", i); 522a02a5a53SEmil Tantilov p += ETH_GSTRING_LEN; 523a02a5a53SEmil Tantilov #ifdef BP_EXTENDED_STATS 524a02a5a53SEmil Tantilov sprintf(p, "rx_queue_%u_bp_poll_yield", i); 525a02a5a53SEmil Tantilov p += ETH_GSTRING_LEN; 526a02a5a53SEmil Tantilov sprintf(p, "rx_queue_%u_bp_misses", i); 527a02a5a53SEmil Tantilov p += ETH_GSTRING_LEN; 528a02a5a53SEmil Tantilov sprintf(p, "rx_queue_%u_bp_cleaned", i); 529a02a5a53SEmil Tantilov p += ETH_GSTRING_LEN; 530a02a5a53SEmil Tantilov #endif /* BP_EXTENDED_STATS */ 531a02a5a53SEmil Tantilov } 532dee1ad47SJeff Kirsher break; 533dee1ad47SJeff Kirsher } 534dee1ad47SJeff Kirsher } 535dee1ad47SJeff Kirsher 536dee1ad47SJeff Kirsher static int ixgbevf_link_test(struct ixgbevf_adapter *adapter, u64 *data) 537dee1ad47SJeff Kirsher { 538dee1ad47SJeff Kirsher struct ixgbe_hw *hw = &adapter->hw; 539dee1ad47SJeff Kirsher bool link_up; 540dee1ad47SJeff Kirsher u32 link_speed = 0; 541dee1ad47SJeff Kirsher *data = 0; 542dee1ad47SJeff Kirsher 543dee1ad47SJeff Kirsher hw->mac.ops.check_link(hw, &link_speed, &link_up, true); 544dee1ad47SJeff Kirsher if (!link_up) 545dee1ad47SJeff Kirsher *data = 1; 546dee1ad47SJeff Kirsher 547dee1ad47SJeff Kirsher return *data; 548dee1ad47SJeff Kirsher } 549dee1ad47SJeff Kirsher 550dee1ad47SJeff Kirsher /* ethtool register test data */ 551dee1ad47SJeff Kirsher struct ixgbevf_reg_test { 552dee1ad47SJeff Kirsher u16 reg; 553dee1ad47SJeff Kirsher u8 array_len; 554dee1ad47SJeff Kirsher u8 test_type; 555dee1ad47SJeff Kirsher u32 mask; 556dee1ad47SJeff Kirsher u32 write; 557dee1ad47SJeff Kirsher }; 558dee1ad47SJeff Kirsher 559dee1ad47SJeff Kirsher /* In the hardware, registers are laid out either singly, in arrays 560dee1ad47SJeff Kirsher * spaced 0x40 bytes apart, or in contiguous tables. We assume 561dee1ad47SJeff Kirsher * most tests take place on arrays or single registers (handled 562dee1ad47SJeff Kirsher * as a single-element array) and special-case the tables. 563dee1ad47SJeff Kirsher * Table tests are always pattern tests. 564dee1ad47SJeff Kirsher * 565dee1ad47SJeff Kirsher * We also make provision for some required setup steps by specifying 566dee1ad47SJeff Kirsher * registers to be written without any read-back testing. 567dee1ad47SJeff Kirsher */ 568dee1ad47SJeff Kirsher 569dee1ad47SJeff Kirsher #define PATTERN_TEST 1 570dee1ad47SJeff Kirsher #define SET_READ_TEST 2 571dee1ad47SJeff Kirsher #define WRITE_NO_TEST 3 572dee1ad47SJeff Kirsher #define TABLE32_TEST 4 573dee1ad47SJeff Kirsher #define TABLE64_TEST_LO 5 574dee1ad47SJeff Kirsher #define TABLE64_TEST_HI 6 575dee1ad47SJeff Kirsher 576dee1ad47SJeff Kirsher /* default VF register test */ 577dee1ad47SJeff Kirsher static const struct ixgbevf_reg_test reg_test_vf[] = { 578dee1ad47SJeff Kirsher { IXGBE_VFRDBAL(0), 2, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 }, 579dee1ad47SJeff Kirsher { IXGBE_VFRDBAH(0), 2, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, 580dee1ad47SJeff Kirsher { IXGBE_VFRDLEN(0), 2, PATTERN_TEST, 0x000FFF80, 0x000FFFFF }, 581dee1ad47SJeff Kirsher { IXGBE_VFRXDCTL(0), 2, WRITE_NO_TEST, 0, IXGBE_RXDCTL_ENABLE }, 582dee1ad47SJeff Kirsher { IXGBE_VFRDT(0), 2, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, 583dee1ad47SJeff Kirsher { IXGBE_VFRXDCTL(0), 2, WRITE_NO_TEST, 0, 0 }, 584dee1ad47SJeff Kirsher { IXGBE_VFTDBAL(0), 2, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, 585dee1ad47SJeff Kirsher { IXGBE_VFTDBAH(0), 2, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, 586dee1ad47SJeff Kirsher { IXGBE_VFTDLEN(0), 2, PATTERN_TEST, 0x000FFF80, 0x000FFF80 }, 587db99d95cSMark Rustad { .reg = 0 } 588dee1ad47SJeff Kirsher }; 589dee1ad47SJeff Kirsher 590dee1ad47SJeff Kirsher static const u32 register_test_patterns[] = { 591dee1ad47SJeff Kirsher 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF 592dee1ad47SJeff Kirsher }; 593dee1ad47SJeff Kirsher 594388b2e4cSMark Rustad static bool reg_pattern_test(struct ixgbevf_adapter *adapter, u64 *data, 595388b2e4cSMark Rustad int reg, u32 mask, u32 write) 596388b2e4cSMark Rustad { 597388b2e4cSMark Rustad u32 pat, val, before; 598388b2e4cSMark Rustad 59926597802SMark Rustad if (IXGBE_REMOVED(adapter->hw.hw_addr)) { 60026597802SMark Rustad *data = 1; 60126597802SMark Rustad return true; 60226597802SMark Rustad } 603388b2e4cSMark Rustad for (pat = 0; pat < ARRAY_SIZE(register_test_patterns); pat++) { 60432c74949SMark Rustad before = ixgbevf_read_reg(&adapter->hw, reg); 605388b2e4cSMark Rustad ixgbe_write_reg(&adapter->hw, reg, 606388b2e4cSMark Rustad register_test_patterns[pat] & write); 60732c74949SMark Rustad val = ixgbevf_read_reg(&adapter->hw, reg); 608388b2e4cSMark Rustad if (val != (register_test_patterns[pat] & write & mask)) { 609388b2e4cSMark Rustad hw_dbg(&adapter->hw, 610388b2e4cSMark Rustad "pattern test reg %04X failed: got 0x%08X expected 0x%08X\n", 611388b2e4cSMark Rustad reg, val, 612388b2e4cSMark Rustad register_test_patterns[pat] & write & mask); 613388b2e4cSMark Rustad *data = reg; 614388b2e4cSMark Rustad ixgbe_write_reg(&adapter->hw, reg, before); 615388b2e4cSMark Rustad return true; 616388b2e4cSMark Rustad } 617388b2e4cSMark Rustad ixgbe_write_reg(&adapter->hw, reg, before); 618388b2e4cSMark Rustad } 619388b2e4cSMark Rustad return false; 620dee1ad47SJeff Kirsher } 621dee1ad47SJeff Kirsher 622388b2e4cSMark Rustad static bool reg_set_and_check(struct ixgbevf_adapter *adapter, u64 *data, 623388b2e4cSMark Rustad int reg, u32 mask, u32 write) 624388b2e4cSMark Rustad { 625388b2e4cSMark Rustad u32 val, before; 626388b2e4cSMark Rustad 62726597802SMark Rustad if (IXGBE_REMOVED(adapter->hw.hw_addr)) { 62826597802SMark Rustad *data = 1; 62926597802SMark Rustad return true; 63026597802SMark Rustad } 63132c74949SMark Rustad before = ixgbevf_read_reg(&adapter->hw, reg); 632388b2e4cSMark Rustad ixgbe_write_reg(&adapter->hw, reg, write & mask); 63332c74949SMark Rustad val = ixgbevf_read_reg(&adapter->hw, reg); 634388b2e4cSMark Rustad if ((write & mask) != (val & mask)) { 635388b2e4cSMark Rustad pr_err("set/check reg %04X test failed: got 0x%08X expected 0x%08X\n", 636388b2e4cSMark Rustad reg, (val & mask), write & mask); 637388b2e4cSMark Rustad *data = reg; 638388b2e4cSMark Rustad ixgbe_write_reg(&adapter->hw, reg, before); 639388b2e4cSMark Rustad return true; 640388b2e4cSMark Rustad } 641388b2e4cSMark Rustad ixgbe_write_reg(&adapter->hw, reg, before); 642388b2e4cSMark Rustad return false; 643dee1ad47SJeff Kirsher } 644dee1ad47SJeff Kirsher 645dee1ad47SJeff Kirsher static int ixgbevf_reg_test(struct ixgbevf_adapter *adapter, u64 *data) 646dee1ad47SJeff Kirsher { 647dee1ad47SJeff Kirsher const struct ixgbevf_reg_test *test; 648dee1ad47SJeff Kirsher u32 i; 649dee1ad47SJeff Kirsher 65026597802SMark Rustad if (IXGBE_REMOVED(adapter->hw.hw_addr)) { 65126597802SMark Rustad dev_err(&adapter->pdev->dev, 65226597802SMark Rustad "Adapter removed - register test blocked\n"); 65326597802SMark Rustad *data = 1; 65426597802SMark Rustad return 1; 65526597802SMark Rustad } 656dee1ad47SJeff Kirsher test = reg_test_vf; 657dee1ad47SJeff Kirsher 658dec0d8e4SJeff Kirsher /* Perform the register test, looping through the test table 659dee1ad47SJeff Kirsher * until we either fail or reach the null entry. 660dee1ad47SJeff Kirsher */ 661dee1ad47SJeff Kirsher while (test->reg) { 662dee1ad47SJeff Kirsher for (i = 0; i < test->array_len; i++) { 663388b2e4cSMark Rustad bool b = false; 664388b2e4cSMark Rustad 665dee1ad47SJeff Kirsher switch (test->test_type) { 666dee1ad47SJeff Kirsher case PATTERN_TEST: 667388b2e4cSMark Rustad b = reg_pattern_test(adapter, data, 668388b2e4cSMark Rustad test->reg + (i * 0x40), 669dee1ad47SJeff Kirsher test->mask, 670dee1ad47SJeff Kirsher test->write); 671dee1ad47SJeff Kirsher break; 672dee1ad47SJeff Kirsher case SET_READ_TEST: 673388b2e4cSMark Rustad b = reg_set_and_check(adapter, data, 674388b2e4cSMark Rustad test->reg + (i * 0x40), 675dee1ad47SJeff Kirsher test->mask, 676dee1ad47SJeff Kirsher test->write); 677dee1ad47SJeff Kirsher break; 678dee1ad47SJeff Kirsher case WRITE_NO_TEST: 679388b2e4cSMark Rustad ixgbe_write_reg(&adapter->hw, 680388b2e4cSMark Rustad test->reg + (i * 0x40), 681388b2e4cSMark Rustad test->write); 682dee1ad47SJeff Kirsher break; 683dee1ad47SJeff Kirsher case TABLE32_TEST: 684388b2e4cSMark Rustad b = reg_pattern_test(adapter, data, 685388b2e4cSMark Rustad test->reg + (i * 4), 686dee1ad47SJeff Kirsher test->mask, 687dee1ad47SJeff Kirsher test->write); 688dee1ad47SJeff Kirsher break; 689dee1ad47SJeff Kirsher case TABLE64_TEST_LO: 690388b2e4cSMark Rustad b = reg_pattern_test(adapter, data, 691388b2e4cSMark Rustad test->reg + (i * 8), 692dee1ad47SJeff Kirsher test->mask, 693dee1ad47SJeff Kirsher test->write); 694dee1ad47SJeff Kirsher break; 695dee1ad47SJeff Kirsher case TABLE64_TEST_HI: 696388b2e4cSMark Rustad b = reg_pattern_test(adapter, data, 697388b2e4cSMark Rustad test->reg + 4 + (i * 8), 698dee1ad47SJeff Kirsher test->mask, 699dee1ad47SJeff Kirsher test->write); 700dee1ad47SJeff Kirsher break; 701dee1ad47SJeff Kirsher } 702388b2e4cSMark Rustad if (b) 703388b2e4cSMark Rustad return 1; 704dee1ad47SJeff Kirsher } 705dee1ad47SJeff Kirsher test++; 706dee1ad47SJeff Kirsher } 707dee1ad47SJeff Kirsher 708dee1ad47SJeff Kirsher *data = 0; 709dee1ad47SJeff Kirsher return *data; 710dee1ad47SJeff Kirsher } 711dee1ad47SJeff Kirsher 712dee1ad47SJeff Kirsher static void ixgbevf_diag_test(struct net_device *netdev, 713dee1ad47SJeff Kirsher struct ethtool_test *eth_test, u64 *data) 714dee1ad47SJeff Kirsher { 715dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 716dee1ad47SJeff Kirsher bool if_running = netif_running(netdev); 717dee1ad47SJeff Kirsher 71826597802SMark Rustad if (IXGBE_REMOVED(adapter->hw.hw_addr)) { 71926597802SMark Rustad dev_err(&adapter->pdev->dev, 72026597802SMark Rustad "Adapter removed - test blocked\n"); 72126597802SMark Rustad data[0] = 1; 72226597802SMark Rustad data[1] = 1; 72326597802SMark Rustad eth_test->flags |= ETH_TEST_FL_FAILED; 72426597802SMark Rustad return; 72526597802SMark Rustad } 726dee1ad47SJeff Kirsher set_bit(__IXGBEVF_TESTING, &adapter->state); 727dee1ad47SJeff Kirsher if (eth_test->flags == ETH_TEST_FL_OFFLINE) { 728dee1ad47SJeff Kirsher /* Offline tests */ 729dee1ad47SJeff Kirsher 730dee1ad47SJeff Kirsher hw_dbg(&adapter->hw, "offline testing starting\n"); 731dee1ad47SJeff Kirsher 732dee1ad47SJeff Kirsher /* Link test performed before hardware reset so autoneg doesn't 733dec0d8e4SJeff Kirsher * interfere with test result 734dec0d8e4SJeff Kirsher */ 735dee1ad47SJeff Kirsher if (ixgbevf_link_test(adapter, &data[1])) 736dee1ad47SJeff Kirsher eth_test->flags |= ETH_TEST_FL_FAILED; 737dee1ad47SJeff Kirsher 738dee1ad47SJeff Kirsher if (if_running) 739dee1ad47SJeff Kirsher /* indicate we're in test mode */ 740324d0867SStefan Assmann ixgbevf_close(netdev); 741dee1ad47SJeff Kirsher else 742dee1ad47SJeff Kirsher ixgbevf_reset(adapter); 743dee1ad47SJeff Kirsher 744dee1ad47SJeff Kirsher hw_dbg(&adapter->hw, "register testing starting\n"); 745dee1ad47SJeff Kirsher if (ixgbevf_reg_test(adapter, &data[0])) 746dee1ad47SJeff Kirsher eth_test->flags |= ETH_TEST_FL_FAILED; 747dee1ad47SJeff Kirsher 748dee1ad47SJeff Kirsher ixgbevf_reset(adapter); 749dee1ad47SJeff Kirsher 750dee1ad47SJeff Kirsher clear_bit(__IXGBEVF_TESTING, &adapter->state); 751dee1ad47SJeff Kirsher if (if_running) 752324d0867SStefan Assmann ixgbevf_open(netdev); 753dee1ad47SJeff Kirsher } else { 754dee1ad47SJeff Kirsher hw_dbg(&adapter->hw, "online testing starting\n"); 755dee1ad47SJeff Kirsher /* Online tests */ 756dee1ad47SJeff Kirsher if (ixgbevf_link_test(adapter, &data[1])) 757dee1ad47SJeff Kirsher eth_test->flags |= ETH_TEST_FL_FAILED; 758dee1ad47SJeff Kirsher 759dee1ad47SJeff Kirsher /* Online tests aren't run; pass by default */ 760dee1ad47SJeff Kirsher data[0] = 0; 761dee1ad47SJeff Kirsher 762dee1ad47SJeff Kirsher clear_bit(__IXGBEVF_TESTING, &adapter->state); 763dee1ad47SJeff Kirsher } 764dee1ad47SJeff Kirsher msleep_interruptible(4 * 1000); 765dee1ad47SJeff Kirsher } 766dee1ad47SJeff Kirsher 767dee1ad47SJeff Kirsher static int ixgbevf_nway_reset(struct net_device *netdev) 768dee1ad47SJeff Kirsher { 769dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 770dee1ad47SJeff Kirsher 77177d5dfcaSAlexander Duyck if (netif_running(netdev)) 772dee1ad47SJeff Kirsher ixgbevf_reinit_locked(adapter); 773dee1ad47SJeff Kirsher 774dee1ad47SJeff Kirsher return 0; 775dee1ad47SJeff Kirsher } 776dee1ad47SJeff Kirsher 7773849623eSJacob Keller static int ixgbevf_get_coalesce(struct net_device *netdev, 7783849623eSJacob Keller struct ethtool_coalesce *ec) 7793849623eSJacob Keller { 7803849623eSJacob Keller struct ixgbevf_adapter *adapter = netdev_priv(netdev); 7813849623eSJacob Keller 7823849623eSJacob Keller /* only valid if in constant ITR mode */ 7833849623eSJacob Keller if (adapter->rx_itr_setting <= 1) 7843849623eSJacob Keller ec->rx_coalesce_usecs = adapter->rx_itr_setting; 7853849623eSJacob Keller else 7863849623eSJacob Keller ec->rx_coalesce_usecs = adapter->rx_itr_setting >> 2; 7873849623eSJacob Keller 788dec0d8e4SJeff Kirsher /* if in mixed Tx/Rx queues per vector mode, report only Rx settings */ 7893849623eSJacob Keller if (adapter->q_vector[0]->tx.count && adapter->q_vector[0]->rx.count) 7903849623eSJacob Keller return 0; 7913849623eSJacob Keller 7923849623eSJacob Keller /* only valid if in constant ITR mode */ 7933849623eSJacob Keller if (adapter->tx_itr_setting <= 1) 7943849623eSJacob Keller ec->tx_coalesce_usecs = adapter->tx_itr_setting; 7953849623eSJacob Keller else 7963849623eSJacob Keller ec->tx_coalesce_usecs = adapter->tx_itr_setting >> 2; 7973849623eSJacob Keller 7983849623eSJacob Keller return 0; 7993849623eSJacob Keller } 8003849623eSJacob Keller 8013849623eSJacob Keller static int ixgbevf_set_coalesce(struct net_device *netdev, 8023849623eSJacob Keller struct ethtool_coalesce *ec) 8033849623eSJacob Keller { 8043849623eSJacob Keller struct ixgbevf_adapter *adapter = netdev_priv(netdev); 8053849623eSJacob Keller struct ixgbevf_q_vector *q_vector; 8063849623eSJacob Keller int num_vectors, i; 8073849623eSJacob Keller u16 tx_itr_param, rx_itr_param; 8083849623eSJacob Keller 809dec0d8e4SJeff Kirsher /* don't accept Tx specific changes if we've got mixed RxTx vectors */ 810dec0d8e4SJeff Kirsher if (adapter->q_vector[0]->tx.count && 811dec0d8e4SJeff Kirsher adapter->q_vector[0]->rx.count && ec->tx_coalesce_usecs) 8123849623eSJacob Keller return -EINVAL; 8133849623eSJacob Keller 8143849623eSJacob Keller if ((ec->rx_coalesce_usecs > (IXGBE_MAX_EITR >> 2)) || 8153849623eSJacob Keller (ec->tx_coalesce_usecs > (IXGBE_MAX_EITR >> 2))) 8163849623eSJacob Keller return -EINVAL; 8173849623eSJacob Keller 8183849623eSJacob Keller if (ec->rx_coalesce_usecs > 1) 8193849623eSJacob Keller adapter->rx_itr_setting = ec->rx_coalesce_usecs << 2; 8203849623eSJacob Keller else 8213849623eSJacob Keller adapter->rx_itr_setting = ec->rx_coalesce_usecs; 8223849623eSJacob Keller 8233849623eSJacob Keller if (adapter->rx_itr_setting == 1) 8243849623eSJacob Keller rx_itr_param = IXGBE_20K_ITR; 8253849623eSJacob Keller else 8263849623eSJacob Keller rx_itr_param = adapter->rx_itr_setting; 8273849623eSJacob Keller 8283849623eSJacob Keller if (ec->tx_coalesce_usecs > 1) 8293849623eSJacob Keller adapter->tx_itr_setting = ec->tx_coalesce_usecs << 2; 8303849623eSJacob Keller else 8313849623eSJacob Keller adapter->tx_itr_setting = ec->tx_coalesce_usecs; 8323849623eSJacob Keller 8333849623eSJacob Keller if (adapter->tx_itr_setting == 1) 8348a9ca110SAlexander Duyck tx_itr_param = IXGBE_12K_ITR; 8353849623eSJacob Keller else 8363849623eSJacob Keller tx_itr_param = adapter->tx_itr_setting; 8373849623eSJacob Keller 8383849623eSJacob Keller num_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; 8393849623eSJacob Keller 8403849623eSJacob Keller for (i = 0; i < num_vectors; i++) { 8413849623eSJacob Keller q_vector = adapter->q_vector[i]; 8423849623eSJacob Keller if (q_vector->tx.count && !q_vector->rx.count) 843dec0d8e4SJeff Kirsher /* Tx only */ 8443849623eSJacob Keller q_vector->itr = tx_itr_param; 8453849623eSJacob Keller else 846dec0d8e4SJeff Kirsher /* Rx only or mixed */ 8473849623eSJacob Keller q_vector->itr = rx_itr_param; 8483849623eSJacob Keller ixgbevf_write_eitr(q_vector); 8493849623eSJacob Keller } 8503849623eSJacob Keller 8513849623eSJacob Keller return 0; 8523849623eSJacob Keller } 8533849623eSJacob Keller 854b6411739SVlad Zolotarov static int ixgbevf_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info, 855b6411739SVlad Zolotarov u32 *rules __always_unused) 856b6411739SVlad Zolotarov { 857b6411739SVlad Zolotarov struct ixgbevf_adapter *adapter = netdev_priv(dev); 858b6411739SVlad Zolotarov 859b6411739SVlad Zolotarov switch (info->cmd) { 860b6411739SVlad Zolotarov case ETHTOOL_GRXRINGS: 861b6411739SVlad Zolotarov info->data = adapter->num_rx_queues; 862b6411739SVlad Zolotarov return 0; 863b6411739SVlad Zolotarov default: 864b6411739SVlad Zolotarov hw_dbg(&adapter->hw, "Command parameters not supported\n"); 865b6411739SVlad Zolotarov return -EOPNOTSUPP; 866b6411739SVlad Zolotarov } 867b6411739SVlad Zolotarov } 868b6411739SVlad Zolotarov 869b6411739SVlad Zolotarov static u32 ixgbevf_get_rxfh_indir_size(struct net_device *netdev) 870b6411739SVlad Zolotarov { 871b6411739SVlad Zolotarov struct ixgbevf_adapter *adapter = netdev_priv(netdev); 872b6411739SVlad Zolotarov 8739cba434fSEmil Tantilov if (adapter->hw.mac.type >= ixgbe_mac_X550_vf) 8749cba434fSEmil Tantilov return IXGBEVF_X550_VFRETA_SIZE; 875b6411739SVlad Zolotarov 8769cba434fSEmil Tantilov return IXGBEVF_82599_RETA_SIZE; 877b6411739SVlad Zolotarov } 878b6411739SVlad Zolotarov 879b6411739SVlad Zolotarov static u32 ixgbevf_get_rxfh_key_size(struct net_device *netdev) 880b6411739SVlad Zolotarov { 881b6411739SVlad Zolotarov return IXGBEVF_RSS_HASH_KEY_SIZE; 882b6411739SVlad Zolotarov } 883b6411739SVlad Zolotarov 884b6411739SVlad Zolotarov static int ixgbevf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, 885b6411739SVlad Zolotarov u8 *hfunc) 886b6411739SVlad Zolotarov { 887b6411739SVlad Zolotarov struct ixgbevf_adapter *adapter = netdev_priv(netdev); 888b6411739SVlad Zolotarov int err = 0; 889b6411739SVlad Zolotarov 890b6411739SVlad Zolotarov if (hfunc) 891b6411739SVlad Zolotarov *hfunc = ETH_RSS_HASH_TOP; 892b6411739SVlad Zolotarov 8939cba434fSEmil Tantilov if (adapter->hw.mac.type >= ixgbe_mac_X550_vf) { 8949cba434fSEmil Tantilov if (key) 8959cba434fSEmil Tantilov memcpy(key, adapter->rss_key, sizeof(adapter->rss_key)); 8969cba434fSEmil Tantilov 8979cba434fSEmil Tantilov if (indir) { 8989cba434fSEmil Tantilov int i; 8999cba434fSEmil Tantilov 9009cba434fSEmil Tantilov for (i = 0; i < IXGBEVF_X550_VFRETA_SIZE; i++) 9019cba434fSEmil Tantilov indir[i] = adapter->rss_indir_tbl[i]; 9029cba434fSEmil Tantilov } 9039cba434fSEmil Tantilov } else { 9049cba434fSEmil Tantilov /* If neither indirection table nor hash key was requested 9059cba434fSEmil Tantilov * - just return a success avoiding taking any locks. 906b6411739SVlad Zolotarov */ 907b6411739SVlad Zolotarov if (!indir && !key) 908b6411739SVlad Zolotarov return 0; 909b6411739SVlad Zolotarov 910b6411739SVlad Zolotarov spin_lock_bh(&adapter->mbx_lock); 911b6411739SVlad Zolotarov if (indir) 912b6411739SVlad Zolotarov err = ixgbevf_get_reta_locked(&adapter->hw, indir, 913b6411739SVlad Zolotarov adapter->num_rx_queues); 914b6411739SVlad Zolotarov 915b6411739SVlad Zolotarov if (!err && key) 916b6411739SVlad Zolotarov err = ixgbevf_get_rss_key_locked(&adapter->hw, key); 917b6411739SVlad Zolotarov 918b6411739SVlad Zolotarov spin_unlock_bh(&adapter->mbx_lock); 9199cba434fSEmil Tantilov } 920b6411739SVlad Zolotarov 921b6411739SVlad Zolotarov return err; 922b6411739SVlad Zolotarov } 923b6411739SVlad Zolotarov 924b47aca13SStephen Hemminger static const struct ethtool_ops ixgbevf_ethtool_ops = { 925dee1ad47SJeff Kirsher .get_settings = ixgbevf_get_settings, 926dee1ad47SJeff Kirsher .get_drvinfo = ixgbevf_get_drvinfo, 927dee1ad47SJeff Kirsher .get_regs_len = ixgbevf_get_regs_len, 928dee1ad47SJeff Kirsher .get_regs = ixgbevf_get_regs, 929dee1ad47SJeff Kirsher .nway_reset = ixgbevf_nway_reset, 930dee1ad47SJeff Kirsher .get_link = ethtool_op_get_link, 931dee1ad47SJeff Kirsher .get_ringparam = ixgbevf_get_ringparam, 932dee1ad47SJeff Kirsher .set_ringparam = ixgbevf_set_ringparam, 933dee1ad47SJeff Kirsher .get_msglevel = ixgbevf_get_msglevel, 934dee1ad47SJeff Kirsher .set_msglevel = ixgbevf_set_msglevel, 935dee1ad47SJeff Kirsher .self_test = ixgbevf_diag_test, 936dee1ad47SJeff Kirsher .get_sset_count = ixgbevf_get_sset_count, 937dee1ad47SJeff Kirsher .get_strings = ixgbevf_get_strings, 938dee1ad47SJeff Kirsher .get_ethtool_stats = ixgbevf_get_ethtool_stats, 9393849623eSJacob Keller .get_coalesce = ixgbevf_get_coalesce, 9403849623eSJacob Keller .set_coalesce = ixgbevf_set_coalesce, 941b6411739SVlad Zolotarov .get_rxnfc = ixgbevf_get_rxnfc, 942b6411739SVlad Zolotarov .get_rxfh_indir_size = ixgbevf_get_rxfh_indir_size, 943b6411739SVlad Zolotarov .get_rxfh_key_size = ixgbevf_get_rxfh_key_size, 944b6411739SVlad Zolotarov .get_rxfh = ixgbevf_get_rxfh, 945dee1ad47SJeff Kirsher }; 946dee1ad47SJeff Kirsher 947dee1ad47SJeff Kirsher void ixgbevf_set_ethtool_ops(struct net_device *netdev) 948dee1ad47SJeff Kirsher { 9497ad24ea4SWilfried Klaebe netdev->ethtool_ops = &ixgbevf_ethtool_ops; 950dee1ad47SJeff Kirsher } 951