root/drivers/net/ethernet/qualcomm/emac/emac-ethtool.c

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

DEFINITIONS

This source file includes following definitions.
  1. emac_get_msglevel
  2. emac_set_msglevel
  3. emac_get_sset_count
  4. emac_get_strings
  5. emac_get_ethtool_stats
  6. emac_nway_reset
  7. emac_get_ringparam
  8. emac_set_ringparam
  9. emac_get_pauseparam
  10. emac_set_pauseparam
  11. emac_get_regs
  12. emac_get_regs_len
  13. emac_set_priv_flags
  14. emac_get_priv_flags
  15. emac_set_ethtool_ops

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* Copyright (c) 2016, The Linux Foundation. All rights reserved.
   3  */
   4 
   5 #include <linux/ethtool.h>
   6 #include <linux/phy.h>
   7 
   8 #include "emac.h"
   9 
  10 static const char * const emac_ethtool_stat_strings[] = {
  11         "rx_ok",
  12         "rx_bcast",
  13         "rx_mcast",
  14         "rx_pause",
  15         "rx_ctrl",
  16         "rx_fcs_err",
  17         "rx_len_err",
  18         "rx_byte_cnt",
  19         "rx_runt",
  20         "rx_frag",
  21         "rx_sz_64",
  22         "rx_sz_65_127",
  23         "rx_sz_128_255",
  24         "rx_sz_256_511",
  25         "rx_sz_512_1023",
  26         "rx_sz_1024_1518",
  27         "rx_sz_1519_max",
  28         "rx_sz_ov",
  29         "rx_rxf_ov",
  30         "rx_align_err",
  31         "rx_bcast_byte_cnt",
  32         "rx_mcast_byte_cnt",
  33         "rx_err_addr",
  34         "rx_crc_align",
  35         "rx_jabbers",
  36         "tx_ok",
  37         "tx_bcast",
  38         "tx_mcast",
  39         "tx_pause",
  40         "tx_exc_defer",
  41         "tx_ctrl",
  42         "tx_defer",
  43         "tx_byte_cnt",
  44         "tx_sz_64",
  45         "tx_sz_65_127",
  46         "tx_sz_128_255",
  47         "tx_sz_256_511",
  48         "tx_sz_512_1023",
  49         "tx_sz_1024_1518",
  50         "tx_sz_1519_max",
  51         "tx_1_col",
  52         "tx_2_col",
  53         "tx_late_col",
  54         "tx_abort_col",
  55         "tx_underrun",
  56         "tx_rd_eop",
  57         "tx_len_err",
  58         "tx_trunc",
  59         "tx_bcast_byte",
  60         "tx_mcast_byte",
  61         "tx_col",
  62 };
  63 
  64 #define EMAC_STATS_LEN  ARRAY_SIZE(emac_ethtool_stat_strings)
  65 
  66 static u32 emac_get_msglevel(struct net_device *netdev)
  67 {
  68         struct emac_adapter *adpt = netdev_priv(netdev);
  69 
  70         return adpt->msg_enable;
  71 }
  72 
  73 static void emac_set_msglevel(struct net_device *netdev, u32 data)
  74 {
  75         struct emac_adapter *adpt = netdev_priv(netdev);
  76 
  77         adpt->msg_enable = data;
  78 }
  79 
  80 static int emac_get_sset_count(struct net_device *netdev, int sset)
  81 {
  82         switch (sset) {
  83         case ETH_SS_PRIV_FLAGS:
  84                 return 1;
  85         case ETH_SS_STATS:
  86                 return EMAC_STATS_LEN;
  87         default:
  88                 return -EOPNOTSUPP;
  89         }
  90 }
  91 
  92 static void emac_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
  93 {
  94         unsigned int i;
  95 
  96         switch (stringset) {
  97         case ETH_SS_PRIV_FLAGS:
  98                 strcpy(data, "single-pause-mode");
  99                 break;
 100 
 101         case ETH_SS_STATS:
 102                 for (i = 0; i < EMAC_STATS_LEN; i++) {
 103                         strlcpy(data, emac_ethtool_stat_strings[i],
 104                                 ETH_GSTRING_LEN);
 105                         data += ETH_GSTRING_LEN;
 106                 }
 107                 break;
 108         }
 109 }
 110 
 111 static void emac_get_ethtool_stats(struct net_device *netdev,
 112                                    struct ethtool_stats *stats,
 113                                    u64 *data)
 114 {
 115         struct emac_adapter *adpt = netdev_priv(netdev);
 116 
 117         spin_lock(&adpt->stats.lock);
 118 
 119         emac_update_hw_stats(adpt);
 120         memcpy(data, &adpt->stats, EMAC_STATS_LEN * sizeof(u64));
 121 
 122         spin_unlock(&adpt->stats.lock);
 123 }
 124 
 125 static int emac_nway_reset(struct net_device *netdev)
 126 {
 127         struct phy_device *phydev = netdev->phydev;
 128 
 129         if (!phydev)
 130                 return -ENODEV;
 131 
 132         return genphy_restart_aneg(phydev);
 133 }
 134 
 135 static void emac_get_ringparam(struct net_device *netdev,
 136                                struct ethtool_ringparam *ring)
 137 {
 138         struct emac_adapter *adpt = netdev_priv(netdev);
 139 
 140         ring->rx_max_pending = EMAC_MAX_RX_DESCS;
 141         ring->tx_max_pending = EMAC_MAX_TX_DESCS;
 142         ring->rx_pending = adpt->rx_desc_cnt;
 143         ring->tx_pending = adpt->tx_desc_cnt;
 144 }
 145 
 146 static int emac_set_ringparam(struct net_device *netdev,
 147                               struct ethtool_ringparam *ring)
 148 {
 149         struct emac_adapter *adpt = netdev_priv(netdev);
 150 
 151         /* We don't have separate queues/rings for small/large frames, so
 152          * reject any attempt to specify those values separately.
 153          */
 154         if (ring->rx_mini_pending || ring->rx_jumbo_pending)
 155                 return -EINVAL;
 156 
 157         adpt->tx_desc_cnt =
 158                 clamp_val(ring->tx_pending, EMAC_MIN_TX_DESCS, EMAC_MAX_TX_DESCS);
 159 
 160         adpt->rx_desc_cnt =
 161                 clamp_val(ring->rx_pending, EMAC_MIN_RX_DESCS, EMAC_MAX_RX_DESCS);
 162 
 163         if (netif_running(netdev))
 164                 return emac_reinit_locked(adpt);
 165 
 166         return 0;
 167 }
 168 
 169 static void emac_get_pauseparam(struct net_device *netdev,
 170                                 struct ethtool_pauseparam *pause)
 171 {
 172         struct emac_adapter *adpt = netdev_priv(netdev);
 173 
 174         pause->autoneg = adpt->automatic ? AUTONEG_ENABLE : AUTONEG_DISABLE;
 175         pause->rx_pause = adpt->rx_flow_control ? 1 : 0;
 176         pause->tx_pause = adpt->tx_flow_control ? 1 : 0;
 177 }
 178 
 179 static int emac_set_pauseparam(struct net_device *netdev,
 180                                struct ethtool_pauseparam *pause)
 181 {
 182         struct emac_adapter *adpt = netdev_priv(netdev);
 183 
 184         adpt->automatic = pause->autoneg == AUTONEG_ENABLE;
 185         adpt->rx_flow_control = pause->rx_pause != 0;
 186         adpt->tx_flow_control = pause->tx_pause != 0;
 187 
 188         if (netif_running(netdev))
 189                 return emac_reinit_locked(adpt);
 190 
 191         return 0;
 192 }
 193 
 194 /* Selected registers that might want to track during runtime. */
 195 static const u16 emac_regs[] = {
 196         EMAC_DMA_MAS_CTRL,
 197         EMAC_MAC_CTRL,
 198         EMAC_TXQ_CTRL_0,
 199         EMAC_RXQ_CTRL_0,
 200         EMAC_DMA_CTRL,
 201         EMAC_INT_MASK,
 202         EMAC_AXI_MAST_CTRL,
 203         EMAC_CORE_HW_VERSION,
 204         EMAC_MISC_CTRL,
 205 };
 206 
 207 /* Every time emac_regs[] above is changed, increase this version number. */
 208 #define EMAC_REGS_VERSION       0
 209 
 210 #define EMAC_MAX_REG_SIZE       ARRAY_SIZE(emac_regs)
 211 
 212 static void emac_get_regs(struct net_device *netdev,
 213                           struct ethtool_regs *regs, void *buff)
 214 {
 215         struct emac_adapter *adpt = netdev_priv(netdev);
 216         u32 *val = buff;
 217         unsigned int i;
 218 
 219         regs->version = EMAC_REGS_VERSION;
 220         regs->len = EMAC_MAX_REG_SIZE * sizeof(u32);
 221 
 222         for (i = 0; i < EMAC_MAX_REG_SIZE; i++)
 223                 val[i] = readl(adpt->base + emac_regs[i]);
 224 }
 225 
 226 static int emac_get_regs_len(struct net_device *netdev)
 227 {
 228         return EMAC_MAX_REG_SIZE * sizeof(u32);
 229 }
 230 
 231 #define EMAC_PRIV_ENABLE_SINGLE_PAUSE   BIT(0)
 232 
 233 static int emac_set_priv_flags(struct net_device *netdev, u32 flags)
 234 {
 235         struct emac_adapter *adpt = netdev_priv(netdev);
 236 
 237         adpt->single_pause_mode = !!(flags & EMAC_PRIV_ENABLE_SINGLE_PAUSE);
 238 
 239         if (netif_running(netdev))
 240                 return emac_reinit_locked(adpt);
 241 
 242         return 0;
 243 }
 244 
 245 static u32 emac_get_priv_flags(struct net_device *netdev)
 246 {
 247         struct emac_adapter *adpt = netdev_priv(netdev);
 248 
 249         return adpt->single_pause_mode ? EMAC_PRIV_ENABLE_SINGLE_PAUSE : 0;
 250 }
 251 
 252 static const struct ethtool_ops emac_ethtool_ops = {
 253         .get_link_ksettings = phy_ethtool_get_link_ksettings,
 254         .set_link_ksettings = phy_ethtool_set_link_ksettings,
 255 
 256         .get_msglevel    = emac_get_msglevel,
 257         .set_msglevel    = emac_set_msglevel,
 258 
 259         .get_sset_count  = emac_get_sset_count,
 260         .get_strings = emac_get_strings,
 261         .get_ethtool_stats = emac_get_ethtool_stats,
 262 
 263         .get_ringparam = emac_get_ringparam,
 264         .set_ringparam = emac_set_ringparam,
 265 
 266         .get_pauseparam = emac_get_pauseparam,
 267         .set_pauseparam = emac_set_pauseparam,
 268 
 269         .nway_reset = emac_nway_reset,
 270 
 271         .get_link = ethtool_op_get_link,
 272 
 273         .get_regs_len    = emac_get_regs_len,
 274         .get_regs        = emac_get_regs,
 275 
 276         .set_priv_flags = emac_set_priv_flags,
 277         .get_priv_flags = emac_get_priv_flags,
 278 };
 279 
 280 void emac_set_ethtool_ops(struct net_device *netdev)
 281 {
 282         netdev->ethtool_ops = &emac_ethtool_ops;
 283 }

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