1dee1ad47SJeff Kirsher /******************************************************************************* 2dee1ad47SJeff Kirsher 3dee1ad47SJeff Kirsher Intel 82599 Virtual Function driver 4dee1ad47SJeff Kirsher Copyright(c) 1999 - 2009 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 16dee1ad47SJeff Kirsher this program; if not, write to the Free Software Foundation, Inc., 17dee1ad47SJeff Kirsher 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 18dee1ad47SJeff Kirsher 19dee1ad47SJeff Kirsher The full GNU General Public License is included in this distribution in 20dee1ad47SJeff Kirsher the file called "COPYING". 21dee1ad47SJeff Kirsher 22dee1ad47SJeff Kirsher Contact Information: 23dee1ad47SJeff Kirsher e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> 24dee1ad47SJeff Kirsher Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 25dee1ad47SJeff Kirsher 26dee1ad47SJeff Kirsher *******************************************************************************/ 27dee1ad47SJeff Kirsher 28dee1ad47SJeff Kirsher /* ethtool support for ixgbevf */ 29dee1ad47SJeff Kirsher 30dee1ad47SJeff Kirsher #include <linux/types.h> 31dee1ad47SJeff Kirsher #include <linux/module.h> 32dee1ad47SJeff Kirsher #include <linux/slab.h> 33dee1ad47SJeff Kirsher #include <linux/pci.h> 34dee1ad47SJeff Kirsher #include <linux/netdevice.h> 35dee1ad47SJeff Kirsher #include <linux/ethtool.h> 36dee1ad47SJeff Kirsher #include <linux/vmalloc.h> 37dee1ad47SJeff Kirsher #include <linux/if_vlan.h> 38dee1ad47SJeff Kirsher #include <linux/uaccess.h> 39dee1ad47SJeff Kirsher 40dee1ad47SJeff Kirsher #include "ixgbevf.h" 41dee1ad47SJeff Kirsher 42dee1ad47SJeff Kirsher #define IXGBE_ALL_RAR_ENTRIES 16 43dee1ad47SJeff Kirsher 44dee1ad47SJeff Kirsher #ifdef ETHTOOL_GSTATS 45dee1ad47SJeff Kirsher struct ixgbe_stats { 46dee1ad47SJeff Kirsher char stat_string[ETH_GSTRING_LEN]; 47dee1ad47SJeff Kirsher int sizeof_stat; 48dee1ad47SJeff Kirsher int stat_offset; 49dee1ad47SJeff Kirsher int base_stat_offset; 50dee1ad47SJeff Kirsher int saved_reset_offset; 51dee1ad47SJeff Kirsher }; 52dee1ad47SJeff Kirsher 53dee1ad47SJeff Kirsher #define IXGBEVF_STAT(m, b, r) sizeof(((struct ixgbevf_adapter *)0)->m), \ 54dee1ad47SJeff Kirsher offsetof(struct ixgbevf_adapter, m), \ 55dee1ad47SJeff Kirsher offsetof(struct ixgbevf_adapter, b), \ 56dee1ad47SJeff Kirsher offsetof(struct ixgbevf_adapter, r) 57dee1ad47SJeff Kirsher static struct ixgbe_stats ixgbe_gstrings_stats[] = { 58dee1ad47SJeff Kirsher {"rx_packets", IXGBEVF_STAT(stats.vfgprc, stats.base_vfgprc, 59dee1ad47SJeff Kirsher stats.saved_reset_vfgprc)}, 60dee1ad47SJeff Kirsher {"tx_packets", IXGBEVF_STAT(stats.vfgptc, stats.base_vfgptc, 61dee1ad47SJeff Kirsher stats.saved_reset_vfgptc)}, 62dee1ad47SJeff Kirsher {"rx_bytes", IXGBEVF_STAT(stats.vfgorc, stats.base_vfgorc, 63dee1ad47SJeff Kirsher stats.saved_reset_vfgorc)}, 64dee1ad47SJeff Kirsher {"tx_bytes", IXGBEVF_STAT(stats.vfgotc, stats.base_vfgotc, 65dee1ad47SJeff Kirsher stats.saved_reset_vfgotc)}, 66dee1ad47SJeff Kirsher {"tx_busy", IXGBEVF_STAT(tx_busy, zero_base, zero_base)}, 67dee1ad47SJeff Kirsher {"multicast", IXGBEVF_STAT(stats.vfmprc, stats.base_vfmprc, 68dee1ad47SJeff Kirsher stats.saved_reset_vfmprc)}, 69dee1ad47SJeff Kirsher {"rx_csum_offload_good", IXGBEVF_STAT(hw_csum_rx_good, zero_base, 70dee1ad47SJeff Kirsher zero_base)}, 71dee1ad47SJeff Kirsher {"rx_csum_offload_errors", IXGBEVF_STAT(hw_csum_rx_error, zero_base, 72dee1ad47SJeff Kirsher zero_base)}, 73dee1ad47SJeff Kirsher {"tx_csum_offload_ctxt", IXGBEVF_STAT(hw_csum_tx_good, zero_base, 74dee1ad47SJeff Kirsher zero_base)}, 75dee1ad47SJeff Kirsher {"rx_header_split", IXGBEVF_STAT(rx_hdr_split, zero_base, zero_base)}, 76dee1ad47SJeff Kirsher }; 77dee1ad47SJeff Kirsher 78dee1ad47SJeff Kirsher #define IXGBE_QUEUE_STATS_LEN 0 79dee1ad47SJeff Kirsher #define IXGBE_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbe_gstrings_stats) 80dee1ad47SJeff Kirsher 81dee1ad47SJeff Kirsher #define IXGBEVF_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + IXGBE_QUEUE_STATS_LEN) 82dee1ad47SJeff Kirsher #endif /* ETHTOOL_GSTATS */ 83dee1ad47SJeff Kirsher #ifdef ETHTOOL_TEST 84dee1ad47SJeff Kirsher static const char ixgbe_gstrings_test[][ETH_GSTRING_LEN] = { 85dee1ad47SJeff Kirsher "Register test (offline)", 86dee1ad47SJeff Kirsher "Link test (on/offline)" 87dee1ad47SJeff Kirsher }; 88dee1ad47SJeff Kirsher #define IXGBE_TEST_LEN (sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN) 89dee1ad47SJeff Kirsher #endif /* ETHTOOL_TEST */ 90dee1ad47SJeff Kirsher 91dee1ad47SJeff Kirsher static int ixgbevf_get_settings(struct net_device *netdev, 92dee1ad47SJeff Kirsher struct ethtool_cmd *ecmd) 93dee1ad47SJeff Kirsher { 94dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 95dee1ad47SJeff Kirsher struct ixgbe_hw *hw = &adapter->hw; 96dee1ad47SJeff Kirsher u32 link_speed = 0; 97dee1ad47SJeff Kirsher bool link_up; 98dee1ad47SJeff Kirsher 99dee1ad47SJeff Kirsher ecmd->supported = SUPPORTED_10000baseT_Full; 100dee1ad47SJeff Kirsher ecmd->autoneg = AUTONEG_DISABLE; 101dee1ad47SJeff Kirsher ecmd->transceiver = XCVR_DUMMY1; 102dee1ad47SJeff Kirsher ecmd->port = -1; 103dee1ad47SJeff Kirsher 104dee1ad47SJeff Kirsher hw->mac.ops.check_link(hw, &link_speed, &link_up, false); 105dee1ad47SJeff Kirsher 106dee1ad47SJeff Kirsher if (link_up) { 107dee1ad47SJeff Kirsher ethtool_cmd_speed_set( 108dee1ad47SJeff Kirsher ecmd, 109dee1ad47SJeff Kirsher (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ? 110dee1ad47SJeff Kirsher SPEED_10000 : SPEED_1000); 111dee1ad47SJeff Kirsher ecmd->duplex = DUPLEX_FULL; 112dee1ad47SJeff Kirsher } else { 113dee1ad47SJeff Kirsher ethtool_cmd_speed_set(ecmd, -1); 114dee1ad47SJeff Kirsher ecmd->duplex = -1; 115dee1ad47SJeff Kirsher } 116dee1ad47SJeff Kirsher 117dee1ad47SJeff Kirsher return 0; 118dee1ad47SJeff Kirsher } 119dee1ad47SJeff Kirsher 120dee1ad47SJeff Kirsher static u32 ixgbevf_get_rx_csum(struct net_device *netdev) 121dee1ad47SJeff Kirsher { 122dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 123dee1ad47SJeff Kirsher return adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED; 124dee1ad47SJeff Kirsher } 125dee1ad47SJeff Kirsher 126dee1ad47SJeff Kirsher static int ixgbevf_set_rx_csum(struct net_device *netdev, u32 data) 127dee1ad47SJeff Kirsher { 128dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 129dee1ad47SJeff Kirsher if (data) 130dee1ad47SJeff Kirsher adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED; 131dee1ad47SJeff Kirsher else 132dee1ad47SJeff Kirsher adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED; 133dee1ad47SJeff Kirsher 134dee1ad47SJeff Kirsher if (netif_running(netdev)) { 135dee1ad47SJeff Kirsher if (!adapter->dev_closed) 136dee1ad47SJeff Kirsher ixgbevf_reinit_locked(adapter); 137dee1ad47SJeff Kirsher } else { 138dee1ad47SJeff Kirsher ixgbevf_reset(adapter); 139dee1ad47SJeff Kirsher } 140dee1ad47SJeff Kirsher 141dee1ad47SJeff Kirsher return 0; 142dee1ad47SJeff Kirsher } 143dee1ad47SJeff Kirsher 144dee1ad47SJeff Kirsher static int ixgbevf_set_tso(struct net_device *netdev, u32 data) 145dee1ad47SJeff Kirsher { 146dee1ad47SJeff Kirsher if (data) { 147dee1ad47SJeff Kirsher netdev->features |= NETIF_F_TSO; 148dee1ad47SJeff Kirsher netdev->features |= NETIF_F_TSO6; 149dee1ad47SJeff Kirsher } else { 150dee1ad47SJeff Kirsher netif_tx_stop_all_queues(netdev); 151dee1ad47SJeff Kirsher netdev->features &= ~NETIF_F_TSO; 152dee1ad47SJeff Kirsher netdev->features &= ~NETIF_F_TSO6; 153dee1ad47SJeff Kirsher netif_tx_start_all_queues(netdev); 154dee1ad47SJeff Kirsher } 155dee1ad47SJeff Kirsher return 0; 156dee1ad47SJeff Kirsher } 157dee1ad47SJeff Kirsher 158dee1ad47SJeff Kirsher static u32 ixgbevf_get_msglevel(struct net_device *netdev) 159dee1ad47SJeff Kirsher { 160dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 161dee1ad47SJeff Kirsher return adapter->msg_enable; 162dee1ad47SJeff Kirsher } 163dee1ad47SJeff Kirsher 164dee1ad47SJeff Kirsher static void ixgbevf_set_msglevel(struct net_device *netdev, u32 data) 165dee1ad47SJeff Kirsher { 166dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 167dee1ad47SJeff Kirsher adapter->msg_enable = data; 168dee1ad47SJeff Kirsher } 169dee1ad47SJeff Kirsher 170dee1ad47SJeff Kirsher #define IXGBE_GET_STAT(_A_, _R_) (_A_->stats._R_) 171dee1ad47SJeff Kirsher 172dee1ad47SJeff Kirsher static char *ixgbevf_reg_names[] = { 173dee1ad47SJeff Kirsher "IXGBE_VFCTRL", 174dee1ad47SJeff Kirsher "IXGBE_VFSTATUS", 175dee1ad47SJeff Kirsher "IXGBE_VFLINKS", 176dee1ad47SJeff Kirsher "IXGBE_VFRXMEMWRAP", 177dee1ad47SJeff Kirsher "IXGBE_VFFRTIMER", 178dee1ad47SJeff Kirsher "IXGBE_VTEICR", 179dee1ad47SJeff Kirsher "IXGBE_VTEICS", 180dee1ad47SJeff Kirsher "IXGBE_VTEIMS", 181dee1ad47SJeff Kirsher "IXGBE_VTEIMC", 182dee1ad47SJeff Kirsher "IXGBE_VTEIAC", 183dee1ad47SJeff Kirsher "IXGBE_VTEIAM", 184dee1ad47SJeff Kirsher "IXGBE_VTEITR", 185dee1ad47SJeff Kirsher "IXGBE_VTIVAR", 186dee1ad47SJeff Kirsher "IXGBE_VTIVAR_MISC", 187dee1ad47SJeff Kirsher "IXGBE_VFRDBAL0", 188dee1ad47SJeff Kirsher "IXGBE_VFRDBAL1", 189dee1ad47SJeff Kirsher "IXGBE_VFRDBAH0", 190dee1ad47SJeff Kirsher "IXGBE_VFRDBAH1", 191dee1ad47SJeff Kirsher "IXGBE_VFRDLEN0", 192dee1ad47SJeff Kirsher "IXGBE_VFRDLEN1", 193dee1ad47SJeff Kirsher "IXGBE_VFRDH0", 194dee1ad47SJeff Kirsher "IXGBE_VFRDH1", 195dee1ad47SJeff Kirsher "IXGBE_VFRDT0", 196dee1ad47SJeff Kirsher "IXGBE_VFRDT1", 197dee1ad47SJeff Kirsher "IXGBE_VFRXDCTL0", 198dee1ad47SJeff Kirsher "IXGBE_VFRXDCTL1", 199dee1ad47SJeff Kirsher "IXGBE_VFSRRCTL0", 200dee1ad47SJeff Kirsher "IXGBE_VFSRRCTL1", 201dee1ad47SJeff Kirsher "IXGBE_VFPSRTYPE", 202dee1ad47SJeff Kirsher "IXGBE_VFTDBAL0", 203dee1ad47SJeff Kirsher "IXGBE_VFTDBAL1", 204dee1ad47SJeff Kirsher "IXGBE_VFTDBAH0", 205dee1ad47SJeff Kirsher "IXGBE_VFTDBAH1", 206dee1ad47SJeff Kirsher "IXGBE_VFTDLEN0", 207dee1ad47SJeff Kirsher "IXGBE_VFTDLEN1", 208dee1ad47SJeff Kirsher "IXGBE_VFTDH0", 209dee1ad47SJeff Kirsher "IXGBE_VFTDH1", 210dee1ad47SJeff Kirsher "IXGBE_VFTDT0", 211dee1ad47SJeff Kirsher "IXGBE_VFTDT1", 212dee1ad47SJeff Kirsher "IXGBE_VFTXDCTL0", 213dee1ad47SJeff Kirsher "IXGBE_VFTXDCTL1", 214dee1ad47SJeff Kirsher "IXGBE_VFTDWBAL0", 215dee1ad47SJeff Kirsher "IXGBE_VFTDWBAL1", 216dee1ad47SJeff Kirsher "IXGBE_VFTDWBAH0", 217dee1ad47SJeff Kirsher "IXGBE_VFTDWBAH1" 218dee1ad47SJeff Kirsher }; 219dee1ad47SJeff Kirsher 220dee1ad47SJeff Kirsher 221dee1ad47SJeff Kirsher static int ixgbevf_get_regs_len(struct net_device *netdev) 222dee1ad47SJeff Kirsher { 223dee1ad47SJeff Kirsher return (ARRAY_SIZE(ixgbevf_reg_names)) * sizeof(u32); 224dee1ad47SJeff Kirsher } 225dee1ad47SJeff Kirsher 226dee1ad47SJeff Kirsher static void ixgbevf_get_regs(struct net_device *netdev, 227dee1ad47SJeff Kirsher struct ethtool_regs *regs, 228dee1ad47SJeff Kirsher void *p) 229dee1ad47SJeff Kirsher { 230dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 231dee1ad47SJeff Kirsher struct ixgbe_hw *hw = &adapter->hw; 232dee1ad47SJeff Kirsher u32 *regs_buff = p; 233dee1ad47SJeff Kirsher u32 regs_len = ixgbevf_get_regs_len(netdev); 234dee1ad47SJeff Kirsher u8 i; 235dee1ad47SJeff Kirsher 236dee1ad47SJeff Kirsher memset(p, 0, regs_len); 237dee1ad47SJeff Kirsher 238dee1ad47SJeff Kirsher regs->version = (1 << 24) | hw->revision_id << 16 | hw->device_id; 239dee1ad47SJeff Kirsher 240dee1ad47SJeff Kirsher /* General Registers */ 241dee1ad47SJeff Kirsher regs_buff[0] = IXGBE_READ_REG(hw, IXGBE_VFCTRL); 242dee1ad47SJeff Kirsher regs_buff[1] = IXGBE_READ_REG(hw, IXGBE_VFSTATUS); 243dee1ad47SJeff Kirsher regs_buff[2] = IXGBE_READ_REG(hw, IXGBE_VFLINKS); 244dee1ad47SJeff Kirsher regs_buff[3] = IXGBE_READ_REG(hw, IXGBE_VFRXMEMWRAP); 245dee1ad47SJeff Kirsher regs_buff[4] = IXGBE_READ_REG(hw, IXGBE_VFFRTIMER); 246dee1ad47SJeff Kirsher 247dee1ad47SJeff Kirsher /* Interrupt */ 248dee1ad47SJeff Kirsher /* don't read EICR because it can clear interrupt causes, instead 249dee1ad47SJeff Kirsher * read EICS which is a shadow but doesn't clear EICR */ 250dee1ad47SJeff Kirsher regs_buff[5] = IXGBE_READ_REG(hw, IXGBE_VTEICS); 251dee1ad47SJeff Kirsher regs_buff[6] = IXGBE_READ_REG(hw, IXGBE_VTEICS); 252dee1ad47SJeff Kirsher regs_buff[7] = IXGBE_READ_REG(hw, IXGBE_VTEIMS); 253dee1ad47SJeff Kirsher regs_buff[8] = IXGBE_READ_REG(hw, IXGBE_VTEIMC); 254dee1ad47SJeff Kirsher regs_buff[9] = IXGBE_READ_REG(hw, IXGBE_VTEIAC); 255dee1ad47SJeff Kirsher regs_buff[10] = IXGBE_READ_REG(hw, IXGBE_VTEIAM); 256dee1ad47SJeff Kirsher regs_buff[11] = IXGBE_READ_REG(hw, IXGBE_VTEITR(0)); 257dee1ad47SJeff Kirsher regs_buff[12] = IXGBE_READ_REG(hw, IXGBE_VTIVAR(0)); 258dee1ad47SJeff Kirsher regs_buff[13] = IXGBE_READ_REG(hw, IXGBE_VTIVAR_MISC); 259dee1ad47SJeff Kirsher 260dee1ad47SJeff Kirsher /* Receive DMA */ 261dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 262dee1ad47SJeff Kirsher regs_buff[14 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDBAL(i)); 263dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 264dee1ad47SJeff Kirsher regs_buff[16 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDBAH(i)); 265dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 266dee1ad47SJeff Kirsher regs_buff[18 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDLEN(i)); 267dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 268dee1ad47SJeff Kirsher regs_buff[20 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDH(i)); 269dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 270dee1ad47SJeff Kirsher regs_buff[22 + i] = IXGBE_READ_REG(hw, IXGBE_VFRDT(i)); 271dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 272dee1ad47SJeff Kirsher regs_buff[24 + i] = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)); 273dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 274dee1ad47SJeff Kirsher regs_buff[26 + i] = IXGBE_READ_REG(hw, IXGBE_VFSRRCTL(i)); 275dee1ad47SJeff Kirsher 276dee1ad47SJeff Kirsher /* Receive */ 277dee1ad47SJeff Kirsher regs_buff[28] = IXGBE_READ_REG(hw, IXGBE_VFPSRTYPE); 278dee1ad47SJeff Kirsher 279dee1ad47SJeff Kirsher /* Transmit */ 280dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 281dee1ad47SJeff Kirsher regs_buff[29 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDBAL(i)); 282dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 283dee1ad47SJeff Kirsher regs_buff[31 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDBAH(i)); 284dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 285dee1ad47SJeff Kirsher regs_buff[33 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDLEN(i)); 286dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 287dee1ad47SJeff Kirsher regs_buff[35 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDH(i)); 288dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 289dee1ad47SJeff Kirsher regs_buff[37 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDT(i)); 290dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 291dee1ad47SJeff Kirsher regs_buff[39 + i] = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(i)); 292dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 293dee1ad47SJeff Kirsher regs_buff[41 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDWBAL(i)); 294dee1ad47SJeff Kirsher for (i = 0; i < 2; i++) 295dee1ad47SJeff Kirsher regs_buff[43 + i] = IXGBE_READ_REG(hw, IXGBE_VFTDWBAH(i)); 296dee1ad47SJeff Kirsher 297dee1ad47SJeff Kirsher for (i = 0; i < ARRAY_SIZE(ixgbevf_reg_names); i++) 298dee1ad47SJeff Kirsher hw_dbg(hw, "%s\t%8.8x\n", ixgbevf_reg_names[i], regs_buff[i]); 299dee1ad47SJeff Kirsher } 300dee1ad47SJeff Kirsher 301dee1ad47SJeff Kirsher static void ixgbevf_get_drvinfo(struct net_device *netdev, 302dee1ad47SJeff Kirsher struct ethtool_drvinfo *drvinfo) 303dee1ad47SJeff Kirsher { 304dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 305dee1ad47SJeff Kirsher 306dee1ad47SJeff Kirsher strlcpy(drvinfo->driver, ixgbevf_driver_name, 32); 307dee1ad47SJeff Kirsher strlcpy(drvinfo->version, ixgbevf_driver_version, 32); 308dee1ad47SJeff Kirsher 309dee1ad47SJeff Kirsher strlcpy(drvinfo->fw_version, "N/A", 4); 310dee1ad47SJeff Kirsher strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); 311dee1ad47SJeff Kirsher } 312dee1ad47SJeff Kirsher 313dee1ad47SJeff Kirsher static void ixgbevf_get_ringparam(struct net_device *netdev, 314dee1ad47SJeff Kirsher struct ethtool_ringparam *ring) 315dee1ad47SJeff Kirsher { 316dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 317dee1ad47SJeff Kirsher struct ixgbevf_ring *tx_ring = adapter->tx_ring; 318dee1ad47SJeff Kirsher struct ixgbevf_ring *rx_ring = adapter->rx_ring; 319dee1ad47SJeff Kirsher 320dee1ad47SJeff Kirsher ring->rx_max_pending = IXGBEVF_MAX_RXD; 321dee1ad47SJeff Kirsher ring->tx_max_pending = IXGBEVF_MAX_TXD; 322dee1ad47SJeff Kirsher ring->rx_mini_max_pending = 0; 323dee1ad47SJeff Kirsher ring->rx_jumbo_max_pending = 0; 324dee1ad47SJeff Kirsher ring->rx_pending = rx_ring->count; 325dee1ad47SJeff Kirsher ring->tx_pending = tx_ring->count; 326dee1ad47SJeff Kirsher ring->rx_mini_pending = 0; 327dee1ad47SJeff Kirsher ring->rx_jumbo_pending = 0; 328dee1ad47SJeff Kirsher } 329dee1ad47SJeff Kirsher 330dee1ad47SJeff Kirsher static int ixgbevf_set_ringparam(struct net_device *netdev, 331dee1ad47SJeff Kirsher struct ethtool_ringparam *ring) 332dee1ad47SJeff Kirsher { 333dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 334dee1ad47SJeff Kirsher struct ixgbevf_ring *tx_ring = NULL, *rx_ring = NULL; 335dee1ad47SJeff Kirsher int i, err = 0; 336dee1ad47SJeff Kirsher u32 new_rx_count, new_tx_count; 337dee1ad47SJeff Kirsher 338dee1ad47SJeff Kirsher if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) 339dee1ad47SJeff Kirsher return -EINVAL; 340dee1ad47SJeff Kirsher 341dee1ad47SJeff Kirsher new_rx_count = max(ring->rx_pending, (u32)IXGBEVF_MIN_RXD); 342dee1ad47SJeff Kirsher new_rx_count = min(new_rx_count, (u32)IXGBEVF_MAX_RXD); 343dee1ad47SJeff Kirsher new_rx_count = ALIGN(new_rx_count, IXGBE_REQ_RX_DESCRIPTOR_MULTIPLE); 344dee1ad47SJeff Kirsher 345dee1ad47SJeff Kirsher new_tx_count = max(ring->tx_pending, (u32)IXGBEVF_MIN_TXD); 346dee1ad47SJeff Kirsher new_tx_count = min(new_tx_count, (u32)IXGBEVF_MAX_TXD); 347dee1ad47SJeff Kirsher new_tx_count = ALIGN(new_tx_count, IXGBE_REQ_TX_DESCRIPTOR_MULTIPLE); 348dee1ad47SJeff Kirsher 349dee1ad47SJeff Kirsher if ((new_tx_count == adapter->tx_ring->count) && 350dee1ad47SJeff Kirsher (new_rx_count == adapter->rx_ring->count)) { 351dee1ad47SJeff Kirsher /* nothing to do */ 352dee1ad47SJeff Kirsher return 0; 353dee1ad47SJeff Kirsher } 354dee1ad47SJeff Kirsher 355dee1ad47SJeff Kirsher while (test_and_set_bit(__IXGBEVF_RESETTING, &adapter->state)) 356dee1ad47SJeff Kirsher msleep(1); 357dee1ad47SJeff Kirsher 358dee1ad47SJeff Kirsher /* 359dee1ad47SJeff Kirsher * If the adapter isn't up and running then just set the 360dee1ad47SJeff Kirsher * new parameters and scurry for the exits. 361dee1ad47SJeff Kirsher */ 362dee1ad47SJeff Kirsher if (!netif_running(adapter->netdev)) { 363dee1ad47SJeff Kirsher for (i = 0; i < adapter->num_tx_queues; i++) 364dee1ad47SJeff Kirsher adapter->tx_ring[i].count = new_tx_count; 365dee1ad47SJeff Kirsher for (i = 0; i < adapter->num_rx_queues; i++) 366dee1ad47SJeff Kirsher adapter->rx_ring[i].count = new_rx_count; 367dee1ad47SJeff Kirsher adapter->tx_ring_count = new_tx_count; 368dee1ad47SJeff Kirsher adapter->rx_ring_count = new_rx_count; 369dee1ad47SJeff Kirsher goto clear_reset; 370dee1ad47SJeff Kirsher } 371dee1ad47SJeff Kirsher 372dee1ad47SJeff Kirsher tx_ring = kcalloc(adapter->num_tx_queues, 373dee1ad47SJeff Kirsher sizeof(struct ixgbevf_ring), GFP_KERNEL); 374dee1ad47SJeff Kirsher if (!tx_ring) { 375dee1ad47SJeff Kirsher err = -ENOMEM; 376dee1ad47SJeff Kirsher goto clear_reset; 377dee1ad47SJeff Kirsher } 378dee1ad47SJeff Kirsher 379dee1ad47SJeff Kirsher rx_ring = kcalloc(adapter->num_rx_queues, 380dee1ad47SJeff Kirsher sizeof(struct ixgbevf_ring), GFP_KERNEL); 381dee1ad47SJeff Kirsher if (!rx_ring) { 382dee1ad47SJeff Kirsher err = -ENOMEM; 383dee1ad47SJeff Kirsher goto err_rx_setup; 384dee1ad47SJeff Kirsher } 385dee1ad47SJeff Kirsher 386dee1ad47SJeff Kirsher ixgbevf_down(adapter); 387dee1ad47SJeff Kirsher 388dee1ad47SJeff Kirsher memcpy(tx_ring, adapter->tx_ring, 389dee1ad47SJeff Kirsher adapter->num_tx_queues * sizeof(struct ixgbevf_ring)); 390dee1ad47SJeff Kirsher for (i = 0; i < adapter->num_tx_queues; i++) { 391dee1ad47SJeff Kirsher tx_ring[i].count = new_tx_count; 392dee1ad47SJeff Kirsher err = ixgbevf_setup_tx_resources(adapter, &tx_ring[i]); 393dee1ad47SJeff Kirsher if (err) { 394dee1ad47SJeff Kirsher while (i) { 395dee1ad47SJeff Kirsher i--; 396dee1ad47SJeff Kirsher ixgbevf_free_tx_resources(adapter, 397dee1ad47SJeff Kirsher &tx_ring[i]); 398dee1ad47SJeff Kirsher } 399dee1ad47SJeff Kirsher goto err_tx_ring_setup; 400dee1ad47SJeff Kirsher } 401dee1ad47SJeff Kirsher tx_ring[i].v_idx = adapter->tx_ring[i].v_idx; 402dee1ad47SJeff Kirsher } 403dee1ad47SJeff Kirsher 404dee1ad47SJeff Kirsher memcpy(rx_ring, adapter->rx_ring, 405dee1ad47SJeff Kirsher adapter->num_rx_queues * sizeof(struct ixgbevf_ring)); 406dee1ad47SJeff Kirsher for (i = 0; i < adapter->num_rx_queues; i++) { 407dee1ad47SJeff Kirsher rx_ring[i].count = new_rx_count; 408dee1ad47SJeff Kirsher err = ixgbevf_setup_rx_resources(adapter, &rx_ring[i]); 409dee1ad47SJeff Kirsher if (err) { 410dee1ad47SJeff Kirsher while (i) { 411dee1ad47SJeff Kirsher i--; 412dee1ad47SJeff Kirsher ixgbevf_free_rx_resources(adapter, 413dee1ad47SJeff Kirsher &rx_ring[i]); 414dee1ad47SJeff Kirsher } 415dee1ad47SJeff Kirsher goto err_rx_ring_setup; 416dee1ad47SJeff Kirsher } 417dee1ad47SJeff Kirsher rx_ring[i].v_idx = adapter->rx_ring[i].v_idx; 418dee1ad47SJeff Kirsher } 419dee1ad47SJeff Kirsher 420dee1ad47SJeff Kirsher /* 421dee1ad47SJeff Kirsher * Only switch to new rings if all the prior allocations 422dee1ad47SJeff Kirsher * and ring setups have succeeded. 423dee1ad47SJeff Kirsher */ 424dee1ad47SJeff Kirsher kfree(adapter->tx_ring); 425dee1ad47SJeff Kirsher adapter->tx_ring = tx_ring; 426dee1ad47SJeff Kirsher adapter->tx_ring_count = new_tx_count; 427dee1ad47SJeff Kirsher 428dee1ad47SJeff Kirsher kfree(adapter->rx_ring); 429dee1ad47SJeff Kirsher adapter->rx_ring = rx_ring; 430dee1ad47SJeff Kirsher adapter->rx_ring_count = new_rx_count; 431dee1ad47SJeff Kirsher 432dee1ad47SJeff Kirsher /* success! */ 433dee1ad47SJeff Kirsher ixgbevf_up(adapter); 434dee1ad47SJeff Kirsher 435dee1ad47SJeff Kirsher goto clear_reset; 436dee1ad47SJeff Kirsher 437dee1ad47SJeff Kirsher err_rx_ring_setup: 438dee1ad47SJeff Kirsher for(i = 0; i < adapter->num_tx_queues; i++) 439dee1ad47SJeff Kirsher ixgbevf_free_tx_resources(adapter, &tx_ring[i]); 440dee1ad47SJeff Kirsher 441dee1ad47SJeff Kirsher err_tx_ring_setup: 442dee1ad47SJeff Kirsher kfree(rx_ring); 443dee1ad47SJeff Kirsher 444dee1ad47SJeff Kirsher err_rx_setup: 445dee1ad47SJeff Kirsher kfree(tx_ring); 446dee1ad47SJeff Kirsher 447dee1ad47SJeff Kirsher clear_reset: 448dee1ad47SJeff Kirsher clear_bit(__IXGBEVF_RESETTING, &adapter->state); 449dee1ad47SJeff Kirsher return err; 450dee1ad47SJeff Kirsher } 451dee1ad47SJeff Kirsher 452dee1ad47SJeff Kirsher static int ixgbevf_get_sset_count(struct net_device *dev, int stringset) 453dee1ad47SJeff Kirsher { 454dee1ad47SJeff Kirsher switch (stringset) { 455dee1ad47SJeff Kirsher case ETH_SS_TEST: 456dee1ad47SJeff Kirsher return IXGBE_TEST_LEN; 457dee1ad47SJeff Kirsher case ETH_SS_STATS: 458dee1ad47SJeff Kirsher return IXGBE_GLOBAL_STATS_LEN; 459dee1ad47SJeff Kirsher default: 460dee1ad47SJeff Kirsher return -EINVAL; 461dee1ad47SJeff Kirsher } 462dee1ad47SJeff Kirsher } 463dee1ad47SJeff Kirsher 464dee1ad47SJeff Kirsher static void ixgbevf_get_ethtool_stats(struct net_device *netdev, 465dee1ad47SJeff Kirsher struct ethtool_stats *stats, u64 *data) 466dee1ad47SJeff Kirsher { 467dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 468dee1ad47SJeff Kirsher int i; 469dee1ad47SJeff Kirsher 470dee1ad47SJeff Kirsher ixgbevf_update_stats(adapter); 471dee1ad47SJeff Kirsher for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) { 472dee1ad47SJeff Kirsher char *p = (char *)adapter + 473dee1ad47SJeff Kirsher ixgbe_gstrings_stats[i].stat_offset; 474dee1ad47SJeff Kirsher char *b = (char *)adapter + 475dee1ad47SJeff Kirsher ixgbe_gstrings_stats[i].base_stat_offset; 476dee1ad47SJeff Kirsher char *r = (char *)adapter + 477dee1ad47SJeff Kirsher ixgbe_gstrings_stats[i].saved_reset_offset; 478dee1ad47SJeff Kirsher data[i] = ((ixgbe_gstrings_stats[i].sizeof_stat == 479dee1ad47SJeff Kirsher sizeof(u64)) ? *(u64 *)p : *(u32 *)p) - 480dee1ad47SJeff Kirsher ((ixgbe_gstrings_stats[i].sizeof_stat == 481dee1ad47SJeff Kirsher sizeof(u64)) ? *(u64 *)b : *(u32 *)b) + 482dee1ad47SJeff Kirsher ((ixgbe_gstrings_stats[i].sizeof_stat == 483dee1ad47SJeff Kirsher sizeof(u64)) ? *(u64 *)r : *(u32 *)r); 484dee1ad47SJeff Kirsher } 485dee1ad47SJeff Kirsher } 486dee1ad47SJeff Kirsher 487dee1ad47SJeff Kirsher static void ixgbevf_get_strings(struct net_device *netdev, u32 stringset, 488dee1ad47SJeff Kirsher u8 *data) 489dee1ad47SJeff Kirsher { 490dee1ad47SJeff Kirsher char *p = (char *)data; 491dee1ad47SJeff Kirsher int i; 492dee1ad47SJeff Kirsher 493dee1ad47SJeff Kirsher switch (stringset) { 494dee1ad47SJeff Kirsher case ETH_SS_TEST: 495dee1ad47SJeff Kirsher memcpy(data, *ixgbe_gstrings_test, 496dee1ad47SJeff Kirsher IXGBE_TEST_LEN * ETH_GSTRING_LEN); 497dee1ad47SJeff Kirsher break; 498dee1ad47SJeff Kirsher case ETH_SS_STATS: 499dee1ad47SJeff Kirsher for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) { 500dee1ad47SJeff Kirsher memcpy(p, ixgbe_gstrings_stats[i].stat_string, 501dee1ad47SJeff Kirsher ETH_GSTRING_LEN); 502dee1ad47SJeff Kirsher p += ETH_GSTRING_LEN; 503dee1ad47SJeff Kirsher } 504dee1ad47SJeff Kirsher break; 505dee1ad47SJeff Kirsher } 506dee1ad47SJeff Kirsher } 507dee1ad47SJeff Kirsher 508dee1ad47SJeff Kirsher static int ixgbevf_link_test(struct ixgbevf_adapter *adapter, u64 *data) 509dee1ad47SJeff Kirsher { 510dee1ad47SJeff Kirsher struct ixgbe_hw *hw = &adapter->hw; 511dee1ad47SJeff Kirsher bool link_up; 512dee1ad47SJeff Kirsher u32 link_speed = 0; 513dee1ad47SJeff Kirsher *data = 0; 514dee1ad47SJeff Kirsher 515dee1ad47SJeff Kirsher hw->mac.ops.check_link(hw, &link_speed, &link_up, true); 516dee1ad47SJeff Kirsher if (!link_up) 517dee1ad47SJeff Kirsher *data = 1; 518dee1ad47SJeff Kirsher 519dee1ad47SJeff Kirsher return *data; 520dee1ad47SJeff Kirsher } 521dee1ad47SJeff Kirsher 522dee1ad47SJeff Kirsher /* ethtool register test data */ 523dee1ad47SJeff Kirsher struct ixgbevf_reg_test { 524dee1ad47SJeff Kirsher u16 reg; 525dee1ad47SJeff Kirsher u8 array_len; 526dee1ad47SJeff Kirsher u8 test_type; 527dee1ad47SJeff Kirsher u32 mask; 528dee1ad47SJeff Kirsher u32 write; 529dee1ad47SJeff Kirsher }; 530dee1ad47SJeff Kirsher 531dee1ad47SJeff Kirsher /* In the hardware, registers are laid out either singly, in arrays 532dee1ad47SJeff Kirsher * spaced 0x40 bytes apart, or in contiguous tables. We assume 533dee1ad47SJeff Kirsher * most tests take place on arrays or single registers (handled 534dee1ad47SJeff Kirsher * as a single-element array) and special-case the tables. 535dee1ad47SJeff Kirsher * Table tests are always pattern tests. 536dee1ad47SJeff Kirsher * 537dee1ad47SJeff Kirsher * We also make provision for some required setup steps by specifying 538dee1ad47SJeff Kirsher * registers to be written without any read-back testing. 539dee1ad47SJeff Kirsher */ 540dee1ad47SJeff Kirsher 541dee1ad47SJeff Kirsher #define PATTERN_TEST 1 542dee1ad47SJeff Kirsher #define SET_READ_TEST 2 543dee1ad47SJeff Kirsher #define WRITE_NO_TEST 3 544dee1ad47SJeff Kirsher #define TABLE32_TEST 4 545dee1ad47SJeff Kirsher #define TABLE64_TEST_LO 5 546dee1ad47SJeff Kirsher #define TABLE64_TEST_HI 6 547dee1ad47SJeff Kirsher 548dee1ad47SJeff Kirsher /* default VF register test */ 549dee1ad47SJeff Kirsher static const struct ixgbevf_reg_test reg_test_vf[] = { 550dee1ad47SJeff Kirsher { IXGBE_VFRDBAL(0), 2, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 }, 551dee1ad47SJeff Kirsher { IXGBE_VFRDBAH(0), 2, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, 552dee1ad47SJeff Kirsher { IXGBE_VFRDLEN(0), 2, PATTERN_TEST, 0x000FFF80, 0x000FFFFF }, 553dee1ad47SJeff Kirsher { IXGBE_VFRXDCTL(0), 2, WRITE_NO_TEST, 0, IXGBE_RXDCTL_ENABLE }, 554dee1ad47SJeff Kirsher { IXGBE_VFRDT(0), 2, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, 555dee1ad47SJeff Kirsher { IXGBE_VFRXDCTL(0), 2, WRITE_NO_TEST, 0, 0 }, 556dee1ad47SJeff Kirsher { IXGBE_VFTDBAL(0), 2, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, 557dee1ad47SJeff Kirsher { IXGBE_VFTDBAH(0), 2, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, 558dee1ad47SJeff Kirsher { IXGBE_VFTDLEN(0), 2, PATTERN_TEST, 0x000FFF80, 0x000FFF80 }, 559dee1ad47SJeff Kirsher { 0, 0, 0, 0 } 560dee1ad47SJeff Kirsher }; 561dee1ad47SJeff Kirsher 562dee1ad47SJeff Kirsher static const u32 register_test_patterns[] = { 563dee1ad47SJeff Kirsher 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF 564dee1ad47SJeff Kirsher }; 565dee1ad47SJeff Kirsher 566dee1ad47SJeff Kirsher #define REG_PATTERN_TEST(R, M, W) \ 567dee1ad47SJeff Kirsher { \ 568dee1ad47SJeff Kirsher u32 pat, val, before; \ 569dee1ad47SJeff Kirsher for (pat = 0; pat < ARRAY_SIZE(register_test_patterns); pat++) { \ 570dee1ad47SJeff Kirsher before = readl(adapter->hw.hw_addr + R); \ 571dee1ad47SJeff Kirsher writel((register_test_patterns[pat] & W), \ 572dee1ad47SJeff Kirsher (adapter->hw.hw_addr + R)); \ 573dee1ad47SJeff Kirsher val = readl(adapter->hw.hw_addr + R); \ 574dee1ad47SJeff Kirsher if (val != (register_test_patterns[pat] & W & M)) { \ 575dee1ad47SJeff Kirsher hw_dbg(&adapter->hw, \ 576dee1ad47SJeff Kirsher "pattern test reg %04X failed: got " \ 577dee1ad47SJeff Kirsher "0x%08X expected 0x%08X\n", \ 578dee1ad47SJeff Kirsher R, val, (register_test_patterns[pat] & W & M)); \ 579dee1ad47SJeff Kirsher *data = R; \ 580dee1ad47SJeff Kirsher writel(before, adapter->hw.hw_addr + R); \ 581dee1ad47SJeff Kirsher return 1; \ 582dee1ad47SJeff Kirsher } \ 583dee1ad47SJeff Kirsher writel(before, adapter->hw.hw_addr + R); \ 584dee1ad47SJeff Kirsher } \ 585dee1ad47SJeff Kirsher } 586dee1ad47SJeff Kirsher 587dee1ad47SJeff Kirsher #define REG_SET_AND_CHECK(R, M, W) \ 588dee1ad47SJeff Kirsher { \ 589dee1ad47SJeff Kirsher u32 val, before; \ 590dee1ad47SJeff Kirsher before = readl(adapter->hw.hw_addr + R); \ 591dee1ad47SJeff Kirsher writel((W & M), (adapter->hw.hw_addr + R)); \ 592dee1ad47SJeff Kirsher val = readl(adapter->hw.hw_addr + R); \ 593dee1ad47SJeff Kirsher if ((W & M) != (val & M)) { \ 594dee1ad47SJeff Kirsher printk(KERN_ERR "set/check reg %04X test failed: got 0x%08X " \ 595dee1ad47SJeff Kirsher "expected 0x%08X\n", R, (val & M), (W & M)); \ 596dee1ad47SJeff Kirsher *data = R; \ 597dee1ad47SJeff Kirsher writel(before, (adapter->hw.hw_addr + R)); \ 598dee1ad47SJeff Kirsher return 1; \ 599dee1ad47SJeff Kirsher } \ 600dee1ad47SJeff Kirsher writel(before, (adapter->hw.hw_addr + R)); \ 601dee1ad47SJeff Kirsher } 602dee1ad47SJeff Kirsher 603dee1ad47SJeff Kirsher static int ixgbevf_reg_test(struct ixgbevf_adapter *adapter, u64 *data) 604dee1ad47SJeff Kirsher { 605dee1ad47SJeff Kirsher const struct ixgbevf_reg_test *test; 606dee1ad47SJeff Kirsher u32 i; 607dee1ad47SJeff Kirsher 608dee1ad47SJeff Kirsher test = reg_test_vf; 609dee1ad47SJeff Kirsher 610dee1ad47SJeff Kirsher /* 611dee1ad47SJeff Kirsher * Perform the register test, looping through the test table 612dee1ad47SJeff Kirsher * until we either fail or reach the null entry. 613dee1ad47SJeff Kirsher */ 614dee1ad47SJeff Kirsher while (test->reg) { 615dee1ad47SJeff Kirsher for (i = 0; i < test->array_len; i++) { 616dee1ad47SJeff Kirsher switch (test->test_type) { 617dee1ad47SJeff Kirsher case PATTERN_TEST: 618dee1ad47SJeff Kirsher REG_PATTERN_TEST(test->reg + (i * 0x40), 619dee1ad47SJeff Kirsher test->mask, 620dee1ad47SJeff Kirsher test->write); 621dee1ad47SJeff Kirsher break; 622dee1ad47SJeff Kirsher case SET_READ_TEST: 623dee1ad47SJeff Kirsher REG_SET_AND_CHECK(test->reg + (i * 0x40), 624dee1ad47SJeff Kirsher test->mask, 625dee1ad47SJeff Kirsher test->write); 626dee1ad47SJeff Kirsher break; 627dee1ad47SJeff Kirsher case WRITE_NO_TEST: 628dee1ad47SJeff Kirsher writel(test->write, 629dee1ad47SJeff Kirsher (adapter->hw.hw_addr + test->reg) 630dee1ad47SJeff Kirsher + (i * 0x40)); 631dee1ad47SJeff Kirsher break; 632dee1ad47SJeff Kirsher case TABLE32_TEST: 633dee1ad47SJeff Kirsher REG_PATTERN_TEST(test->reg + (i * 4), 634dee1ad47SJeff Kirsher test->mask, 635dee1ad47SJeff Kirsher test->write); 636dee1ad47SJeff Kirsher break; 637dee1ad47SJeff Kirsher case TABLE64_TEST_LO: 638dee1ad47SJeff Kirsher REG_PATTERN_TEST(test->reg + (i * 8), 639dee1ad47SJeff Kirsher test->mask, 640dee1ad47SJeff Kirsher test->write); 641dee1ad47SJeff Kirsher break; 642dee1ad47SJeff Kirsher case TABLE64_TEST_HI: 643dee1ad47SJeff Kirsher REG_PATTERN_TEST((test->reg + 4) + (i * 8), 644dee1ad47SJeff Kirsher test->mask, 645dee1ad47SJeff Kirsher test->write); 646dee1ad47SJeff Kirsher break; 647dee1ad47SJeff Kirsher } 648dee1ad47SJeff Kirsher } 649dee1ad47SJeff Kirsher test++; 650dee1ad47SJeff Kirsher } 651dee1ad47SJeff Kirsher 652dee1ad47SJeff Kirsher *data = 0; 653dee1ad47SJeff Kirsher return *data; 654dee1ad47SJeff Kirsher } 655dee1ad47SJeff Kirsher 656dee1ad47SJeff Kirsher static void ixgbevf_diag_test(struct net_device *netdev, 657dee1ad47SJeff Kirsher struct ethtool_test *eth_test, u64 *data) 658dee1ad47SJeff Kirsher { 659dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 660dee1ad47SJeff Kirsher bool if_running = netif_running(netdev); 661dee1ad47SJeff Kirsher 662dee1ad47SJeff Kirsher set_bit(__IXGBEVF_TESTING, &adapter->state); 663dee1ad47SJeff Kirsher if (eth_test->flags == ETH_TEST_FL_OFFLINE) { 664dee1ad47SJeff Kirsher /* Offline tests */ 665dee1ad47SJeff Kirsher 666dee1ad47SJeff Kirsher hw_dbg(&adapter->hw, "offline testing starting\n"); 667dee1ad47SJeff Kirsher 668dee1ad47SJeff Kirsher /* Link test performed before hardware reset so autoneg doesn't 669dee1ad47SJeff Kirsher * interfere with test result */ 670dee1ad47SJeff Kirsher if (ixgbevf_link_test(adapter, &data[1])) 671dee1ad47SJeff Kirsher eth_test->flags |= ETH_TEST_FL_FAILED; 672dee1ad47SJeff Kirsher 673dee1ad47SJeff Kirsher if (if_running) 674dee1ad47SJeff Kirsher /* indicate we're in test mode */ 675dee1ad47SJeff Kirsher dev_close(netdev); 676dee1ad47SJeff Kirsher else 677dee1ad47SJeff Kirsher ixgbevf_reset(adapter); 678dee1ad47SJeff Kirsher 679dee1ad47SJeff Kirsher hw_dbg(&adapter->hw, "register testing starting\n"); 680dee1ad47SJeff Kirsher if (ixgbevf_reg_test(adapter, &data[0])) 681dee1ad47SJeff Kirsher eth_test->flags |= ETH_TEST_FL_FAILED; 682dee1ad47SJeff Kirsher 683dee1ad47SJeff Kirsher ixgbevf_reset(adapter); 684dee1ad47SJeff Kirsher 685dee1ad47SJeff Kirsher clear_bit(__IXGBEVF_TESTING, &adapter->state); 686dee1ad47SJeff Kirsher if (if_running) 687dee1ad47SJeff Kirsher dev_open(netdev); 688dee1ad47SJeff Kirsher } else { 689dee1ad47SJeff Kirsher hw_dbg(&adapter->hw, "online testing starting\n"); 690dee1ad47SJeff Kirsher /* Online tests */ 691dee1ad47SJeff Kirsher if (ixgbevf_link_test(adapter, &data[1])) 692dee1ad47SJeff Kirsher eth_test->flags |= ETH_TEST_FL_FAILED; 693dee1ad47SJeff Kirsher 694dee1ad47SJeff Kirsher /* Online tests aren't run; pass by default */ 695dee1ad47SJeff Kirsher data[0] = 0; 696dee1ad47SJeff Kirsher 697dee1ad47SJeff Kirsher clear_bit(__IXGBEVF_TESTING, &adapter->state); 698dee1ad47SJeff Kirsher } 699dee1ad47SJeff Kirsher msleep_interruptible(4 * 1000); 700dee1ad47SJeff Kirsher } 701dee1ad47SJeff Kirsher 702dee1ad47SJeff Kirsher static int ixgbevf_nway_reset(struct net_device *netdev) 703dee1ad47SJeff Kirsher { 704dee1ad47SJeff Kirsher struct ixgbevf_adapter *adapter = netdev_priv(netdev); 705dee1ad47SJeff Kirsher 706dee1ad47SJeff Kirsher if (netif_running(netdev)) { 707dee1ad47SJeff Kirsher if (!adapter->dev_closed) 708dee1ad47SJeff Kirsher ixgbevf_reinit_locked(adapter); 709dee1ad47SJeff Kirsher } 710dee1ad47SJeff Kirsher 711dee1ad47SJeff Kirsher return 0; 712dee1ad47SJeff Kirsher } 713dee1ad47SJeff Kirsher 714dee1ad47SJeff Kirsher static struct ethtool_ops ixgbevf_ethtool_ops = { 715dee1ad47SJeff Kirsher .get_settings = ixgbevf_get_settings, 716dee1ad47SJeff Kirsher .get_drvinfo = ixgbevf_get_drvinfo, 717dee1ad47SJeff Kirsher .get_regs_len = ixgbevf_get_regs_len, 718dee1ad47SJeff Kirsher .get_regs = ixgbevf_get_regs, 719dee1ad47SJeff Kirsher .nway_reset = ixgbevf_nway_reset, 720dee1ad47SJeff Kirsher .get_link = ethtool_op_get_link, 721dee1ad47SJeff Kirsher .get_ringparam = ixgbevf_get_ringparam, 722dee1ad47SJeff Kirsher .set_ringparam = ixgbevf_set_ringparam, 723dee1ad47SJeff Kirsher .get_rx_csum = ixgbevf_get_rx_csum, 724dee1ad47SJeff Kirsher .set_rx_csum = ixgbevf_set_rx_csum, 725dee1ad47SJeff Kirsher .get_tx_csum = ethtool_op_get_tx_csum, 726dee1ad47SJeff Kirsher .set_tx_csum = ethtool_op_set_tx_ipv6_csum, 727dee1ad47SJeff Kirsher .get_sg = ethtool_op_get_sg, 728dee1ad47SJeff Kirsher .set_sg = ethtool_op_set_sg, 729dee1ad47SJeff Kirsher .get_msglevel = ixgbevf_get_msglevel, 730dee1ad47SJeff Kirsher .set_msglevel = ixgbevf_set_msglevel, 731dee1ad47SJeff Kirsher .get_tso = ethtool_op_get_tso, 732dee1ad47SJeff Kirsher .set_tso = ixgbevf_set_tso, 733dee1ad47SJeff Kirsher .self_test = ixgbevf_diag_test, 734dee1ad47SJeff Kirsher .get_sset_count = ixgbevf_get_sset_count, 735dee1ad47SJeff Kirsher .get_strings = ixgbevf_get_strings, 736dee1ad47SJeff Kirsher .get_ethtool_stats = ixgbevf_get_ethtool_stats, 737dee1ad47SJeff Kirsher }; 738dee1ad47SJeff Kirsher 739dee1ad47SJeff Kirsher void ixgbevf_set_ethtool_ops(struct net_device *netdev) 740dee1ad47SJeff Kirsher { 741dee1ad47SJeff Kirsher SET_ETHTOOL_OPS(netdev, &ixgbevf_ethtool_ops); 742dee1ad47SJeff Kirsher } 743