root/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. xgbe_get_strings
  2. xgbe_get_ethtool_stats
  3. xgbe_get_sset_count
  4. xgbe_get_pauseparam
  5. xgbe_set_pauseparam
  6. xgbe_get_link_ksettings
  7. xgbe_set_link_ksettings
  8. xgbe_get_drvinfo
  9. xgbe_get_msglevel
  10. xgbe_set_msglevel
  11. xgbe_get_coalesce
  12. xgbe_set_coalesce
  13. xgbe_get_rxnfc
  14. xgbe_get_rxfh_key_size
  15. xgbe_get_rxfh_indir_size
  16. xgbe_get_rxfh
  17. xgbe_set_rxfh
  18. xgbe_get_ts_info
  19. xgbe_get_module_info
  20. xgbe_get_module_eeprom
  21. xgbe_get_ringparam
  22. xgbe_set_ringparam
  23. xgbe_get_channels
  24. xgbe_print_set_channels_input
  25. xgbe_set_channels
  26. xgbe_get_ethtool_ops

   1 /*
   2  * AMD 10Gb Ethernet driver
   3  *
   4  * This file is available to you under your choice of the following two
   5  * licenses:
   6  *
   7  * License 1: GPLv2
   8  *
   9  * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
  10  *
  11  * This file is free software; you may copy, redistribute and/or modify
  12  * it under the terms of the GNU General Public License as published by
  13  * the Free Software Foundation, either version 2 of the License, or (at
  14  * your option) any later version.
  15  *
  16  * This file is distributed in the hope that it will be useful, but
  17  * WITHOUT ANY WARRANTY; without even the implied warranty of
  18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19  * General Public License for more details.
  20  *
  21  * You should have received a copy of the GNU General Public License
  22  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  23  *
  24  * This file incorporates work covered by the following copyright and
  25  * permission notice:
  26  *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
  27  *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
  28  *     Inc. unless otherwise expressly agreed to in writing between Synopsys
  29  *     and you.
  30  *
  31  *     The Software IS NOT an item of Licensed Software or Licensed Product
  32  *     under any End User Software License Agreement or Agreement for Licensed
  33  *     Product with Synopsys or any supplement thereto.  Permission is hereby
  34  *     granted, free of charge, to any person obtaining a copy of this software
  35  *     annotated with this license and the Software, to deal in the Software
  36  *     without restriction, including without limitation the rights to use,
  37  *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  38  *     of the Software, and to permit persons to whom the Software is furnished
  39  *     to do so, subject to the following conditions:
  40  *
  41  *     The above copyright notice and this permission notice shall be included
  42  *     in all copies or substantial portions of the Software.
  43  *
  44  *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
  45  *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  46  *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  47  *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
  48  *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  49  *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  50  *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  51  *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  52  *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  53  *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  54  *     THE POSSIBILITY OF SUCH DAMAGE.
  55  *
  56  *
  57  * License 2: Modified BSD
  58  *
  59  * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
  60  * All rights reserved.
  61  *
  62  * Redistribution and use in source and binary forms, with or without
  63  * modification, are permitted provided that the following conditions are met:
  64  *     * Redistributions of source code must retain the above copyright
  65  *       notice, this list of conditions and the following disclaimer.
  66  *     * Redistributions in binary form must reproduce the above copyright
  67  *       notice, this list of conditions and the following disclaimer in the
  68  *       documentation and/or other materials provided with the distribution.
  69  *     * Neither the name of Advanced Micro Devices, Inc. nor the
  70  *       names of its contributors may be used to endorse or promote products
  71  *       derived from this software without specific prior written permission.
  72  *
  73  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  74  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  75  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  76  * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  77  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  78  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  79  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  80  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  81  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  82  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  83  *
  84  * This file incorporates work covered by the following copyright and
  85  * permission notice:
  86  *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
  87  *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
  88  *     Inc. unless otherwise expressly agreed to in writing between Synopsys
  89  *     and you.
  90  *
  91  *     The Software IS NOT an item of Licensed Software or Licensed Product
  92  *     under any End User Software License Agreement or Agreement for Licensed
  93  *     Product with Synopsys or any supplement thereto.  Permission is hereby
  94  *     granted, free of charge, to any person obtaining a copy of this software
  95  *     annotated with this license and the Software, to deal in the Software
  96  *     without restriction, including without limitation the rights to use,
  97  *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  98  *     of the Software, and to permit persons to whom the Software is furnished
  99  *     to do so, subject to the following conditions:
 100  *
 101  *     The above copyright notice and this permission notice shall be included
 102  *     in all copies or substantial portions of the Software.
 103  *
 104  *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
 105  *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 106  *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 107  *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
 108  *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 109  *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 110  *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 111  *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 112  *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 113  *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 114  *     THE POSSIBILITY OF SUCH DAMAGE.
 115  */
 116 
 117 #include <linux/spinlock.h>
 118 #include <linux/phy.h>
 119 #include <linux/net_tstamp.h>
 120 
 121 #include "xgbe.h"
 122 #include "xgbe-common.h"
 123 
 124 struct xgbe_stats {
 125         char stat_string[ETH_GSTRING_LEN];
 126         int stat_size;
 127         int stat_offset;
 128 };
 129 
 130 #define XGMAC_MMC_STAT(_string, _var)                           \
 131         { _string,                                              \
 132           FIELD_SIZEOF(struct xgbe_mmc_stats, _var),            \
 133           offsetof(struct xgbe_prv_data, mmc_stats._var),       \
 134         }
 135 
 136 #define XGMAC_EXT_STAT(_string, _var)                           \
 137         { _string,                                              \
 138           FIELD_SIZEOF(struct xgbe_ext_stats, _var),            \
 139           offsetof(struct xgbe_prv_data, ext_stats._var),       \
 140         }
 141 
 142 static const struct xgbe_stats xgbe_gstring_stats[] = {
 143         XGMAC_MMC_STAT("tx_bytes", txoctetcount_gb),
 144         XGMAC_MMC_STAT("tx_packets", txframecount_gb),
 145         XGMAC_MMC_STAT("tx_unicast_packets", txunicastframes_gb),
 146         XGMAC_MMC_STAT("tx_broadcast_packets", txbroadcastframes_gb),
 147         XGMAC_MMC_STAT("tx_multicast_packets", txmulticastframes_gb),
 148         XGMAC_MMC_STAT("tx_vlan_packets", txvlanframes_g),
 149         XGMAC_EXT_STAT("tx_vxlan_packets", tx_vxlan_packets),
 150         XGMAC_EXT_STAT("tx_tso_packets", tx_tso_packets),
 151         XGMAC_MMC_STAT("tx_64_byte_packets", tx64octets_gb),
 152         XGMAC_MMC_STAT("tx_65_to_127_byte_packets", tx65to127octets_gb),
 153         XGMAC_MMC_STAT("tx_128_to_255_byte_packets", tx128to255octets_gb),
 154         XGMAC_MMC_STAT("tx_256_to_511_byte_packets", tx256to511octets_gb),
 155         XGMAC_MMC_STAT("tx_512_to_1023_byte_packets", tx512to1023octets_gb),
 156         XGMAC_MMC_STAT("tx_1024_to_max_byte_packets", tx1024tomaxoctets_gb),
 157         XGMAC_MMC_STAT("tx_underflow_errors", txunderflowerror),
 158         XGMAC_MMC_STAT("tx_pause_frames", txpauseframes),
 159 
 160         XGMAC_MMC_STAT("rx_bytes", rxoctetcount_gb),
 161         XGMAC_MMC_STAT("rx_packets", rxframecount_gb),
 162         XGMAC_MMC_STAT("rx_unicast_packets", rxunicastframes_g),
 163         XGMAC_MMC_STAT("rx_broadcast_packets", rxbroadcastframes_g),
 164         XGMAC_MMC_STAT("rx_multicast_packets", rxmulticastframes_g),
 165         XGMAC_MMC_STAT("rx_vlan_packets", rxvlanframes_gb),
 166         XGMAC_EXT_STAT("rx_vxlan_packets", rx_vxlan_packets),
 167         XGMAC_MMC_STAT("rx_64_byte_packets", rx64octets_gb),
 168         XGMAC_MMC_STAT("rx_65_to_127_byte_packets", rx65to127octets_gb),
 169         XGMAC_MMC_STAT("rx_128_to_255_byte_packets", rx128to255octets_gb),
 170         XGMAC_MMC_STAT("rx_256_to_511_byte_packets", rx256to511octets_gb),
 171         XGMAC_MMC_STAT("rx_512_to_1023_byte_packets", rx512to1023octets_gb),
 172         XGMAC_MMC_STAT("rx_1024_to_max_byte_packets", rx1024tomaxoctets_gb),
 173         XGMAC_MMC_STAT("rx_undersize_packets", rxundersize_g),
 174         XGMAC_MMC_STAT("rx_oversize_packets", rxoversize_g),
 175         XGMAC_MMC_STAT("rx_crc_errors", rxcrcerror),
 176         XGMAC_MMC_STAT("rx_crc_errors_small_packets", rxrunterror),
 177         XGMAC_MMC_STAT("rx_crc_errors_giant_packets", rxjabbererror),
 178         XGMAC_MMC_STAT("rx_length_errors", rxlengtherror),
 179         XGMAC_MMC_STAT("rx_out_of_range_errors", rxoutofrangetype),
 180         XGMAC_MMC_STAT("rx_fifo_overflow_errors", rxfifooverflow),
 181         XGMAC_MMC_STAT("rx_watchdog_errors", rxwatchdogerror),
 182         XGMAC_EXT_STAT("rx_csum_errors", rx_csum_errors),
 183         XGMAC_EXT_STAT("rx_vxlan_csum_errors", rx_vxlan_csum_errors),
 184         XGMAC_MMC_STAT("rx_pause_frames", rxpauseframes),
 185         XGMAC_EXT_STAT("rx_split_header_packets", rx_split_header_packets),
 186         XGMAC_EXT_STAT("rx_buffer_unavailable", rx_buffer_unavailable),
 187 };
 188 
 189 #define XGBE_STATS_COUNT        ARRAY_SIZE(xgbe_gstring_stats)
 190 
 191 static void xgbe_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
 192 {
 193         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 194         int i;
 195 
 196         switch (stringset) {
 197         case ETH_SS_STATS:
 198                 for (i = 0; i < XGBE_STATS_COUNT; i++) {
 199                         memcpy(data, xgbe_gstring_stats[i].stat_string,
 200                                ETH_GSTRING_LEN);
 201                         data += ETH_GSTRING_LEN;
 202                 }
 203                 for (i = 0; i < pdata->tx_ring_count; i++) {
 204                         sprintf(data, "txq_%u_packets", i);
 205                         data += ETH_GSTRING_LEN;
 206                         sprintf(data, "txq_%u_bytes", i);
 207                         data += ETH_GSTRING_LEN;
 208                 }
 209                 for (i = 0; i < pdata->rx_ring_count; i++) {
 210                         sprintf(data, "rxq_%u_packets", i);
 211                         data += ETH_GSTRING_LEN;
 212                         sprintf(data, "rxq_%u_bytes", i);
 213                         data += ETH_GSTRING_LEN;
 214                 }
 215                 break;
 216         }
 217 }
 218 
 219 static void xgbe_get_ethtool_stats(struct net_device *netdev,
 220                                    struct ethtool_stats *stats, u64 *data)
 221 {
 222         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 223         u8 *stat;
 224         int i;
 225 
 226         pdata->hw_if.read_mmc_stats(pdata);
 227         for (i = 0; i < XGBE_STATS_COUNT; i++) {
 228                 stat = (u8 *)pdata + xgbe_gstring_stats[i].stat_offset;
 229                 *data++ = *(u64 *)stat;
 230         }
 231         for (i = 0; i < pdata->tx_ring_count; i++) {
 232                 *data++ = pdata->ext_stats.txq_packets[i];
 233                 *data++ = pdata->ext_stats.txq_bytes[i];
 234         }
 235         for (i = 0; i < pdata->rx_ring_count; i++) {
 236                 *data++ = pdata->ext_stats.rxq_packets[i];
 237                 *data++ = pdata->ext_stats.rxq_bytes[i];
 238         }
 239 }
 240 
 241 static int xgbe_get_sset_count(struct net_device *netdev, int stringset)
 242 {
 243         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 244         int ret;
 245 
 246         switch (stringset) {
 247         case ETH_SS_STATS:
 248                 ret = XGBE_STATS_COUNT +
 249                       (pdata->tx_ring_count * 2) +
 250                       (pdata->rx_ring_count * 2);
 251                 break;
 252 
 253         default:
 254                 ret = -EOPNOTSUPP;
 255         }
 256 
 257         return ret;
 258 }
 259 
 260 static void xgbe_get_pauseparam(struct net_device *netdev,
 261                                 struct ethtool_pauseparam *pause)
 262 {
 263         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 264 
 265         pause->autoneg = pdata->phy.pause_autoneg;
 266         pause->tx_pause = pdata->phy.tx_pause;
 267         pause->rx_pause = pdata->phy.rx_pause;
 268 }
 269 
 270 static int xgbe_set_pauseparam(struct net_device *netdev,
 271                                struct ethtool_pauseparam *pause)
 272 {
 273         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 274         struct ethtool_link_ksettings *lks = &pdata->phy.lks;
 275         int ret = 0;
 276 
 277         if (pause->autoneg && (pdata->phy.autoneg != AUTONEG_ENABLE)) {
 278                 netdev_err(netdev,
 279                            "autoneg disabled, pause autoneg not available\n");
 280                 return -EINVAL;
 281         }
 282 
 283         pdata->phy.pause_autoneg = pause->autoneg;
 284         pdata->phy.tx_pause = pause->tx_pause;
 285         pdata->phy.rx_pause = pause->rx_pause;
 286 
 287         XGBE_CLR_ADV(lks, Pause);
 288         XGBE_CLR_ADV(lks, Asym_Pause);
 289 
 290         if (pause->rx_pause) {
 291                 XGBE_SET_ADV(lks, Pause);
 292                 XGBE_SET_ADV(lks, Asym_Pause);
 293         }
 294 
 295         if (pause->tx_pause) {
 296                 /* Equivalent to XOR of Asym_Pause */
 297                 if (XGBE_ADV(lks, Asym_Pause))
 298                         XGBE_CLR_ADV(lks, Asym_Pause);
 299                 else
 300                         XGBE_SET_ADV(lks, Asym_Pause);
 301         }
 302 
 303         if (netif_running(netdev))
 304                 ret = pdata->phy_if.phy_config_aneg(pdata);
 305 
 306         return ret;
 307 }
 308 
 309 static int xgbe_get_link_ksettings(struct net_device *netdev,
 310                                    struct ethtool_link_ksettings *cmd)
 311 {
 312         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 313         struct ethtool_link_ksettings *lks = &pdata->phy.lks;
 314 
 315         cmd->base.phy_address = pdata->phy.address;
 316 
 317         cmd->base.autoneg = pdata->phy.autoneg;
 318         cmd->base.speed = pdata->phy.speed;
 319         cmd->base.duplex = pdata->phy.duplex;
 320 
 321         cmd->base.port = PORT_NONE;
 322 
 323         XGBE_LM_COPY(cmd, supported, lks, supported);
 324         XGBE_LM_COPY(cmd, advertising, lks, advertising);
 325         XGBE_LM_COPY(cmd, lp_advertising, lks, lp_advertising);
 326 
 327         return 0;
 328 }
 329 
 330 static int xgbe_set_link_ksettings(struct net_device *netdev,
 331                                    const struct ethtool_link_ksettings *cmd)
 332 {
 333         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 334         struct ethtool_link_ksettings *lks = &pdata->phy.lks;
 335         __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
 336         u32 speed;
 337         int ret;
 338 
 339         speed = cmd->base.speed;
 340 
 341         if (cmd->base.phy_address != pdata->phy.address) {
 342                 netdev_err(netdev, "invalid phy address %hhu\n",
 343                            cmd->base.phy_address);
 344                 return -EINVAL;
 345         }
 346 
 347         if ((cmd->base.autoneg != AUTONEG_ENABLE) &&
 348             (cmd->base.autoneg != AUTONEG_DISABLE)) {
 349                 netdev_err(netdev, "unsupported autoneg %hhu\n",
 350                            cmd->base.autoneg);
 351                 return -EINVAL;
 352         }
 353 
 354         if (cmd->base.autoneg == AUTONEG_DISABLE) {
 355                 if (!pdata->phy_if.phy_valid_speed(pdata, speed)) {
 356                         netdev_err(netdev, "unsupported speed %u\n", speed);
 357                         return -EINVAL;
 358                 }
 359 
 360                 if (cmd->base.duplex != DUPLEX_FULL) {
 361                         netdev_err(netdev, "unsupported duplex %hhu\n",
 362                                    cmd->base.duplex);
 363                         return -EINVAL;
 364                 }
 365         }
 366 
 367         netif_dbg(pdata, link, netdev,
 368                   "requested advertisement 0x%*pb, phy supported 0x%*pb\n",
 369                   __ETHTOOL_LINK_MODE_MASK_NBITS, cmd->link_modes.advertising,
 370                   __ETHTOOL_LINK_MODE_MASK_NBITS, lks->link_modes.supported);
 371 
 372         bitmap_and(advertising,
 373                    cmd->link_modes.advertising, lks->link_modes.supported,
 374                    __ETHTOOL_LINK_MODE_MASK_NBITS);
 375 
 376         if ((cmd->base.autoneg == AUTONEG_ENABLE) &&
 377             bitmap_empty(advertising, __ETHTOOL_LINK_MODE_MASK_NBITS)) {
 378                 netdev_err(netdev,
 379                            "unsupported requested advertisement\n");
 380                 return -EINVAL;
 381         }
 382 
 383         ret = 0;
 384         pdata->phy.autoneg = cmd->base.autoneg;
 385         pdata->phy.speed = speed;
 386         pdata->phy.duplex = cmd->base.duplex;
 387         bitmap_copy(lks->link_modes.advertising, advertising,
 388                     __ETHTOOL_LINK_MODE_MASK_NBITS);
 389 
 390         if (cmd->base.autoneg == AUTONEG_ENABLE)
 391                 XGBE_SET_ADV(lks, Autoneg);
 392         else
 393                 XGBE_CLR_ADV(lks, Autoneg);
 394 
 395         if (netif_running(netdev))
 396                 ret = pdata->phy_if.phy_config_aneg(pdata);
 397 
 398         return ret;
 399 }
 400 
 401 static void xgbe_get_drvinfo(struct net_device *netdev,
 402                              struct ethtool_drvinfo *drvinfo)
 403 {
 404         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 405         struct xgbe_hw_features *hw_feat = &pdata->hw_feat;
 406 
 407         strlcpy(drvinfo->driver, XGBE_DRV_NAME, sizeof(drvinfo->driver));
 408         strlcpy(drvinfo->version, XGBE_DRV_VERSION, sizeof(drvinfo->version));
 409         strlcpy(drvinfo->bus_info, dev_name(pdata->dev),
 410                 sizeof(drvinfo->bus_info));
 411         snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), "%d.%d.%d",
 412                  XGMAC_GET_BITS(hw_feat->version, MAC_VR, USERVER),
 413                  XGMAC_GET_BITS(hw_feat->version, MAC_VR, DEVID),
 414                  XGMAC_GET_BITS(hw_feat->version, MAC_VR, SNPSVER));
 415 }
 416 
 417 static u32 xgbe_get_msglevel(struct net_device *netdev)
 418 {
 419         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 420 
 421         return pdata->msg_enable;
 422 }
 423 
 424 static void xgbe_set_msglevel(struct net_device *netdev, u32 msglevel)
 425 {
 426         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 427 
 428         pdata->msg_enable = msglevel;
 429 }
 430 
 431 static int xgbe_get_coalesce(struct net_device *netdev,
 432                              struct ethtool_coalesce *ec)
 433 {
 434         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 435 
 436         memset(ec, 0, sizeof(struct ethtool_coalesce));
 437 
 438         ec->rx_coalesce_usecs = pdata->rx_usecs;
 439         ec->rx_max_coalesced_frames = pdata->rx_frames;
 440 
 441         ec->tx_max_coalesced_frames = pdata->tx_frames;
 442 
 443         return 0;
 444 }
 445 
 446 static int xgbe_set_coalesce(struct net_device *netdev,
 447                              struct ethtool_coalesce *ec)
 448 {
 449         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 450         struct xgbe_hw_if *hw_if = &pdata->hw_if;
 451         unsigned int rx_frames, rx_riwt, rx_usecs;
 452         unsigned int tx_frames;
 453 
 454         /* Check for not supported parameters  */
 455         if ((ec->rx_coalesce_usecs_irq) ||
 456             (ec->rx_max_coalesced_frames_irq) ||
 457             (ec->tx_coalesce_usecs) ||
 458             (ec->tx_coalesce_usecs_irq) ||
 459             (ec->tx_max_coalesced_frames_irq) ||
 460             (ec->stats_block_coalesce_usecs) ||
 461             (ec->use_adaptive_rx_coalesce) ||
 462             (ec->use_adaptive_tx_coalesce) ||
 463             (ec->pkt_rate_low) ||
 464             (ec->rx_coalesce_usecs_low) ||
 465             (ec->rx_max_coalesced_frames_low) ||
 466             (ec->tx_coalesce_usecs_low) ||
 467             (ec->tx_max_coalesced_frames_low) ||
 468             (ec->pkt_rate_high) ||
 469             (ec->rx_coalesce_usecs_high) ||
 470             (ec->rx_max_coalesced_frames_high) ||
 471             (ec->tx_coalesce_usecs_high) ||
 472             (ec->tx_max_coalesced_frames_high) ||
 473             (ec->rate_sample_interval)) {
 474                 netdev_err(netdev, "unsupported coalescing parameter\n");
 475                 return -EOPNOTSUPP;
 476         }
 477 
 478         rx_riwt = hw_if->usec_to_riwt(pdata, ec->rx_coalesce_usecs);
 479         rx_usecs = ec->rx_coalesce_usecs;
 480         rx_frames = ec->rx_max_coalesced_frames;
 481 
 482         /* Use smallest possible value if conversion resulted in zero */
 483         if (rx_usecs && !rx_riwt)
 484                 rx_riwt = 1;
 485 
 486         /* Check the bounds of values for Rx */
 487         if (rx_riwt > XGMAC_MAX_DMA_RIWT) {
 488                 netdev_err(netdev, "rx-usec is limited to %d usecs\n",
 489                            hw_if->riwt_to_usec(pdata, XGMAC_MAX_DMA_RIWT));
 490                 return -EINVAL;
 491         }
 492         if (rx_frames > pdata->rx_desc_count) {
 493                 netdev_err(netdev, "rx-frames is limited to %d frames\n",
 494                            pdata->rx_desc_count);
 495                 return -EINVAL;
 496         }
 497 
 498         tx_frames = ec->tx_max_coalesced_frames;
 499 
 500         /* Check the bounds of values for Tx */
 501         if (tx_frames > pdata->tx_desc_count) {
 502                 netdev_err(netdev, "tx-frames is limited to %d frames\n",
 503                            pdata->tx_desc_count);
 504                 return -EINVAL;
 505         }
 506 
 507         pdata->rx_riwt = rx_riwt;
 508         pdata->rx_usecs = rx_usecs;
 509         pdata->rx_frames = rx_frames;
 510         hw_if->config_rx_coalesce(pdata);
 511 
 512         pdata->tx_frames = tx_frames;
 513         hw_if->config_tx_coalesce(pdata);
 514 
 515         return 0;
 516 }
 517 
 518 static int xgbe_get_rxnfc(struct net_device *netdev,
 519                           struct ethtool_rxnfc *rxnfc, u32 *rule_locs)
 520 {
 521         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 522 
 523         switch (rxnfc->cmd) {
 524         case ETHTOOL_GRXRINGS:
 525                 rxnfc->data = pdata->rx_ring_count;
 526                 break;
 527         default:
 528                 return -EOPNOTSUPP;
 529         }
 530 
 531         return 0;
 532 }
 533 
 534 static u32 xgbe_get_rxfh_key_size(struct net_device *netdev)
 535 {
 536         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 537 
 538         return sizeof(pdata->rss_key);
 539 }
 540 
 541 static u32 xgbe_get_rxfh_indir_size(struct net_device *netdev)
 542 {
 543         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 544 
 545         return ARRAY_SIZE(pdata->rss_table);
 546 }
 547 
 548 static int xgbe_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
 549                          u8 *hfunc)
 550 {
 551         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 552         unsigned int i;
 553 
 554         if (indir) {
 555                 for (i = 0; i < ARRAY_SIZE(pdata->rss_table); i++)
 556                         indir[i] = XGMAC_GET_BITS(pdata->rss_table[i],
 557                                                   MAC_RSSDR, DMCH);
 558         }
 559 
 560         if (key)
 561                 memcpy(key, pdata->rss_key, sizeof(pdata->rss_key));
 562 
 563         if (hfunc)
 564                 *hfunc = ETH_RSS_HASH_TOP;
 565 
 566         return 0;
 567 }
 568 
 569 static int xgbe_set_rxfh(struct net_device *netdev, const u32 *indir,
 570                          const u8 *key, const u8 hfunc)
 571 {
 572         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 573         struct xgbe_hw_if *hw_if = &pdata->hw_if;
 574         unsigned int ret;
 575 
 576         if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) {
 577                 netdev_err(netdev, "unsupported hash function\n");
 578                 return -EOPNOTSUPP;
 579         }
 580 
 581         if (indir) {
 582                 ret = hw_if->set_rss_lookup_table(pdata, indir);
 583                 if (ret)
 584                         return ret;
 585         }
 586 
 587         if (key) {
 588                 ret = hw_if->set_rss_hash_key(pdata, key);
 589                 if (ret)
 590                         return ret;
 591         }
 592 
 593         return 0;
 594 }
 595 
 596 static int xgbe_get_ts_info(struct net_device *netdev,
 597                             struct ethtool_ts_info *ts_info)
 598 {
 599         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 600 
 601         ts_info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
 602                                    SOF_TIMESTAMPING_RX_SOFTWARE |
 603                                    SOF_TIMESTAMPING_SOFTWARE |
 604                                    SOF_TIMESTAMPING_TX_HARDWARE |
 605                                    SOF_TIMESTAMPING_RX_HARDWARE |
 606                                    SOF_TIMESTAMPING_RAW_HARDWARE;
 607 
 608         if (pdata->ptp_clock)
 609                 ts_info->phc_index = ptp_clock_index(pdata->ptp_clock);
 610         else
 611                 ts_info->phc_index = -1;
 612 
 613         ts_info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);
 614         ts_info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
 615                               (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |
 616                               (1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
 617                               (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
 618                               (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
 619                               (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
 620                               (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
 621                               (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
 622                               (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
 623                               (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) |
 624                               (1 << HWTSTAMP_FILTER_ALL);
 625 
 626         return 0;
 627 }
 628 
 629 static int xgbe_get_module_info(struct net_device *netdev,
 630                                 struct ethtool_modinfo *modinfo)
 631 {
 632         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 633 
 634         return pdata->phy_if.module_info(pdata, modinfo);
 635 }
 636 
 637 static int xgbe_get_module_eeprom(struct net_device *netdev,
 638                                   struct ethtool_eeprom *eeprom, u8 *data)
 639 {
 640         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 641 
 642         return pdata->phy_if.module_eeprom(pdata, eeprom, data);
 643 }
 644 
 645 static void xgbe_get_ringparam(struct net_device *netdev,
 646                                struct ethtool_ringparam *ringparam)
 647 {
 648         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 649 
 650         ringparam->rx_max_pending = XGBE_RX_DESC_CNT_MAX;
 651         ringparam->tx_max_pending = XGBE_TX_DESC_CNT_MAX;
 652         ringparam->rx_pending = pdata->rx_desc_count;
 653         ringparam->tx_pending = pdata->tx_desc_count;
 654 }
 655 
 656 static int xgbe_set_ringparam(struct net_device *netdev,
 657                               struct ethtool_ringparam *ringparam)
 658 {
 659         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 660         unsigned int rx, tx;
 661 
 662         if (ringparam->rx_mini_pending || ringparam->rx_jumbo_pending) {
 663                 netdev_err(netdev, "unsupported ring parameter\n");
 664                 return -EINVAL;
 665         }
 666 
 667         if ((ringparam->rx_pending < XGBE_RX_DESC_CNT_MIN) ||
 668             (ringparam->rx_pending > XGBE_RX_DESC_CNT_MAX)) {
 669                 netdev_err(netdev,
 670                            "rx ring parameter must be between %u and %u\n",
 671                            XGBE_RX_DESC_CNT_MIN, XGBE_RX_DESC_CNT_MAX);
 672                 return -EINVAL;
 673         }
 674 
 675         if ((ringparam->tx_pending < XGBE_TX_DESC_CNT_MIN) ||
 676             (ringparam->tx_pending > XGBE_TX_DESC_CNT_MAX)) {
 677                 netdev_err(netdev,
 678                            "tx ring parameter must be between %u and %u\n",
 679                            XGBE_TX_DESC_CNT_MIN, XGBE_TX_DESC_CNT_MAX);
 680                 return -EINVAL;
 681         }
 682 
 683         rx = __rounddown_pow_of_two(ringparam->rx_pending);
 684         if (rx != ringparam->rx_pending)
 685                 netdev_notice(netdev,
 686                               "rx ring parameter rounded to power of two: %u\n",
 687                               rx);
 688 
 689         tx = __rounddown_pow_of_two(ringparam->tx_pending);
 690         if (tx != ringparam->tx_pending)
 691                 netdev_notice(netdev,
 692                               "tx ring parameter rounded to power of two: %u\n",
 693                               tx);
 694 
 695         if ((rx == pdata->rx_desc_count) &&
 696             (tx == pdata->tx_desc_count))
 697                 goto out;
 698 
 699         pdata->rx_desc_count = rx;
 700         pdata->tx_desc_count = tx;
 701 
 702         xgbe_restart_dev(pdata);
 703 
 704 out:
 705         return 0;
 706 }
 707 
 708 static void xgbe_get_channels(struct net_device *netdev,
 709                               struct ethtool_channels *channels)
 710 {
 711         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 712         unsigned int rx, tx, combined;
 713 
 714         /* Calculate maximums allowed:
 715          *   - Take into account the number of available IRQs
 716          *   - Do not take into account the number of online CPUs so that
 717          *     the user can over-subscribe if desired
 718          *   - Tx is additionally limited by the number of hardware queues
 719          */
 720         rx = min(pdata->hw_feat.rx_ch_cnt, pdata->rx_max_channel_count);
 721         rx = min(rx, pdata->channel_irq_count);
 722         tx = min(pdata->hw_feat.tx_ch_cnt, pdata->tx_max_channel_count);
 723         tx = min(tx, pdata->channel_irq_count);
 724         tx = min(tx, pdata->tx_max_q_count);
 725 
 726         combined = min(rx, tx);
 727 
 728         channels->max_combined = combined;
 729         channels->max_rx = rx ? rx - 1 : 0;
 730         channels->max_tx = tx ? tx - 1 : 0;
 731 
 732         /* Get current settings based on device state */
 733         rx = pdata->new_rx_ring_count ? : pdata->rx_ring_count;
 734         tx = pdata->new_tx_ring_count ? : pdata->tx_ring_count;
 735 
 736         combined = min(rx, tx);
 737         rx -= combined;
 738         tx -= combined;
 739 
 740         channels->combined_count = combined;
 741         channels->rx_count = rx;
 742         channels->tx_count = tx;
 743 }
 744 
 745 static void xgbe_print_set_channels_input(struct net_device *netdev,
 746                                           struct ethtool_channels *channels)
 747 {
 748         netdev_err(netdev, "channel inputs: combined=%u, rx-only=%u, tx-only=%u\n",
 749                    channels->combined_count, channels->rx_count,
 750                    channels->tx_count);
 751 }
 752 
 753 static int xgbe_set_channels(struct net_device *netdev,
 754                              struct ethtool_channels *channels)
 755 {
 756         struct xgbe_prv_data *pdata = netdev_priv(netdev);
 757         unsigned int rx, rx_curr, tx, tx_curr, combined;
 758 
 759         /* Calculate maximums allowed:
 760          *   - Take into account the number of available IRQs
 761          *   - Do not take into account the number of online CPUs so that
 762          *     the user can over-subscribe if desired
 763          *   - Tx is additionally limited by the number of hardware queues
 764          */
 765         rx = min(pdata->hw_feat.rx_ch_cnt, pdata->rx_max_channel_count);
 766         rx = min(rx, pdata->channel_irq_count);
 767         tx = min(pdata->hw_feat.tx_ch_cnt, pdata->tx_max_channel_count);
 768         tx = min(tx, pdata->tx_max_q_count);
 769         tx = min(tx, pdata->channel_irq_count);
 770 
 771         combined = min(rx, tx);
 772 
 773         /* Should not be setting other count */
 774         if (channels->other_count) {
 775                 netdev_err(netdev,
 776                            "other channel count must be zero\n");
 777                 return -EINVAL;
 778         }
 779 
 780         /* Require at least one Combined (Rx and Tx) channel */
 781         if (!channels->combined_count) {
 782                 netdev_err(netdev,
 783                            "at least one combined Rx/Tx channel is required\n");
 784                 xgbe_print_set_channels_input(netdev, channels);
 785                 return -EINVAL;
 786         }
 787 
 788         /* Check combined channels */
 789         if (channels->combined_count > combined) {
 790                 netdev_err(netdev,
 791                            "combined channel count cannot exceed %u\n",
 792                            combined);
 793                 xgbe_print_set_channels_input(netdev, channels);
 794                 return -EINVAL;
 795         }
 796 
 797         /* Can have some Rx-only or Tx-only channels, but not both */
 798         if (channels->rx_count && channels->tx_count) {
 799                 netdev_err(netdev,
 800                            "cannot specify both Rx-only and Tx-only channels\n");
 801                 xgbe_print_set_channels_input(netdev, channels);
 802                 return -EINVAL;
 803         }
 804 
 805         /* Check that we don't exceed the maximum number of channels */
 806         if ((channels->combined_count + channels->rx_count) > rx) {
 807                 netdev_err(netdev,
 808                            "total Rx channels (%u) requested exceeds maximum available (%u)\n",
 809                            channels->combined_count + channels->rx_count, rx);
 810                 xgbe_print_set_channels_input(netdev, channels);
 811                 return -EINVAL;
 812         }
 813 
 814         if ((channels->combined_count + channels->tx_count) > tx) {
 815                 netdev_err(netdev,
 816                            "total Tx channels (%u) requested exceeds maximum available (%u)\n",
 817                            channels->combined_count + channels->tx_count, tx);
 818                 xgbe_print_set_channels_input(netdev, channels);
 819                 return -EINVAL;
 820         }
 821 
 822         rx = channels->combined_count + channels->rx_count;
 823         tx = channels->combined_count + channels->tx_count;
 824 
 825         rx_curr = pdata->new_rx_ring_count ? : pdata->rx_ring_count;
 826         tx_curr = pdata->new_tx_ring_count ? : pdata->tx_ring_count;
 827 
 828         if ((rx == rx_curr) && (tx == tx_curr))
 829                 goto out;
 830 
 831         pdata->new_rx_ring_count = rx;
 832         pdata->new_tx_ring_count = tx;
 833 
 834         xgbe_full_restart_dev(pdata);
 835 
 836 out:
 837         return 0;
 838 }
 839 
 840 static const struct ethtool_ops xgbe_ethtool_ops = {
 841         .get_drvinfo = xgbe_get_drvinfo,
 842         .get_msglevel = xgbe_get_msglevel,
 843         .set_msglevel = xgbe_set_msglevel,
 844         .get_link = ethtool_op_get_link,
 845         .get_coalesce = xgbe_get_coalesce,
 846         .set_coalesce = xgbe_set_coalesce,
 847         .get_pauseparam = xgbe_get_pauseparam,
 848         .set_pauseparam = xgbe_set_pauseparam,
 849         .get_strings = xgbe_get_strings,
 850         .get_ethtool_stats = xgbe_get_ethtool_stats,
 851         .get_sset_count = xgbe_get_sset_count,
 852         .get_rxnfc = xgbe_get_rxnfc,
 853         .get_rxfh_key_size = xgbe_get_rxfh_key_size,
 854         .get_rxfh_indir_size = xgbe_get_rxfh_indir_size,
 855         .get_rxfh = xgbe_get_rxfh,
 856         .set_rxfh = xgbe_set_rxfh,
 857         .get_ts_info = xgbe_get_ts_info,
 858         .get_link_ksettings = xgbe_get_link_ksettings,
 859         .set_link_ksettings = xgbe_set_link_ksettings,
 860         .get_module_info = xgbe_get_module_info,
 861         .get_module_eeprom = xgbe_get_module_eeprom,
 862         .get_ringparam = xgbe_get_ringparam,
 863         .set_ringparam = xgbe_set_ringparam,
 864         .get_channels = xgbe_get_channels,
 865         .set_channels = xgbe_set_channels,
 866 };
 867 
 868 const struct ethtool_ops *xgbe_get_ethtool_ops(void)
 869 {
 870         return &xgbe_ethtool_ops;
 871 }

/* [<][>][^][v][top][bottom][index][help] */