1 // SPDX-License-Identifier: (GPL-2.0 OR MIT) 2 /* Google virtual Ethernet (gve) driver 3 * 4 * Copyright (C) 2015-2019 Google, Inc. 5 */ 6 7 #include <linux/rtnetlink.h> 8 #include "gve.h" 9 10 static void gve_get_drvinfo(struct net_device *netdev, 11 struct ethtool_drvinfo *info) 12 { 13 struct gve_priv *priv = netdev_priv(netdev); 14 15 strlcpy(info->driver, "gve", sizeof(info->driver)); 16 strlcpy(info->version, gve_version_str, sizeof(info->version)); 17 strlcpy(info->bus_info, pci_name(priv->pdev), sizeof(info->bus_info)); 18 } 19 20 static void gve_set_msglevel(struct net_device *netdev, u32 value) 21 { 22 struct gve_priv *priv = netdev_priv(netdev); 23 24 priv->msg_enable = value; 25 } 26 27 static u32 gve_get_msglevel(struct net_device *netdev) 28 { 29 struct gve_priv *priv = netdev_priv(netdev); 30 31 return priv->msg_enable; 32 } 33 34 static const char gve_gstrings_main_stats[][ETH_GSTRING_LEN] = { 35 "rx_packets", "tx_packets", "rx_bytes", "tx_bytes", 36 "rx_dropped", "tx_dropped", "tx_timeouts", 37 }; 38 39 #define GVE_MAIN_STATS_LEN ARRAY_SIZE(gve_gstrings_main_stats) 40 #define NUM_GVE_TX_CNTS 5 41 #define NUM_GVE_RX_CNTS 2 42 43 static void gve_get_strings(struct net_device *netdev, u32 stringset, u8 *data) 44 { 45 struct gve_priv *priv = netdev_priv(netdev); 46 char *s = (char *)data; 47 int i; 48 49 if (stringset != ETH_SS_STATS) 50 return; 51 52 memcpy(s, *gve_gstrings_main_stats, 53 sizeof(gve_gstrings_main_stats)); 54 s += sizeof(gve_gstrings_main_stats); 55 for (i = 0; i < priv->rx_cfg.num_queues; i++) { 56 snprintf(s, ETH_GSTRING_LEN, "rx_desc_cnt[%u]", i); 57 s += ETH_GSTRING_LEN; 58 snprintf(s, ETH_GSTRING_LEN, "rx_desc_fill_cnt[%u]", i); 59 s += ETH_GSTRING_LEN; 60 } 61 for (i = 0; i < priv->tx_cfg.num_queues; i++) { 62 snprintf(s, ETH_GSTRING_LEN, "tx_req[%u]", i); 63 s += ETH_GSTRING_LEN; 64 snprintf(s, ETH_GSTRING_LEN, "tx_done[%u]", i); 65 s += ETH_GSTRING_LEN; 66 snprintf(s, ETH_GSTRING_LEN, "tx_wake[%u]", i); 67 s += ETH_GSTRING_LEN; 68 snprintf(s, ETH_GSTRING_LEN, "tx_stop[%u]", i); 69 s += ETH_GSTRING_LEN; 70 snprintf(s, ETH_GSTRING_LEN, "tx_event_counter[%u]", i); 71 s += ETH_GSTRING_LEN; 72 } 73 } 74 75 static int gve_get_sset_count(struct net_device *netdev, int sset) 76 { 77 struct gve_priv *priv = netdev_priv(netdev); 78 79 switch (sset) { 80 case ETH_SS_STATS: 81 return GVE_MAIN_STATS_LEN + 82 (priv->rx_cfg.num_queues * NUM_GVE_RX_CNTS) + 83 (priv->tx_cfg.num_queues * NUM_GVE_TX_CNTS); 84 default: 85 return -EOPNOTSUPP; 86 } 87 } 88 89 static void 90 gve_get_ethtool_stats(struct net_device *netdev, 91 struct ethtool_stats *stats, u64 *data) 92 { 93 struct gve_priv *priv = netdev_priv(netdev); 94 u64 rx_pkts, rx_bytes, tx_pkts, tx_bytes; 95 unsigned int start; 96 int ring; 97 int i; 98 99 ASSERT_RTNL(); 100 101 for (rx_pkts = 0, rx_bytes = 0, ring = 0; 102 ring < priv->rx_cfg.num_queues; ring++) { 103 if (priv->rx) { 104 do { 105 start = 106 u64_stats_fetch_begin(&priv->rx[ring].statss); 107 rx_pkts += priv->rx[ring].rpackets; 108 rx_bytes += priv->rx[ring].rbytes; 109 } while (u64_stats_fetch_retry(&priv->rx[ring].statss, 110 start)); 111 } 112 } 113 for (tx_pkts = 0, tx_bytes = 0, ring = 0; 114 ring < priv->tx_cfg.num_queues; ring++) { 115 if (priv->tx) { 116 do { 117 start = 118 u64_stats_fetch_begin(&priv->tx[ring].statss); 119 tx_pkts += priv->tx[ring].pkt_done; 120 tx_bytes += priv->tx[ring].bytes_done; 121 } while (u64_stats_fetch_retry(&priv->tx[ring].statss, 122 start)); 123 } 124 } 125 126 i = 0; 127 data[i++] = rx_pkts; 128 data[i++] = tx_pkts; 129 data[i++] = rx_bytes; 130 data[i++] = tx_bytes; 131 /* Skip rx_dropped and tx_dropped */ 132 i += 2; 133 data[i++] = priv->tx_timeo_cnt; 134 i = GVE_MAIN_STATS_LEN; 135 136 /* walk RX rings */ 137 if (priv->rx) { 138 for (ring = 0; ring < priv->rx_cfg.num_queues; ring++) { 139 struct gve_rx_ring *rx = &priv->rx[ring]; 140 141 data[i++] = rx->cnt; 142 data[i++] = rx->fill_cnt; 143 } 144 } else { 145 i += priv->rx_cfg.num_queues * NUM_GVE_RX_CNTS; 146 } 147 /* walk TX rings */ 148 if (priv->tx) { 149 for (ring = 0; ring < priv->tx_cfg.num_queues; ring++) { 150 struct gve_tx_ring *tx = &priv->tx[ring]; 151 152 data[i++] = tx->req; 153 data[i++] = tx->done; 154 data[i++] = tx->wake_queue; 155 data[i++] = tx->stop_queue; 156 data[i++] = be32_to_cpu(gve_tx_load_event_counter(priv, 157 tx)); 158 } 159 } else { 160 i += priv->tx_cfg.num_queues * NUM_GVE_TX_CNTS; 161 } 162 } 163 164 static void gve_get_channels(struct net_device *netdev, 165 struct ethtool_channels *cmd) 166 { 167 struct gve_priv *priv = netdev_priv(netdev); 168 169 cmd->max_rx = priv->rx_cfg.max_queues; 170 cmd->max_tx = priv->tx_cfg.max_queues; 171 cmd->max_other = 0; 172 cmd->max_combined = 0; 173 cmd->rx_count = priv->rx_cfg.num_queues; 174 cmd->tx_count = priv->tx_cfg.num_queues; 175 cmd->other_count = 0; 176 cmd->combined_count = 0; 177 } 178 179 static int gve_set_channels(struct net_device *netdev, 180 struct ethtool_channels *cmd) 181 { 182 struct gve_priv *priv = netdev_priv(netdev); 183 struct gve_queue_config new_tx_cfg = priv->tx_cfg; 184 struct gve_queue_config new_rx_cfg = priv->rx_cfg; 185 struct ethtool_channels old_settings; 186 int new_tx = cmd->tx_count; 187 int new_rx = cmd->rx_count; 188 189 gve_get_channels(netdev, &old_settings); 190 191 /* Changing combined is not allowed allowed */ 192 if (cmd->combined_count != old_settings.combined_count) 193 return -EINVAL; 194 195 if (!new_rx || !new_tx) 196 return -EINVAL; 197 198 if (!netif_carrier_ok(netdev)) { 199 priv->tx_cfg.num_queues = new_tx; 200 priv->rx_cfg.num_queues = new_rx; 201 return 0; 202 } 203 204 new_tx_cfg.num_queues = new_tx; 205 new_rx_cfg.num_queues = new_rx; 206 207 return gve_adjust_queues(priv, new_rx_cfg, new_tx_cfg); 208 } 209 210 static void gve_get_ringparam(struct net_device *netdev, 211 struct ethtool_ringparam *cmd) 212 { 213 struct gve_priv *priv = netdev_priv(netdev); 214 215 cmd->rx_max_pending = priv->rx_desc_cnt; 216 cmd->tx_max_pending = priv->tx_desc_cnt; 217 cmd->rx_pending = priv->rx_desc_cnt; 218 cmd->tx_pending = priv->tx_desc_cnt; 219 } 220 221 static int gve_user_reset(struct net_device *netdev, u32 *flags) 222 { 223 struct gve_priv *priv = netdev_priv(netdev); 224 225 if (*flags == ETH_RESET_ALL) { 226 *flags = 0; 227 return gve_reset(priv, true); 228 } 229 230 return -EOPNOTSUPP; 231 } 232 233 const struct ethtool_ops gve_ethtool_ops = { 234 .get_drvinfo = gve_get_drvinfo, 235 .get_strings = gve_get_strings, 236 .get_sset_count = gve_get_sset_count, 237 .get_ethtool_stats = gve_get_ethtool_stats, 238 .set_msglevel = gve_set_msglevel, 239 .get_msglevel = gve_get_msglevel, 240 .set_channels = gve_set_channels, 241 .get_channels = gve_get_channels, 242 .get_link = ethtool_op_get_link, 243 .get_ringparam = gve_get_ringparam, 244 .reset = gve_user_reset, 245 }; 246