root/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c

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

DEFINITIONS

This source file includes following definitions.
  1. ehea_get_link_ksettings
  2. ehea_set_link_ksettings
  3. ehea_nway_reset
  4. ehea_get_drvinfo
  5. ehea_get_msglevel
  6. ehea_set_msglevel
  7. ehea_get_strings
  8. ehea_get_sset_count
  9. ehea_get_ethtool_stats
  10. ehea_set_ethtool_ops

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  linux/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c
   4  *
   5  *  eHEA ethernet device driver for IBM eServer System p
   6  *
   7  *  (C) Copyright IBM Corp. 2006
   8  *
   9  *  Authors:
  10  *       Christoph Raisch <raisch@de.ibm.com>
  11  *       Jan-Bernd Themann <themann@de.ibm.com>
  12  *       Thomas Klein <tklein@de.ibm.com>
  13  */
  14 
  15 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  16 
  17 #include "ehea.h"
  18 #include "ehea_phyp.h"
  19 
  20 static int ehea_get_link_ksettings(struct net_device *dev,
  21                                    struct ethtool_link_ksettings *cmd)
  22 {
  23         struct ehea_port *port = netdev_priv(dev);
  24         u32 supported, advertising;
  25         u32 speed;
  26         int ret;
  27 
  28         ret = ehea_sense_port_attr(port);
  29 
  30         if (ret)
  31                 return ret;
  32 
  33         if (netif_carrier_ok(dev)) {
  34                 switch (port->port_speed) {
  35                 case EHEA_SPEED_10M:
  36                         speed = SPEED_10;
  37                         break;
  38                 case EHEA_SPEED_100M:
  39                         speed = SPEED_100;
  40                         break;
  41                 case EHEA_SPEED_1G:
  42                         speed = SPEED_1000;
  43                         break;
  44                 case EHEA_SPEED_10G:
  45                         speed = SPEED_10000;
  46                         break;
  47                 default:
  48                         speed = -1;
  49                         break; /* BUG */
  50                 }
  51                 cmd->base.duplex = port->full_duplex == 1 ?
  52                                                      DUPLEX_FULL : DUPLEX_HALF;
  53         } else {
  54                 speed = SPEED_UNKNOWN;
  55                 cmd->base.duplex = DUPLEX_UNKNOWN;
  56         }
  57         cmd->base.speed = speed;
  58 
  59         if (cmd->base.speed == SPEED_10000) {
  60                 supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
  61                 advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE);
  62                 cmd->base.port = PORT_FIBRE;
  63         } else {
  64                 supported = (SUPPORTED_1000baseT_Full | SUPPORTED_100baseT_Full
  65                                | SUPPORTED_100baseT_Half | SUPPORTED_10baseT_Full
  66                                | SUPPORTED_10baseT_Half | SUPPORTED_Autoneg
  67                                | SUPPORTED_TP);
  68                 advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg
  69                                  | ADVERTISED_TP);
  70                 cmd->base.port = PORT_TP;
  71         }
  72 
  73         cmd->base.autoneg = port->autoneg == 1 ?
  74                 AUTONEG_ENABLE : AUTONEG_DISABLE;
  75 
  76         ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
  77                                                 supported);
  78         ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
  79                                                 advertising);
  80 
  81         return 0;
  82 }
  83 
  84 static int ehea_set_link_ksettings(struct net_device *dev,
  85                                    const struct ethtool_link_ksettings *cmd)
  86 {
  87         struct ehea_port *port = netdev_priv(dev);
  88         int ret = 0;
  89         u32 sp;
  90 
  91         if (cmd->base.autoneg == AUTONEG_ENABLE) {
  92                 sp = EHEA_SPEED_AUTONEG;
  93                 goto doit;
  94         }
  95 
  96         switch (cmd->base.speed) {
  97         case SPEED_10:
  98                 if (cmd->base.duplex == DUPLEX_FULL)
  99                         sp = H_SPEED_10M_F;
 100                 else
 101                         sp = H_SPEED_10M_H;
 102                 break;
 103 
 104         case SPEED_100:
 105                 if (cmd->base.duplex == DUPLEX_FULL)
 106                         sp = H_SPEED_100M_F;
 107                 else
 108                         sp = H_SPEED_100M_H;
 109                 break;
 110 
 111         case SPEED_1000:
 112                 if (cmd->base.duplex == DUPLEX_FULL)
 113                         sp = H_SPEED_1G_F;
 114                 else
 115                         ret = -EINVAL;
 116                 break;
 117 
 118         case SPEED_10000:
 119                 if (cmd->base.duplex == DUPLEX_FULL)
 120                         sp = H_SPEED_10G_F;
 121                 else
 122                         ret = -EINVAL;
 123                 break;
 124 
 125         default:
 126                         ret = -EINVAL;
 127                 break;
 128         }
 129 
 130         if (ret)
 131                 goto out;
 132 doit:
 133         ret = ehea_set_portspeed(port, sp);
 134 
 135         if (!ret)
 136                 netdev_info(dev,
 137                             "Port speed successfully set: %dMbps %s Duplex\n",
 138                             port->port_speed,
 139                             port->full_duplex == 1 ? "Full" : "Half");
 140 out:
 141         return ret;
 142 }
 143 
 144 static int ehea_nway_reset(struct net_device *dev)
 145 {
 146         struct ehea_port *port = netdev_priv(dev);
 147         int ret;
 148 
 149         ret = ehea_set_portspeed(port, EHEA_SPEED_AUTONEG);
 150 
 151         if (!ret)
 152                 netdev_info(port->netdev,
 153                             "Port speed successfully set: %dMbps %s Duplex\n",
 154                             port->port_speed,
 155                             port->full_duplex == 1 ? "Full" : "Half");
 156         return ret;
 157 }
 158 
 159 static void ehea_get_drvinfo(struct net_device *dev,
 160                                struct ethtool_drvinfo *info)
 161 {
 162         strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
 163         strlcpy(info->version, DRV_VERSION, sizeof(info->version));
 164 }
 165 
 166 static u32 ehea_get_msglevel(struct net_device *dev)
 167 {
 168         struct ehea_port *port = netdev_priv(dev);
 169         return port->msg_enable;
 170 }
 171 
 172 static void ehea_set_msglevel(struct net_device *dev, u32 value)
 173 {
 174         struct ehea_port *port = netdev_priv(dev);
 175         port->msg_enable = value;
 176 }
 177 
 178 static const char ehea_ethtool_stats_keys[][ETH_GSTRING_LEN] = {
 179         {"sig_comp_iv"},
 180         {"swqe_refill_th"},
 181         {"port resets"},
 182         {"Receive errors"},
 183         {"TCP cksum errors"},
 184         {"IP cksum errors"},
 185         {"Frame cksum errors"},
 186         {"num SQ stopped"},
 187         {"PR0 free_swqes"},
 188         {"PR1 free_swqes"},
 189         {"PR2 free_swqes"},
 190         {"PR3 free_swqes"},
 191         {"PR4 free_swqes"},
 192         {"PR5 free_swqes"},
 193         {"PR6 free_swqes"},
 194         {"PR7 free_swqes"},
 195         {"PR8 free_swqes"},
 196         {"PR9 free_swqes"},
 197         {"PR10 free_swqes"},
 198         {"PR11 free_swqes"},
 199         {"PR12 free_swqes"},
 200         {"PR13 free_swqes"},
 201         {"PR14 free_swqes"},
 202         {"PR15 free_swqes"},
 203 };
 204 
 205 static void ehea_get_strings(struct net_device *dev, u32 stringset, u8 *data)
 206 {
 207         if (stringset == ETH_SS_STATS) {
 208                 memcpy(data, &ehea_ethtool_stats_keys,
 209                        sizeof(ehea_ethtool_stats_keys));
 210         }
 211 }
 212 
 213 static int ehea_get_sset_count(struct net_device *dev, int sset)
 214 {
 215         switch (sset) {
 216         case ETH_SS_STATS:
 217                 return ARRAY_SIZE(ehea_ethtool_stats_keys);
 218         default:
 219                 return -EOPNOTSUPP;
 220         }
 221 }
 222 
 223 static void ehea_get_ethtool_stats(struct net_device *dev,
 224                                      struct ethtool_stats *stats, u64 *data)
 225 {
 226         int i, k, tmp;
 227         struct ehea_port *port = netdev_priv(dev);
 228 
 229         for (i = 0; i < ehea_get_sset_count(dev, ETH_SS_STATS); i++)
 230                 data[i] = 0;
 231         i = 0;
 232 
 233         data[i++] = port->sig_comp_iv;
 234         data[i++] = port->port_res[0].swqe_refill_th;
 235         data[i++] = port->resets;
 236 
 237         for (k = 0, tmp = 0; k < EHEA_MAX_PORT_RES; k++)
 238                 tmp += port->port_res[k].p_stats.poll_receive_errors;
 239         data[i++] = tmp;
 240 
 241         for (k = 0, tmp = 0; k < EHEA_MAX_PORT_RES; k++)
 242                 tmp += port->port_res[k].p_stats.err_tcp_cksum;
 243         data[i++] = tmp;
 244 
 245         for (k = 0, tmp = 0; k < EHEA_MAX_PORT_RES; k++)
 246                 tmp += port->port_res[k].p_stats.err_ip_cksum;
 247         data[i++] = tmp;
 248 
 249         for (k = 0, tmp = 0; k < EHEA_MAX_PORT_RES; k++)
 250                 tmp += port->port_res[k].p_stats.err_frame_crc;
 251         data[i++] = tmp;
 252 
 253         for (k = 0, tmp = 0; k < EHEA_MAX_PORT_RES; k++)
 254                 tmp += port->port_res[k].p_stats.queue_stopped;
 255         data[i++] = tmp;
 256 
 257         for (k = 0; k < 16; k++)
 258                 data[i++] = atomic_read(&port->port_res[k].swqe_avail);
 259 }
 260 
 261 static const struct ethtool_ops ehea_ethtool_ops = {
 262         .get_drvinfo = ehea_get_drvinfo,
 263         .get_msglevel = ehea_get_msglevel,
 264         .set_msglevel = ehea_set_msglevel,
 265         .get_link = ethtool_op_get_link,
 266         .get_strings = ehea_get_strings,
 267         .get_sset_count = ehea_get_sset_count,
 268         .get_ethtool_stats = ehea_get_ethtool_stats,
 269         .nway_reset = ehea_nway_reset,          /* Restart autonegotiation */
 270         .get_link_ksettings = ehea_get_link_ksettings,
 271         .set_link_ksettings = ehea_set_link_ksettings,
 272 };
 273 
 274 void ehea_set_ethtool_ops(struct net_device *netdev)
 275 {
 276         netdev->ethtool_ops = &ehea_ethtool_ops;
 277 }

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